OLD | NEW |
1 // Copyright (c) 2010 Google Inc. | 1 // Copyright (c) 2010 Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 // is specified, it is made available for use by the MinidumpProcessor. | 64 // is specified, it is made available for use by the MinidumpProcessor. |
65 // | 65 // |
66 // Returns the value of MinidumpProcessor::Process. If processing succeeds, | 66 // Returns the value of MinidumpProcessor::Process. If processing succeeds, |
67 // prints identifying OS and CPU information from the minidump, crash | 67 // prints identifying OS and CPU information from the minidump, crash |
68 // information if the minidump was produced as a result of a crash, and | 68 // information if the minidump was produced as a result of a crash, and |
69 // call stacks for each thread contained in the minidump. All information | 69 // call stacks for each thread contained in the minidump. All information |
70 // is printed to stdout. | 70 // is printed to stdout. |
71 bool PrintMinidumpProcess(const string &minidump_file, | 71 bool PrintMinidumpProcess(const string &minidump_file, |
72 const std::vector<string> &symbol_paths, | 72 const std::vector<string> &symbol_paths, |
73 bool machine_readable, | 73 bool machine_readable, |
74 bool output_stack_contents, | 74 bool output_stack_contents) { |
75 bool output_modules_only) { | |
76 scoped_ptr<SimpleSymbolSupplier> symbol_supplier; | 75 scoped_ptr<SimpleSymbolSupplier> symbol_supplier; |
77 if (!symbol_paths.empty()) { | 76 if (!symbol_paths.empty()) { |
78 // TODO(mmentovai): check existence of symbol_path if specified? | 77 // TODO(mmentovai): check existence of symbol_path if specified? |
79 symbol_supplier.reset(new SimpleSymbolSupplier(symbol_paths)); | 78 symbol_supplier.reset(new SimpleSymbolSupplier(symbol_paths)); |
80 } | 79 } |
81 | 80 |
82 BasicSourceLineResolver resolver; | 81 BasicSourceLineResolver resolver; |
83 MinidumpProcessor minidump_processor(symbol_supplier.get(), &resolver); | 82 MinidumpProcessor minidump_processor(symbol_supplier.get(), &resolver); |
84 | 83 |
85 // Process the minidump. | 84 // Process the minidump. |
86 Minidump dump(minidump_file); | 85 Minidump dump(minidump_file); |
87 if (!dump.Read()) { | 86 if (!dump.Read()) { |
88 BPLOG(ERROR) << "Minidump " << dump.path() << " could not be read"; | 87 BPLOG(ERROR) << "Minidump " << dump.path() << " could not be read"; |
89 return false; | 88 return false; |
90 } | 89 } |
91 ProcessState process_state; | 90 ProcessState process_state; |
92 if (minidump_processor.Process(&dump, &process_state) != | 91 if (minidump_processor.Process(&dump, &process_state) != |
93 google_breakpad::PROCESS_OK) { | 92 google_breakpad::PROCESS_OK) { |
94 BPLOG(ERROR) << "MinidumpProcessor::Process failed"; | 93 BPLOG(ERROR) << "MinidumpProcessor::Process failed"; |
95 return false; | 94 return false; |
96 } | 95 } |
97 | 96 |
98 if (output_modules_only) { | 97 if (machine_readable) { |
99 PrintProcessModules(process_state); | |
100 } else if (machine_readable) { | |
101 PrintProcessStateMachineReadable(process_state); | 98 PrintProcessStateMachineReadable(process_state); |
102 } else { | 99 } else { |
103 PrintProcessState(process_state, output_stack_contents, &resolver); | 100 PrintProcessState(process_state, output_stack_contents, &resolver); |
104 } | 101 } |
105 | 102 |
106 return true; | 103 return true; |
107 } | 104 } |
108 | 105 |
109 void usage(const char *program_name) { | 106 void usage(const char *program_name) { |
110 fprintf(stderr, "usage: %s [-m|-s|-b] <minidump-file> [symbol-path ...]\n" | 107 fprintf(stderr, "usage: %s [-m|-s] <minidump-file> [symbol-path ...]\n" |
111 " -m : Output in machine-readable format\n" | 108 " -m : Output in machine-readable format\n" |
112 " -s : Output stack contents\n" | 109 " -s : Output stack contents\n", |
113 " -b : Output contained full module paths\n", | |
114 program_name); | 110 program_name); |
115 } | 111 } |
116 | 112 |
117 } // namespace | 113 } // namespace |
118 | 114 |
119 int main(int argc, char **argv) { | 115 int main(int argc, char **argv) { |
120 BPLOG_INIT(&argc, &argv); | 116 BPLOG_INIT(&argc, &argv); |
121 | 117 |
122 if (argc < 2) { | 118 if (argc < 2) { |
123 usage(argv[0]); | 119 usage(argv[0]); |
124 return 1; | 120 return 1; |
125 } | 121 } |
126 | 122 |
127 const char *minidump_file; | 123 const char *minidump_file; |
128 bool machine_readable = false; | 124 bool machine_readable = false; |
129 bool output_stack_contents = false; | 125 bool output_stack_contents = false; |
130 bool output_modules_only = false; | |
131 int symbol_path_arg; | 126 int symbol_path_arg; |
132 | 127 |
133 if (strcmp(argv[1], "-m") == 0) { | 128 if (strcmp(argv[1], "-m") == 0) { |
134 if (argc < 3) { | 129 if (argc < 3) { |
135 usage(argv[0]); | 130 usage(argv[0]); |
136 return 1; | 131 return 1; |
137 } | 132 } |
138 | 133 |
139 machine_readable = true; | 134 machine_readable = true; |
140 minidump_file = argv[2]; | 135 minidump_file = argv[2]; |
141 symbol_path_arg = 3; | 136 symbol_path_arg = 3; |
142 } else if (strcmp(argv[1], "-s") == 0) { | 137 } else if (strcmp(argv[1], "-s") == 0) { |
143 if (argc < 3) { | 138 if (argc < 3) { |
144 usage(argv[0]); | 139 usage(argv[0]); |
145 return 1; | 140 return 1; |
146 } | 141 } |
147 | 142 |
148 output_stack_contents = true; | 143 output_stack_contents = true; |
149 minidump_file = argv[2]; | 144 minidump_file = argv[2]; |
150 symbol_path_arg = 3; | 145 symbol_path_arg = 3; |
151 } else if (strcmp(argv[1], "-b") == 0) { | |
152 if (argc < 3) { | |
153 usage(argv[0]); | |
154 return 1; | |
155 } | |
156 | |
157 output_modules_only = true; | |
158 minidump_file = argv[2]; | |
159 symbol_path_arg = 3; | |
160 } else { | 146 } else { |
161 minidump_file = argv[1]; | 147 minidump_file = argv[1]; |
162 symbol_path_arg = 2; | 148 symbol_path_arg = 2; |
163 } | 149 } |
164 | 150 |
165 // extra arguments are symbol paths | 151 // extra arguments are symbol paths |
166 std::vector<string> symbol_paths; | 152 std::vector<string> symbol_paths; |
167 if (argc > symbol_path_arg) { | 153 if (argc > symbol_path_arg) { |
168 for (int argi = symbol_path_arg; argi < argc; ++argi) | 154 for (int argi = symbol_path_arg; argi < argc; ++argi) |
169 symbol_paths.push_back(argv[argi]); | 155 symbol_paths.push_back(argv[argi]); |
170 } | 156 } |
171 | 157 |
172 return PrintMinidumpProcess(minidump_file, | 158 return PrintMinidumpProcess(minidump_file, |
173 symbol_paths, | 159 symbol_paths, |
174 machine_readable, | 160 machine_readable, |
175 output_stack_contents, | 161 output_stack_contents) ? 0 : 1; |
176 output_modules_only) ? 0 : 1; | |
177 } | 162 } |
OLD | NEW |