1 : // Copyright 2015 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : // Runs the refinery over a minidump and outputs the validation report.
16 :
17 : #include <iostream>
18 :
19 : #include "base/command_line.h"
20 : #include "base/logging.h"
21 : #include "base/files/file_path.h"
22 : #include "base/memory/scoped_ptr.h"
23 : #include "base/strings/stringprintf.h"
24 : #include "syzygy/minidump/minidump.h"
25 : #include "syzygy/refinery/analyzers/analysis_runner.h"
26 : #include "syzygy/refinery/analyzers/exception_analyzer.h"
27 : #include "syzygy/refinery/analyzers/heap_analyzer.h"
28 : #include "syzygy/refinery/analyzers/memory_analyzer.h"
29 : #include "syzygy/refinery/analyzers/module_analyzer.h"
30 : #include "syzygy/refinery/analyzers/stack_analyzer.h"
31 : #include "syzygy/refinery/analyzers/thread_analyzer.h"
32 : #include "syzygy/refinery/process_state/process_state.h"
33 : #include "syzygy/refinery/process_state/process_state_util.h"
34 : #include "syzygy/refinery/process_state/refinery.pb.h"
35 : #include "syzygy/refinery/symbols/dia_symbol_provider.h"
36 : #include "syzygy/refinery/symbols/symbol_provider.h"
37 : #include "syzygy/refinery/validators/exception_handler_validator.h"
38 :
39 m : namespace {
40 :
41 m : using minidump::Minidump;
42 m : using refinery::AnalysisRunner;
43 m : using refinery::Analyzer;
44 m : using refinery::ProcessState;
45 m : using refinery::ValidationReport;
46 m : using refinery::Validator;
47 :
48 m : const char kUsage[] =
49 m : "Usage: %ls --dump=<dump file>\n"
50 m : "\n"
51 m : " Runs the refinery analysis and validation, then prints the validation \n"
52 m : " report.\n";
53 :
54 m : bool ParseCommandLine(const base::CommandLine* cmd,
55 m : base::FilePath* dump_path) {
56 m : *dump_path = cmd->GetSwitchValuePath("dump");
57 m : if (dump_path->empty()) {
58 m : LOG(ERROR) << "Missing dump file.";
59 m : LOG(ERROR) << base::StringPrintf(kUsage, cmd->GetProgram());
60 m : return false;
61 m : }
62 :
63 m : return true;
64 m : }
65 :
66 m : bool Analyze(const Minidump& minidump, ProcessState* process_state) {
67 m : AnalysisRunner runner;
68 :
69 m : scoped_ptr<Analyzer> analyzer(new refinery::MemoryAnalyzer());
70 m : runner.AddAnalyzer(analyzer.Pass());
71 m : analyzer.reset(new refinery::ThreadAnalyzer());
72 m : runner.AddAnalyzer(analyzer.Pass());
73 m : analyzer.reset(new refinery::ExceptionAnalyzer());
74 m : runner.AddAnalyzer(analyzer.Pass());
75 m : analyzer.reset(new refinery::ModuleAnalyzer());
76 m : runner.AddAnalyzer(analyzer.Pass());
77 :
78 m : scoped_refptr<refinery::SymbolProvider> symbol_provider(
79 m : new refinery::SymbolProvider());
80 m : analyzer.reset(new refinery::HeapAnalyzer(symbol_provider));
81 m : runner.AddAnalyzer(analyzer.Pass());
82 :
83 m : scoped_refptr<refinery::DiaSymbolProvider> dia_symbol_provider(
84 m : new refinery::DiaSymbolProvider());
85 m : analyzer.reset(new refinery::StackAnalyzer(dia_symbol_provider));
86 m : runner.AddAnalyzer(analyzer.Pass());
87 :
88 m : return runner.Analyze(minidump, process_state) == Analyzer::ANALYSIS_COMPLETE;
89 m : }
90 :
91 m : bool Validate(ProcessState* process_state, ValidationReport* report) {
92 m : refinery::ExceptionHandlerValidator validator;
93 m : if (validator.Validate(process_state, report) !=
94 m : Validator::VALIDATION_COMPLETE) {
95 m : LOG(ERROR) << "Exception handler chain validation failed";
96 m : return false;
97 m : }
98 :
99 m : return true;
100 m : }
101 :
102 m : } // namespace
103 :
104 m : int main(int argc, const char* const* argv) {
105 m : base::CommandLine::Init(argc, argv);
106 :
107 : // Get the dump.
108 m : base::FilePath dump_path;
109 m : if (!ParseCommandLine(base::CommandLine::ForCurrentProcess(), &dump_path))
110 m : return 1;
111 :
112 m : Minidump minidump;
113 m : if (!minidump.Open(dump_path)) {
114 m : LOG(ERROR) << "Unable to open dump file.";
115 m : return 1;
116 m : }
117 :
118 : // Analyze.
119 m : ProcessState process_state;
120 m : if (!Analyze(minidump, &process_state))
121 m : return 1;
122 :
123 : // Validate and output.
124 m : ValidationReport report;
125 m : if (!Validate(&process_state, &report))
126 m : return 1;
127 :
128 m : std::cout << "Validation report:";
129 m : std::cout << report.DebugString();
130 :
131 m : return 0;
132 m : }
|