diff options
Diffstat (limited to 'src/processor')
84 files changed, 568 insertions, 208 deletions
diff --git a/src/processor/address_map_unittest.cc b/src/processor/address_map_unittest.cc index 1bf0d718..2d754b60 100644 --- a/src/processor/address_map_unittest.cc +++ b/src/processor/address_map_unittest.cc @@ -30,6 +30,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <limits.h> #include <stdio.h> diff --git a/src/processor/basic_code_modules.cc b/src/processor/basic_code_modules.cc index 57021d47..bdfc8f3d 100644 --- a/src/processor/basic_code_modules.cc +++ b/src/processor/basic_code_modules.cc @@ -33,6 +33,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "processor/basic_code_modules.h" #include <assert.h> diff --git a/src/processor/basic_source_line_resolver.cc b/src/processor/basic_source_line_resolver.cc index 07aba6bc..220bd746 100644 --- a/src/processor/basic_source_line_resolver.cc +++ b/src/processor/basic_source_line_resolver.cc @@ -31,6 +31,10 @@ // See basic_source_line_resolver.h and basic_source_line_resolver_types.h // for documentation. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <assert.h> #include <stdio.h> #include <string.h> diff --git a/src/processor/basic_source_line_resolver_unittest.cc b/src/processor/basic_source_line_resolver_unittest.cc index fba4e9a6..a73ded8b 100644 --- a/src/processor/basic_source_line_resolver_unittest.cc +++ b/src/processor/basic_source_line_resolver_unittest.cc @@ -26,6 +26,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <assert.h> #include <stdio.h> diff --git a/src/processor/call_stack.cc b/src/processor/call_stack.cc index 87ffd1ae..6ecae6dc 100644 --- a/src/processor/call_stack.cc +++ b/src/processor/call_stack.cc @@ -32,6 +32,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/stack_frame.h" diff --git a/src/processor/cfi_frame_info.cc b/src/processor/cfi_frame_info.cc index 5216a44e..2094e094 100644 --- a/src/processor/cfi_frame_info.cc +++ b/src/processor/cfi_frame_info.cc @@ -31,6 +31,10 @@ // cfi_frame_info.cc: Implementation of CFIFrameInfo class. // See cfi_frame_info.h for details. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "processor/cfi_frame_info.h" #include <string.h> diff --git a/src/processor/cfi_frame_info_unittest.cc b/src/processor/cfi_frame_info_unittest.cc index 85f970a5..0cf4562d 100644 --- a/src/processor/cfi_frame_info_unittest.cc +++ b/src/processor/cfi_frame_info_unittest.cc @@ -31,6 +31,10 @@ // cfi_frame_info_unittest.cc: Unit tests for CFIFrameInfo, // CFIRuleParser, CFIFrameInfoParseHandler, and SimpleCFIWalker. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <string.h> #include "breakpad_googletest_includes.h" diff --git a/src/processor/contained_range_map_unittest.cc b/src/processor/contained_range_map_unittest.cc index 670bb189..1d681fdf 100644 --- a/src/processor/contained_range_map_unittest.cc +++ b/src/processor/contained_range_map_unittest.cc @@ -30,6 +30,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <stdio.h> #include "processor/contained_range_map-inl.h" diff --git a/src/processor/convert_old_arm64_context.cc b/src/processor/convert_old_arm64_context.cc index 8347064a..768475b2 100644 --- a/src/processor/convert_old_arm64_context.cc +++ b/src/processor/convert_old_arm64_context.cc @@ -26,6 +26,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "processor/convert_old_arm64_context.h" #include <string.h> diff --git a/src/processor/disassembler_objdump.cc b/src/processor/disassembler_objdump.cc index dfe10d58..9f9569a5 100644 --- a/src/processor/disassembler_objdump.cc +++ b/src/processor/disassembler_objdump.cc @@ -30,10 +30,16 @@ // // Author: Mark Brand +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "processor/disassembler_objdump.h" -#ifdef __linux__ #include <unistd.h> +#include <sys/wait.h> + +#include <array> #include <fstream> #include <iostream> #include <iterator> @@ -41,76 +47,15 @@ #include <sstream> #include <vector> +#include "common/linux/eintr_wrapper.h" +#include "common/linux/scoped_pipe.h" +#include "common/linux/scoped_tmpfile.h" #include "processor/logging.h" namespace google_breakpad { namespace { -const size_t kMaxX86InstructionLength = 15; - -// Small RAII wrapper for temporary files. -// -// Example: -// ScopedTmpFile tmp("/tmp/tmpfile-XXXX"); -// if (tmp.Create()) { -// std::cerr << tmp.path() << std::endl; -// } -class ScopedTmpFile { - public: - // Initialize the ScopedTmpFile object - this does not create the temporary - // file yet. - ScopedTmpFile(const char* path_format); - ~ScopedTmpFile(); - - // Creates the temporary file, returns true on success. - bool Create(); - - // Writes bytes to the temporary file, returns true on success. - bool Write(const uint8_t* bytes, unsigned int bytes_len); - - // Returns the path of the temporary file. - string path() const { return path_; } - - private: - int fd_; - string path_; -}; - -ScopedTmpFile::ScopedTmpFile(const char* path_format) : path_(path_format) {} - -ScopedTmpFile::~ScopedTmpFile() { - if (fd_) { - close(fd_); - unlink(path_.c_str()); - } -} - -bool ScopedTmpFile::Create() { - fd_ = mkstemp(path_.data()); - if (fd_ < 0) { - unlink(path_.c_str()); - fd_ = 0; - path_ = ""; - return false; - } - - return true; -} -bool ScopedTmpFile::Write(const uint8_t* bytes, unsigned int bytes_len) { - if (fd_) { - do { - ssize_t result = write(fd_, bytes, bytes_len); - if (result < 0) { - break; - } - - bytes += result; - bytes_len -= result; - } while (bytes_len); - } - - return bytes_len == 0; -} +const size_t kMaxX86InstructionLength = 15; bool IsInstructionPrefix(const string& token) { if (token == "lock" || token == "rep" || token == "repz" || @@ -285,47 +230,87 @@ bool DisassemblerObjdump::DisassembleInstruction(uint32_t cpu, return false; } - // Create two temporary files, one for the raw instruction bytes to pass to - // objdump, and one for the output, and write the bytes to the input file. - ScopedTmpFile raw_bytes_file("/tmp/breakpad_mem_region-raw_bytes-XXXXXX"); - ScopedTmpFile disassembly_file("/tmp/breakpad_mem_region-disassembly-XXXXXX"); - if (!raw_bytes_file.Create() || !disassembly_file.Create() || - !raw_bytes_file.Write(raw_bytes, raw_bytes_len)) { - BPLOG(ERROR) << "Failed creating temporary files."; + // Create a temporary file for the raw instruction bytes to pass to + // objdump, and write the bytes to the input file. + ScopedTmpFile raw_bytes_file; + if (!raw_bytes_file.InitData(raw_bytes, raw_bytes_len)) { + BPLOG(ERROR) << "Failed creating temporary file."; + return false; + } + + // Create a pipe to use to read the disassembly back from objdump. + ScopedPipe disassembly_pipe; + if (!disassembly_pipe.Init()) { + BPLOG(ERROR) << "Failed creating pipe for output."; return false; } - char cmd[1024] = {0}; - snprintf(cmd, 1024, - "objdump -D --no-show-raw-insn -b binary -M intel -m %s %s > %s", - architecture.c_str(), raw_bytes_file.path().c_str(), - disassembly_file.path().c_str()); - if (system(cmd)) { - BPLOG(ERROR) << "Failed to call objdump."; + pid_t child_pid = fork(); + if (child_pid < 0) { + BPLOG(ERROR) << "Fork failed."; return false; } - // Pipe each output line into the string until the string contains the first - // instruction from objdump. - std::ifstream objdump_stream(disassembly_file.path()); + if (child_pid == 0) { + // In the child process, set up the input and output file descriptors. + if (dup2(raw_bytes_file.GetFd(), STDIN_FILENO) < 0 || + disassembly_pipe.Dup2WriteFd(STDOUT_FILENO) < 0 || + disassembly_pipe.Dup2WriteFd(STDERR_FILENO) < 0) { + BPLOG(ERROR) << "Failed dup'ing file descriptors."; + exit(-1); + } - // Match the instruction line, from: - // 0: lock cmpxchg DWORD PTR [esi+0x10],eax - // extract the string "lock cmpxchg DWORD PTR [esi+0x10],eax" - std::regex instruction_regex( - "^\\s+[0-9a-f]+:\\s+" // " 0:" - "((?:\\s*\\S*)+)$"); // "lock cmpxchg..." + // We need to close the read end of the pipe in the child process so that + // when the parent closes it, the pipe is disconnected. + disassembly_pipe.CloseReadFd(); - std::string line; - std::smatch match; - do { - if (!getline(objdump_stream, line)) { - BPLOG(INFO) << "Failed to find instruction in objdump output."; + // We use "/proc/self/fd/0" here to allow objdump to parse an unnamed file, + // since objdump does not have a mode to read from stdin. This cannot be + // used with a pipe, since objdump requires that the input is a standard + // file. + execlp("objdump", "objdump", "-D", "--no-show-raw-insn", "-b", "binary", + "-M", "intel", "-m", architecture.c_str(), "/proc/self/fd/0", + nullptr); + + BPLOG(ERROR) << "Failed to exec objdump."; + exit(-1); + } else { + // In the parent process, parse the objdump output. + + // Match the instruction line, from: + // 0: lock cmpxchg DWORD PTR [esi+0x10],eax + // extract the string "lock cmpxchg DWORD PTR [esi+0x10],eax" + std::regex instruction_regex( + "^\\s+[0-9a-f]+:\\s+" // " 0:" + "((?:\\s*\\S*)+)$"); // "lock cmpxchg..." + + std::string line; + std::smatch match; + while (disassembly_pipe.ReadLine(line)) { + if (std::regex_match(line, match, instruction_regex)) { + instruction = match[1].str(); + break; + } + } + + // Close the read pipe so that objdump will exit (in case we broke out of + // the loop above before reading all of the output). + disassembly_pipe.CloseReadFd(); + + // Now wait for objdump to exit. + int status = 0; + HANDLE_EINTR(waitpid(child_pid, &status, 0)); + + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + BPLOG(ERROR) << "objdump didn't run successfully."; return false; } - } while (!std::regex_match(line, match, instruction_regex)); - instruction = match[1].str(); + if (instruction == "") { + BPLOG(ERROR) << "Failed to find instruction in objdump output."; + return false; + } + } return true; } @@ -498,23 +483,5 @@ bool DisassemblerObjdump::CalculateDestAddress(const DumpContext& context, uint64_t& address) { return CalculateAddress(context, dest_, address); } -} // namespace google_breakpad - -#else // __linux__ -namespace google_breakpad { -DisassemblerObjdump::DisassemblerObjdump(const uint32_t cpu, - const MemoryRegion* memory_region, - uint64_t address) {} - -bool DisassemblerObjdump::CalculateSrcAddress(const DumpContext& context, - uint64_t& address) { - return false; -} - -bool DisassemblerObjdump::CalculateDestAddress(const DumpContext& context, - uint64_t& address) { - return false; -} -} // namespace google_breakpad -#endif // __linux__ +} // namespace google_breakpad
\ No newline at end of file diff --git a/src/processor/disassembler_objdump_unittest.cc b/src/processor/disassembler_objdump_unittest.cc index 4b4ce6c3..30a60da5 100644 --- a/src/processor/disassembler_objdump_unittest.cc +++ b/src/processor/disassembler_objdump_unittest.cc @@ -26,6 +26,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <unistd.h> #include <vector> diff --git a/src/processor/disassembler_x86.cc b/src/processor/disassembler_x86.cc index dffb996d..741cec7f 100644 --- a/src/processor/disassembler_x86.cc +++ b/src/processor/disassembler_x86.cc @@ -33,6 +33,10 @@ // // Author: Cris Neckar +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "processor/disassembler_x86.h" #include <string.h> diff --git a/src/processor/disassembler_x86_unittest.cc b/src/processor/disassembler_x86_unittest.cc index 117b3bf8..18525b82 100644 --- a/src/processor/disassembler_x86_unittest.cc +++ b/src/processor/disassembler_x86_unittest.cc @@ -26,6 +26,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <unistd.h> #include "breakpad_googletest_includes.h" diff --git a/src/processor/dump_context.cc b/src/processor/dump_context.cc index a8ab0084..ab97930f 100644 --- a/src/processor/dump_context.cc +++ b/src/processor/dump_context.cc @@ -30,6 +30,10 @@ // // See dump_context.h for documentation. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "google_breakpad/processor/dump_context.h" #include <assert.h> @@ -772,24 +776,14 @@ void DumpContext::Print() { context_riscv->t6); #if defined(__riscv) - for (unsigned int freg_index = 0; - freg_index < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; ++freg_index) { - riscv_fpr_size fp_value = context_riscv->float_save.regs[freg_index]; -# if __riscv_flen == 32 - printf(" float_save.regs[%2d] = 0x%" PRIx32 "\n", - freg_index, fp_value); -# elif __riscv_flen == 64 - printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", - freg_index, fp_value); -# elif __riscv_flen == 128 - printf(" float_save.regs[%2d] = 0x%" PRIx64 "%" PRIx64 "\n", - freg_index, fp_value.high, fp_value.low); -# else -# error "Unexpected __riscv_flen" -# endif + for (unsigned int freg_index = 0; freg_index < MD_CONTEXT_RISCV_FPR_COUNT; + ++freg_index) { + // Breakpad only supports RISCV32 with 32 bit floating point. + uint32_t fp_value = context_riscv->fpregs[freg_index]; + printf(" fpregs[%2d] = 0x%" PRIx32 "\n", freg_index, + fp_value); } - printf(" float_save.fpcsr = 0x%" PRIx32 "\n", - context_riscv->float_save.fpcsr); + printf(" fcsr = 0x%" PRIx32 "\n", context_riscv->fcsr); #endif break; } @@ -866,25 +860,14 @@ void DumpContext::Print() { context_riscv64->t6); #if defined(__riscv) - for (unsigned int freg_index = 0; - freg_index < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; ++freg_index) { - riscv_fpr_size fp_value = context_riscv64->float_save.regs[freg_index]; -# if __riscv_flen == 32 - printf(" float_save.regs[%2d] = 0x%" PRIx32 "\n", - freg_index, fp_value); -# elif __riscv_flen == 64 - printf(" float_save.regs[%2d] = 0x%" PRIx64 "\n", - freg_index, fp_value); -# elif __riscv_flen == 128 - printf(" float_save.regs[%2d] = 0x%" - PRIx64 "%" PRIx64 "\n", - freg_index, fp_value.high, fp_value.low); -# else -# error "Unexpected __riscv_flen" -# endif + for (unsigned int freg_index = 0; freg_index < MD_CONTEXT_RISCV_FPR_COUNT; + ++freg_index) { + // Breakpad only supports RISCV64 with 64 bit floating point. + uint64_t fp_value = context_riscv64->fpregs[freg_index]; + printf(" fpregs[%2d] = 0x%" PRIx64 "\n", freg_index, + fp_value); } - printf(" float_save.fpcsr = 0x%" PRIx32 "\n", - context_riscv64->float_save.fpcsr); + printf(" fcsr = 0x%" PRIx32 "\n", context_riscv64->fcsr); #endif break; } diff --git a/src/processor/dump_object.cc b/src/processor/dump_object.cc index 6186c8fa..4050b11e 100644 --- a/src/processor/dump_object.cc +++ b/src/processor/dump_object.cc @@ -28,6 +28,10 @@ // dump_object.cc: A base class for all mini/micro dump object. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "google_breakpad/processor/dump_object.h" namespace google_breakpad { diff --git a/src/processor/exploitability.cc b/src/processor/exploitability.cc index 7a4107bf..89064c9b 100644 --- a/src/processor/exploitability.cc +++ b/src/processor/exploitability.cc @@ -33,6 +33,10 @@ // Author: Cris Neckar +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <cassert> #include "common/scoped_ptr.h" diff --git a/src/processor/exploitability_linux.cc b/src/processor/exploitability_linux.cc index 63a12656..76e78f45 100644 --- a/src/processor/exploitability_linux.cc +++ b/src/processor/exploitability_linux.cc @@ -33,6 +33,10 @@ // // Author: Matthew Riley +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "processor/exploitability_linux.h" #include <string.h> @@ -41,7 +45,9 @@ #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/process_state.h" #include "google_breakpad/processor/stack_frame.h" +#ifdef __linux__ #include "processor/disassembler_objdump.h" +#endif #include "processor/logging.h" namespace { @@ -156,7 +162,7 @@ ExploitabilityRating ExploitabilityLinux::CheckPlatformExploitability() { } bool ExploitabilityLinux::EndedOnIllegalWrite(uint64_t instruction_ptr) { -#ifdef _WIN32 +#ifndef __linux__ BPLOG(INFO) << "MinGW does not support fork and exec. Terminating method."; return false; #else @@ -220,7 +226,7 @@ bool ExploitabilityLinux::EndedOnIllegalWrite(uint64_t instruction_ptr) { } else { return false; } -#endif // _WIN32 +#endif // __linux__ } bool ExploitabilityLinux::StackPointerOffStack(uint64_t stack_ptr) { diff --git a/src/processor/exploitability_unittest.cc b/src/processor/exploitability_unittest.cc index bc1823c6..09e4690d 100644 --- a/src/processor/exploitability_unittest.cc +++ b/src/processor/exploitability_unittest.cc @@ -26,6 +26,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <stdlib.h> #include <unistd.h> @@ -80,7 +84,7 @@ ExploitabilityFor(const string& filename) { SimpleSymbolSupplier supplier(TestDataDir() + "/symbols"); BasicSourceLineResolver resolver; MinidumpProcessor processor(&supplier, &resolver, true); - processor.set_enable_objdump(true); + processor.set_enable_objdump_for_exploitability(true); ProcessState state; string minidump_file = TestDataDir() + "/" + filename; diff --git a/src/processor/exploitability_win.cc b/src/processor/exploitability_win.cc index accaadd3..b94e8725 100644 --- a/src/processor/exploitability_win.cc +++ b/src/processor/exploitability_win.cc @@ -33,6 +33,10 @@ // // Author: Cris Neckar +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <vector> #include "processor/exploitability_win.h" diff --git a/src/processor/fast_source_line_resolver.cc b/src/processor/fast_source_line_resolver.cc index 0d1ebc6b..79803f2c 100644 --- a/src/processor/fast_source_line_resolver.cc +++ b/src/processor/fast_source_line_resolver.cc @@ -36,6 +36,10 @@ // // Author: Siyang Xie (lambxsy@google.com) +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "google_breakpad/processor/fast_source_line_resolver.h" #include "processor/fast_source_line_resolver_types.h" diff --git a/src/processor/fast_source_line_resolver_unittest.cc b/src/processor/fast_source_line_resolver_unittest.cc index 1bb35019..08340c15 100644 --- a/src/processor/fast_source_line_resolver_unittest.cc +++ b/src/processor/fast_source_line_resolver_unittest.cc @@ -36,6 +36,10 @@ // // Author: Siyang Xie (lambxsy@google.com) +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <assert.h> #include <stdio.h> diff --git a/src/processor/logging.cc b/src/processor/logging.cc index 136f4f8f..46386eb5 100644 --- a/src/processor/logging.cc +++ b/src/processor/logging.cc @@ -32,6 +32,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <assert.h> #include <errno.h> #include <string.h> diff --git a/src/processor/map_serializers_unittest.cc b/src/processor/map_serializers_unittest.cc index 74ebd5e5..cd31ddc8 100644 --- a/src/processor/map_serializers_unittest.cc +++ b/src/processor/map_serializers_unittest.cc @@ -31,6 +31,10 @@ // // Author: Siyang Xie (lambxsy@google.com) +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <climits> #include <map> #include <string> diff --git a/src/processor/microdump.cc b/src/processor/microdump.cc index 83fb098c..94d2c200 100644 --- a/src/processor/microdump.cc +++ b/src/processor/microdump.cc @@ -30,6 +30,10 @@ // // See microdump.h for documentation. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "google_breakpad/processor/microdump.h" #include <stdio.h> diff --git a/src/processor/microdump_processor.cc b/src/processor/microdump_processor.cc index be6150cd..3c25d5cf 100644 --- a/src/processor/microdump_processor.cc +++ b/src/processor/microdump_processor.cc @@ -30,6 +30,10 @@ // // See microdump_processor.h for documentation. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "google_breakpad/processor/microdump_processor.h" #include <assert.h> diff --git a/src/processor/microdump_processor_unittest.cc b/src/processor/microdump_processor_unittest.cc index 3362431b..47f5e35e 100644 --- a/src/processor/microdump_processor_unittest.cc +++ b/src/processor/microdump_processor_unittest.cc @@ -28,6 +28,10 @@ // Unit test for MicrodumpProcessor. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <fstream> #include <iostream> #include <string> diff --git a/src/processor/microdump_stackwalk.cc b/src/processor/microdump_stackwalk.cc index 593b07d6..222310f7 100644 --- a/src/processor/microdump_stackwalk.cc +++ b/src/processor/microdump_stackwalk.cc @@ -29,6 +29,10 @@ // microdump_stackwalk.cc: Process a microdump with MicrodumpProcessor, printing // the results, including stack traces. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <stdio.h> #include <string.h> #include <unistd.h> diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 135770d5..83f72b97 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -32,6 +32,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "google_breakpad/processor/minidump.h" #include <assert.h> @@ -72,6 +76,11 @@ using std::vector; namespace { +// Limit arrived at by adding up possible states in Intel Ch. 13.5 X-SAVE +// MANAGED STATE +// (~ 3680 bytes) plus some extra for the future. +const uint32_t kMaxXSaveAreaSize = 16384; + // Returns true iff |context_size| matches exactly one of the sizes of the // various MDRawContext* types. // TODO(blundell): This function can be removed once @@ -503,6 +512,10 @@ bool MinidumpContext::Read(uint32_t expected_size) { // sizeof(MDRawContextAMD64). For now we skip this extended data. if (expected_size > sizeof(MDRawContextAMD64)) { size_t bytes_left = expected_size - sizeof(MDRawContextAMD64); + if (bytes_left > kMaxXSaveAreaSize) { + BPLOG(ERROR) << "MinidumpContext oversized xstate area"; + return false; + } std::vector<uint8_t> xstate(bytes_left); if (!minidump_->ReadBytes(xstate.data(), bytes_left)) { @@ -1246,12 +1259,11 @@ bool MinidumpContext::Read(uint32_t expected_size) { Swap(&context_riscv->t5); Swap(&context_riscv->t6); - for (int fpr_index = 0; - fpr_index < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; + for (int fpr_index = 0; fpr_index < MD_CONTEXT_RISCV_FPR_COUNT; ++fpr_index) { - Swap(&context_riscv->float_save.regs[fpr_index]); + Swap(&context_riscv->fpregs[fpr_index]); } - Swap(&context_riscv->float_save.fpcsr); + Swap(&context_riscv->fcsr); } SetContextRISCV(context_riscv.release()); @@ -1325,12 +1337,11 @@ bool MinidumpContext::Read(uint32_t expected_size) { Swap(&context_riscv64->t5); Swap(&context_riscv64->t6); - for (int fpr_index = 0; - fpr_index < MD_FLOATINGSAVEAREA_RISCV_FPR_COUNT; + for (int fpr_index = 0; fpr_index < MD_CONTEXT_RISCV_FPR_COUNT; ++fpr_index) { - Swap(&context_riscv64->float_save.regs[fpr_index]); + Swap(&context_riscv64->fpregs[fpr_index]); } - Swap(&context_riscv64->float_save.fpcsr); + Swap(&context_riscv64->fcsr); } SetContextRISCV64(context_riscv64.release()); @@ -5479,6 +5490,27 @@ void MinidumpCrashpadInfo::Print() { printf(" module_list[%d].simple_annotations[\"%s\"] = %s\n", module_index, annot.first.c_str(), annot.second.c_str()); } + const auto& crashpad_annots = + module_crashpad_info_annotation_objects_[module_index]; + for (const AnnotationObject& annot : crashpad_annots) { + std::string str_value; + if (annot.type == 1) { + // Value represents a C-style string. + for (const uint8_t& v : annot.value) { + str_value.append(1, static_cast<char>(v)); + } + } else { + // Value represents something else. + char buffer[3]; + for (const uint8_t& v : annot.value) { + snprintf(buffer, sizeof(buffer), "%02X", v); + str_value.append(buffer); + } + } + printf( + " module_list[%d].crashpad_annotations[\"%s\"] (type = %u) = %s\n", + module_index, annot.name.c_str(), annot.type, str_value.c_str()); + } printf(" address_mask = %" PRIu64 "\n", crashpad_info_.address_mask); } diff --git a/src/processor/minidump_dump.cc b/src/processor/minidump_dump.cc index 83afd1da..d3c33ad4 100644 --- a/src/processor/minidump_dump.cc +++ b/src/processor/minidump_dump.cc @@ -31,6 +31,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <stdio.h> #include <string.h> #include <unistd.h> diff --git a/src/processor/minidump_processor.cc b/src/processor/minidump_processor.cc index fb330e26..5d2dea6d 100644 --- a/src/processor/minidump_processor.cc +++ b/src/processor/minidump_processor.cc @@ -26,6 +26,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "google_breakpad/processor/minidump_processor.h" #include <assert.h> @@ -44,11 +48,14 @@ #include "google_breakpad/processor/process_state.h" #include "google_breakpad/processor/exploitability.h" #include "google_breakpad/processor/stack_frame_symbolizer.h" -#include "processor/disassembler_objdump.h" #include "processor/logging.h" #include "processor/stackwalker_x86.h" #include "processor/symbolic_constants_win.h" +#ifdef __linux__ +#include "processor/disassembler_objdump.h" +#endif + namespace google_breakpad { MinidumpProcessor::MinidumpProcessor(SymbolSupplier* supplier, @@ -56,7 +63,8 @@ MinidumpProcessor::MinidumpProcessor(SymbolSupplier* supplier, : frame_symbolizer_(new StackFrameSymbolizer(supplier, resolver)), own_frame_symbolizer_(true), enable_exploitability_(false), - enable_objdump_(false) { + enable_objdump_(false), + enable_objdump_for_exploitability_(false) { } MinidumpProcessor::MinidumpProcessor(SymbolSupplier* supplier, @@ -65,7 +73,8 @@ MinidumpProcessor::MinidumpProcessor(SymbolSupplier* supplier, : frame_symbolizer_(new StackFrameSymbolizer(supplier, resolver)), own_frame_symbolizer_(true), enable_exploitability_(enable_exploitability), - enable_objdump_(false) { + enable_objdump_(false), + enable_objdump_for_exploitability_(false) { } MinidumpProcessor::MinidumpProcessor(StackFrameSymbolizer* frame_symbolizer, @@ -73,7 +82,8 @@ MinidumpProcessor::MinidumpProcessor(StackFrameSymbolizer* frame_symbolizer, : frame_symbolizer_(frame_symbolizer), own_frame_symbolizer_(false), enable_exploitability_(enable_exploitability), - enable_objdump_(false) { + enable_objdump_(false), + enable_objdump_for_exploitability_(false) { assert(frame_symbolizer_); } @@ -368,9 +378,8 @@ ProcessResult MinidumpProcessor::Process( // rating. if (enable_exploitability_) { scoped_ptr<Exploitability> exploitability( - Exploitability::ExploitabilityForPlatform(dump, - process_state, - enable_objdump_)); + Exploitability::ExploitabilityForPlatform( + dump, process_state, enable_objdump_for_exploitability_)); // The engine will be null if the platform is not supported if (exploitability != NULL) { process_state->exploitability_ = exploitability->CheckExploitability(); @@ -626,6 +635,16 @@ bool MinidumpProcessor::GetCPUInfo(Minidump* dump, SystemInfo* info) { break; } + case MD_CPU_ARCHITECTURE_RISCV: { + info->cpu = "riscv"; + break; + } + + case MD_CPU_ARCHITECTURE_RISCV64: { + info->cpu = "riscv64"; + break; + } + default: { // Assign the numeric architecture ID into the CPU string. char cpu_string[7]; @@ -760,6 +779,8 @@ bool MinidumpProcessor::GetProcessCreateTime(Minidump* dump, return true; } +#ifdef __linux__ + static bool IsCanonicalAddress(uint64_t address) { uint64_t sign_bit = (address >> 63) & 1; for (int shift = 48; shift < 63; ++shift) { @@ -832,6 +853,7 @@ static void CalculateFaultAddressFromInstruction(Minidump* dump, *address = write_address; } } +#endif // __linux__ // static string MinidumpProcessor::GetCrashReason(Minidump* dump, uint64_t* address, @@ -1776,6 +1798,21 @@ string MinidumpProcessor::GetCrashReason(Minidump* dump, uint64_t* address, case MD_EXCEPTION_FLAG_LIN_SEGV_PKUERR: reason.append("SEGV_PKUERR"); break; + case MD_EXCEPTION_FLAG_LIN_SEGV_ACCADI: + reason.append("SEGV_ACCADI"); + break; + case MD_EXCEPTION_FLAG_LIN_SEGV_ADIDERR: + reason.append("SEGV_ADIDERR"); + break; + case MD_EXCEPTION_FLAG_LIN_SEGV_ADIPERR: + reason.append("SEGV_ADIPERR"); + break; + case MD_EXCEPTION_FLAG_LIN_SEGV_MTEAERR: + reason.append("SEGV_MTEAERR"); + break; + case MD_EXCEPTION_FLAG_LIN_SEGV_MTESERR: + reason.append("SEGV_MTESERR"); + break; default: reason.append(flags_string); BPLOG(INFO) << "Unknown exception reason " << reason; @@ -2070,6 +2107,7 @@ string MinidumpProcessor::GetCrashReason(Minidump* dump, uint64_t* address, static_cast<MDCPUArchitecture>(raw_system_info->processor_architecture), *address); +#ifdef __linux__ // For invalid accesses to non-canonical addresses, amd64 cpus don't provide // the fault address, so recover it from the disassembly and register state // if possible. @@ -2078,6 +2116,7 @@ string MinidumpProcessor::GetCrashReason(Minidump* dump, uint64_t* address, && std::numeric_limits<uint64_t>::max() == *address) { CalculateFaultAddressFromInstruction(dump, address); } +#endif // __linux__ } return reason; diff --git a/src/processor/minidump_processor_unittest.cc b/src/processor/minidump_processor_unittest.cc index 1ca8c9fb..de3cfdd5 100644 --- a/src/processor/minidump_processor_unittest.cc +++ b/src/processor/minidump_processor_unittest.cc @@ -29,6 +29,10 @@ // Unit test for MinidumpProcessor. Uses a pre-generated minidump and // corresponding symbol file, and checks the stack frames for correctness. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <stdlib.h> #include <string> diff --git a/src/processor/minidump_stackwalk.cc b/src/processor/minidump_stackwalk.cc index cee9a734..74b41acf 100644 --- a/src/processor/minidump_stackwalk.cc +++ b/src/processor/minidump_stackwalk.cc @@ -31,6 +31,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <stdio.h> #include <string.h> #include <unistd.h> @@ -57,6 +61,7 @@ struct Options { bool machine_readable; bool output_stack_contents; bool output_requesting_thread_only; + bool brief; string minidump_file; std::vector<string> symbol_paths; @@ -110,6 +115,8 @@ bool PrintMinidumpProcess(const Options& options) { if (options.machine_readable) { PrintProcessStateMachineReadable(process_state); + } else if (options.brief) { + PrintRequestingThreadBrief(process_state); } else { PrintProcessState(process_state, options.output_stack_contents, options.output_requesting_thread_only, &resolver); @@ -130,7 +137,8 @@ static void Usage(int argc, const char *argv[], bool error) { "\n" " -m Output in machine-readable format\n" " -s Output stack contents\n" - " -c Output thread that causes crash or dump only\n", + " -c Output thread that causes crash or dump only\n" + " -b Brief of the thread that causes crash or dump\n", google_breakpad::BaseName(argv[0]).c_str()); } @@ -140,14 +148,18 @@ static void SetupOptions(int argc, const char *argv[], Options* options) { options->machine_readable = false; options->output_stack_contents = false; options->output_requesting_thread_only = false; + options->brief = false; - while ((ch = getopt(argc, (char * const*)argv, "chms")) != -1) { + while ((ch = getopt(argc, (char* const*)argv, "bchms")) != -1) { switch (ch) { case 'h': Usage(argc, argv, false); exit(0); break; + case 'b': + options->brief = true; + break; case 'c': options->output_requesting_thread_only = true; break; diff --git a/src/processor/minidump_unittest.cc b/src/processor/minidump_unittest.cc index 53d44ae1..719adf78 100644 --- a/src/processor/minidump_unittest.cc +++ b/src/processor/minidump_unittest.cc @@ -29,6 +29,10 @@ // Unit test for Minidump. Uses a pre-generated minidump and // verifies that certain streams are correct. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <iostream> #include <fstream> #include <sstream> diff --git a/src/processor/module_comparer.cc b/src/processor/module_comparer.cc index 389712c5..a6413038 100644 --- a/src/processor/module_comparer.cc +++ b/src/processor/module_comparer.cc @@ -31,6 +31,10 @@ // // Author: lambxsy@google.com (Siyang Xie) +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "processor/module_comparer.h" #include <map> @@ -64,7 +68,7 @@ bool ModuleComparer::Compare(const string& symbol_data) { buffer.reset(); // Serialize BasicSourceLineResolver::Module. - unsigned int serialized_size = 0; + size_t serialized_size = 0; scoped_array<char> serialized_data( serializer_.Serialize(*(basic_module.get()), &serialized_size)); ASSERT_TRUE(serialized_data.get()); diff --git a/src/processor/module_serializer.cc b/src/processor/module_serializer.cc index d0445094..05519958 100644 --- a/src/processor/module_serializer.cc +++ b/src/processor/module_serializer.cc @@ -32,6 +32,10 @@ // // Author: Siyang Xie (lambxsy@google.com) +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "processor/module_serializer.h" #include <map> @@ -107,10 +111,10 @@ char* ModuleSerializer::Write(const BasicSourceLineResolver::Module& module, return dest; } -char* ModuleSerializer::Serialize( - const BasicSourceLineResolver::Module& module, unsigned int* size) { +char* ModuleSerializer::Serialize(const BasicSourceLineResolver::Module& module, + size_t* size) { // Compute size of memory to allocate. - unsigned int size_to_alloc = SizeOf(module); + const size_t size_to_alloc = SizeOf(module); // Allocate memory for serialized data. char* serialized_data = new char[size_to_alloc]; @@ -124,8 +128,8 @@ char* ModuleSerializer::Serialize( // Write serialized data to allocated memory chunk. char* end_address = Write(module, serialized_data); // Verify the allocated memory size is equal to the size of data been written. - unsigned int size_written = - static_cast<unsigned int>(end_address - serialized_data); + const size_t size_written = + static_cast<size_t>(end_address - serialized_data); if (size_to_alloc != size_written) { BPLOG(ERROR) << "size_to_alloc differs from size_written: " << size_to_alloc << " vs " << size_written; @@ -134,6 +138,7 @@ char* ModuleSerializer::Serialize( // Set size and return the start address of memory chunk. if (size) *size = size_to_alloc; + return serialized_data; } @@ -146,7 +151,7 @@ bool ModuleSerializer::SerializeModuleAndLoadIntoFastResolver( BasicSourceLineResolver::Module* basic_module = dynamic_cast<BasicSourceLineResolver::Module*>(iter->second); - unsigned int size = 0; + size_t size = 0; scoped_array<char> symbol_data(Serialize(*basic_module, &size)); if (!symbol_data.get()) { BPLOG(ERROR) << "Serialization failed for module: " << basic_module->name_; @@ -197,8 +202,8 @@ bool ModuleSerializer::ConvertOneModule( return SerializeModuleAndLoadIntoFastResolver(iter, fast_resolver); } -char* ModuleSerializer::SerializeSymbolFileData( - const string& symbol_data, unsigned int* size) { +char* ModuleSerializer::SerializeSymbolFileData(const string& symbol_data, + size_t* size) { scoped_ptr<BasicSourceLineResolver::Module> module( new BasicSourceLineResolver::Module("no name")); scoped_array<char> buffer(new char[symbol_data.size() + 1]); diff --git a/src/processor/module_serializer.h b/src/processor/module_serializer.h index 4e365a41..fd387cbb 100644 --- a/src/processor/module_serializer.h +++ b/src/processor/module_serializer.h @@ -72,13 +72,13 @@ class ModuleSerializer { // Caller takes the ownership of the memory chunk (allocated on heap), and // owner should call delete [] to free the memory after use. char* Serialize(const BasicSourceLineResolver::Module& module, - unsigned int* size = NULL); + size_t* size = nullptr); // Given the string format symbol_data, produces a chunk of serialized data. // Caller takes ownership of the serialized data (on heap), and owner should // call delete [] to free the memory after use. char* SerializeSymbolFileData(const string& symbol_data, - unsigned int* size = NULL); + size_t* size = nullptr); // Serializes one loaded module with given moduleid in the basic source line // resolver, and loads the serialized data into the fast source line resolver. diff --git a/src/processor/pathname_stripper.cc b/src/processor/pathname_stripper.cc index f34b53f7..11dc6974 100644 --- a/src/processor/pathname_stripper.cc +++ b/src/processor/pathname_stripper.cc @@ -32,6 +32,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "processor/pathname_stripper.h" namespace google_breakpad { diff --git a/src/processor/pathname_stripper_unittest.cc b/src/processor/pathname_stripper_unittest.cc index ff474a7b..c5c39cc8 100644 --- a/src/processor/pathname_stripper_unittest.cc +++ b/src/processor/pathname_stripper_unittest.cc @@ -26,6 +26,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <stdio.h> #include "processor/pathname_stripper.h" diff --git a/src/processor/postfix_evaluator_unittest.cc b/src/processor/postfix_evaluator_unittest.cc index 76d85751..d3c52409 100644 --- a/src/processor/postfix_evaluator_unittest.cc +++ b/src/processor/postfix_evaluator_unittest.cc @@ -30,6 +30,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <assert.h> #include <stdio.h> diff --git a/src/processor/proc_maps_linux.cc b/src/processor/proc_maps_linux.cc index 05c1145a..6fcb909a 100644 --- a/src/processor/proc_maps_linux.cc +++ b/src/processor/proc_maps_linux.cc @@ -6,6 +6,10 @@ #define __STDC_FORMAT_MACROS #endif +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "google_breakpad/processor/proc_maps_linux.h" #include <fcntl.h> diff --git a/src/processor/proc_maps_linux_unittest.cc b/src/processor/proc_maps_linux_unittest.cc index dc51babb..3d683cad 100644 --- a/src/processor/proc_maps_linux_unittest.cc +++ b/src/processor/proc_maps_linux_unittest.cc @@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "breakpad_googletest_includes.h" #include "common/using_std_string.h" #include "google_breakpad/processor/proc_maps_linux.h" diff --git a/src/processor/process_state.cc b/src/processor/process_state.cc index 95bbd48d..c5c38b6c 100644 --- a/src/processor/process_state.cc +++ b/src/processor/process_state.cc @@ -32,6 +32,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "google_breakpad/processor/process_state.h" #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/code_modules.h" diff --git a/src/processor/range_map_truncate_lower_unittest.cc b/src/processor/range_map_truncate_lower_unittest.cc index 12dad873..b3599fc5 100644 --- a/src/processor/range_map_truncate_lower_unittest.cc +++ b/src/processor/range_map_truncate_lower_unittest.cc @@ -26,6 +26,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <limits.h> #include <stdio.h> diff --git a/src/processor/range_map_truncate_upper_unittest.cc b/src/processor/range_map_truncate_upper_unittest.cc index 57046e19..aa058ad4 100644 --- a/src/processor/range_map_truncate_upper_unittest.cc +++ b/src/processor/range_map_truncate_upper_unittest.cc @@ -31,6 +31,10 @@ // // Author: Ivan Penkov +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <limits.h> #include <stdio.h> diff --git a/src/processor/range_map_unittest.cc b/src/processor/range_map_unittest.cc index 2745e809..8735bb09 100644 --- a/src/processor/range_map_unittest.cc +++ b/src/processor/range_map_unittest.cc @@ -31,6 +31,10 @@ // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <limits.h> #include <stdio.h> diff --git a/src/processor/simple_symbol_supplier.cc b/src/processor/simple_symbol_supplier.cc index 5b3f6819..0de34c94 100644 --- a/src/processor/simple_symbol_supplier.cc +++ b/src/processor/simple_symbol_supplier.cc @@ -32,6 +32,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "processor/simple_symbol_supplier.h" #include <assert.h> diff --git a/src/processor/source_line_resolver_base.cc b/src/processor/source_line_resolver_base.cc index 5c0b6cd7..da9ff762 100644 --- a/src/processor/source_line_resolver_base.cc +++ b/src/processor/source_line_resolver_base.cc @@ -33,6 +33,10 @@ // // Author: Siyang Xie (lambxsy@google.com) +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <stdio.h> #include <string.h> #include <sys/stat.h> diff --git a/src/processor/stack_frame_cpu.cc b/src/processor/stack_frame_cpu.cc index e31a3198..4a4a052c 100644 --- a/src/processor/stack_frame_cpu.cc +++ b/src/processor/stack_frame_cpu.cc @@ -32,6 +32,10 @@ // // Author: Colin Blundell +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "google_breakpad/processor/stack_frame_cpu.h" namespace google_breakpad { diff --git a/src/processor/stack_frame_symbolizer.cc b/src/processor/stack_frame_symbolizer.cc index 0d124a02..3afd471b 100644 --- a/src/processor/stack_frame_symbolizer.cc +++ b/src/processor/stack_frame_symbolizer.cc @@ -31,6 +31,10 @@ // line information in a stack frame, and also looks up WindowsFrameInfo or // CFIFrameInfo for a stack frame. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "google_breakpad/processor/stack_frame_symbolizer.h" #include <assert.h> diff --git a/src/processor/stackwalk_common.cc b/src/processor/stackwalk_common.cc index a1b6364d..688b2782 100644 --- a/src/processor/stackwalk_common.cc +++ b/src/processor/stackwalk_common.cc @@ -31,6 +31,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "processor/stackwalk_common.h" #include <assert.h> @@ -273,6 +277,32 @@ static void PrintStackContents(const string& indent, printf("\n"); } +static void PrintFrameHeader(const StackFrame* frame, int frame_index) { + printf("%2d ", frame_index); + + uint64_t instruction_address = frame->ReturnAddress(); + + if (frame->module) { + printf("%s", PathnameStripper::File(frame->module->code_file()).c_str()); + if (!frame->function_name.empty()) { + printf("!%s", frame->function_name.c_str()); + if (!frame->source_file_name.empty()) { + string source_file = PathnameStripper::File(frame->source_file_name); + printf(" [%s : %d + 0x%" PRIx64 "]", source_file.c_str(), + frame->source_line, + instruction_address - frame->source_line_base); + } else { + printf(" + 0x%" PRIx64, instruction_address - frame->function_base); + } + } else { + printf(" + 0x%" PRIx64, + instruction_address - frame->module->base_address()); + } + } else { + printf("0x%" PRIx64, instruction_address); + } +} + // PrintStack prints the call stack in |stack| to stdout, in a reasonably // useful form. Module, function, and source file names are displayed if // they are available. The code offset to the base code address of the @@ -294,30 +324,7 @@ static void PrintStack(const CallStack* stack, } for (int frame_index = 0; frame_index < frame_count; ++frame_index) { const StackFrame* frame = stack->frames()->at(frame_index); - printf("%2d ", frame_index); - - uint64_t instruction_address = frame->ReturnAddress(); - - if (frame->module) { - printf("%s", PathnameStripper::File(frame->module->code_file()).c_str()); - if (!frame->function_name.empty()) { - printf("!%s", frame->function_name.c_str()); - if (!frame->source_file_name.empty()) { - string source_file = PathnameStripper::File(frame->source_file_name); - printf(" [%s : %d + 0x%" PRIx64 "]", - source_file.c_str(), - frame->source_line, - instruction_address - frame->source_line_base); - } else { - printf(" + 0x%" PRIx64, instruction_address - frame->function_base); - } - } else { - printf(" + 0x%" PRIx64, - instruction_address - frame->module->base_address()); - } - } else { - printf("0x%" PRIx64, instruction_address); - } + PrintFrameHeader(frame, frame_index); printf("\n "); // Inlined frames don't have registers info. @@ -1277,4 +1284,21 @@ void PrintProcessStateMachineReadable(const ProcessState& process_state) { } } +void PrintRequestingThreadBrief(const ProcessState& process_state) { + int requesting_thread = process_state.requesting_thread(); + if (requesting_thread == -1) { + printf(" <no crashing or requesting dump thread identified>\n"); + return; + } + + printf("Thread %d (%s)\n", requesting_thread, + process_state.crashed() ? "crashed" : "requested dump, did not crash"); + const CallStack* stack = process_state.threads()->at(requesting_thread); + int frame_count = stack->frames()->size(); + for (int frame_index = 0; frame_index < frame_count; ++frame_index) { + PrintFrameHeader(stack->frames()->at(frame_index), frame_index); + printf("\n"); + } +} + } // namespace google_breakpad diff --git a/src/processor/stackwalk_common.h b/src/processor/stackwalk_common.h index bb12b98f..3782f987 100644 --- a/src/processor/stackwalk_common.h +++ b/src/processor/stackwalk_common.h @@ -43,6 +43,7 @@ void PrintProcessState(const ProcessState& process_state, bool output_stack_contents, bool output_requesting_thread_only, SourceLineResolverInterface* resolver); +void PrintRequestingThreadBrief(const ProcessState& process_state); } // namespace google_breakpad diff --git a/src/processor/stackwalker.cc b/src/processor/stackwalker.cc index e607b721..1ff6cf7c 100644 --- a/src/processor/stackwalker.cc +++ b/src/processor/stackwalker.cc @@ -32,6 +32,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "google_breakpad/processor/stackwalker.h" #include <assert.h> diff --git a/src/processor/stackwalker_address_list.cc b/src/processor/stackwalker_address_list.cc index b393d475..7c346c66 100644 --- a/src/processor/stackwalker_address_list.cc +++ b/src/processor/stackwalker_address_list.cc @@ -32,6 +32,10 @@ // // Author: Chris Hamilton <chrisha@chromium.org> +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <assert.h> #include <vector> diff --git a/src/processor/stackwalker_address_list.h b/src/processor/stackwalker_address_list.h index 28d377c3..d27f3fb2 100644 --- a/src/processor/stackwalker_address_list.h +++ b/src/processor/stackwalker_address_list.h @@ -36,7 +36,6 @@ #ifndef PROCESSOR_STACKWALKER_ADDRESS_LIST_H_ #define PROCESSOR_STACKWALKER_ADDRESS_LIST_H_ -#include "common/basictypes.h" #include "google_breakpad/common/breakpad_types.h" #include "google_breakpad/processor/stackwalker.h" @@ -53,6 +52,8 @@ class StackwalkerAddressList : public Stackwalker { size_t frame_count, const CodeModules* modules, StackFrameSymbolizer* frame_symbolizer); + StackwalkerAddressList(const StackwalkerAddressList&) = delete; + void operator=(const StackwalkerAddressList&) = delete; private: // Implementation of Stackwalker. @@ -62,8 +63,6 @@ class StackwalkerAddressList : public Stackwalker { const uint64_t* frames_; size_t frame_count_; - - DISALLOW_COPY_AND_ASSIGN(StackwalkerAddressList); }; } // namespace google_breakpad diff --git a/src/processor/stackwalker_address_list_unittest.cc b/src/processor/stackwalker_address_list_unittest.cc index feda6268..1b5a4fc7 100644 --- a/src/processor/stackwalker_address_list_unittest.cc +++ b/src/processor/stackwalker_address_list_unittest.cc @@ -31,6 +31,10 @@ // // Author: Chris Hamilton <chrisha@chromium.org> +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <string> #include <vector> diff --git a/src/processor/stackwalker_amd64.cc b/src/processor/stackwalker_amd64.cc index 6a539709..b934e73b 100644 --- a/src/processor/stackwalker_amd64.cc +++ b/src/processor/stackwalker_amd64.cc @@ -32,6 +32,10 @@ // // Author: Mark Mentovai, Ted Mielczarek +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <assert.h> #include "common/scoped_ptr.h" diff --git a/src/processor/stackwalker_amd64_unittest.cc b/src/processor/stackwalker_amd64_unittest.cc index a7e513e9..88f6ef7f 100644 --- a/src/processor/stackwalker_amd64_unittest.cc +++ b/src/processor/stackwalker_amd64_unittest.cc @@ -30,6 +30,10 @@ // stackwalker_amd64_unittest.cc: Unit tests for StackwalkerAMD64 class. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <string.h> #include <string> #include <vector> diff --git a/src/processor/stackwalker_arm.cc b/src/processor/stackwalker_arm.cc index 7df2eb6d..5f6f3e8d 100644 --- a/src/processor/stackwalker_arm.cc +++ b/src/processor/stackwalker_arm.cc @@ -32,6 +32,10 @@ // // Author: Mark Mentovai, Ted Mielczarek, Jim Blandy +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <vector> #include "common/scoped_ptr.h" diff --git a/src/processor/stackwalker_arm64.cc b/src/processor/stackwalker_arm64.cc index ae3a0595..9c09835f 100644 --- a/src/processor/stackwalker_arm64.cc +++ b/src/processor/stackwalker_arm64.cc @@ -32,6 +32,10 @@ // // Author: Mark Mentovai, Ted Mielczarek, Jim Blandy, Colin Blundell +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <vector> #include "common/scoped_ptr.h" diff --git a/src/processor/stackwalker_arm64_unittest.cc b/src/processor/stackwalker_arm64_unittest.cc index 37475058..f302d7d5 100644 --- a/src/processor/stackwalker_arm64_unittest.cc +++ b/src/processor/stackwalker_arm64_unittest.cc @@ -30,6 +30,10 @@ // stackwalker_arm64_unittest.cc: Unit tests for StackwalkerARM64 class. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <string.h> #include <string> #include <vector> diff --git a/src/processor/stackwalker_arm_unittest.cc b/src/processor/stackwalker_arm_unittest.cc index 20c810a7..6103e202 100644 --- a/src/processor/stackwalker_arm_unittest.cc +++ b/src/processor/stackwalker_arm_unittest.cc @@ -30,6 +30,10 @@ // stackwalker_arm_unittest.cc: Unit tests for StackwalkerARM class. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <string.h> #include <string> #include <vector> diff --git a/src/processor/stackwalker_mips.cc b/src/processor/stackwalker_mips.cc index 11b08fae..7195c162 100644 --- a/src/processor/stackwalker_mips.cc +++ b/src/processor/stackwalker_mips.cc @@ -32,6 +32,10 @@ // // Author: Tata Elxsi +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "common/scoped_ptr.h" #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/code_modules.h" diff --git a/src/processor/stackwalker_mips64_unittest.cc b/src/processor/stackwalker_mips64_unittest.cc index aefcf8ee..55b7503f 100644 --- a/src/processor/stackwalker_mips64_unittest.cc +++ b/src/processor/stackwalker_mips64_unittest.cc @@ -31,6 +31,10 @@ // stackwalker_mips64_unittest.cc: Unit tests for StackwalkerMIPS class for // mips64 platforms. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <string.h> #include <string> #include <vector> diff --git a/src/processor/stackwalker_mips_unittest.cc b/src/processor/stackwalker_mips_unittest.cc index ac7324c4..305f4db8 100644 --- a/src/processor/stackwalker_mips_unittest.cc +++ b/src/processor/stackwalker_mips_unittest.cc @@ -30,6 +30,10 @@ // stackwalker_mips_unittest.cc: Unit tests for StackwalkerMIPS class. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <string.h> #include <string> #include <vector> diff --git a/src/processor/stackwalker_ppc.cc b/src/processor/stackwalker_ppc.cc index e71d9138..0083392b 100644 --- a/src/processor/stackwalker_ppc.cc +++ b/src/processor/stackwalker_ppc.cc @@ -33,6 +33,10 @@ // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "common/scoped_ptr.h" #include "processor/stackwalker_ppc.h" #include "google_breakpad/processor/call_stack.h" diff --git a/src/processor/stackwalker_ppc64.cc b/src/processor/stackwalker_ppc64.cc index 9ac8e45b..c36d16be 100644 --- a/src/processor/stackwalker_ppc64.cc +++ b/src/processor/stackwalker_ppc64.cc @@ -31,6 +31,10 @@ // See stackwalker_ppc64.h for documentation. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "common/scoped_ptr.h" #include "processor/stackwalker_ppc64.h" #include "google_breakpad/processor/call_stack.h" diff --git a/src/processor/stackwalker_riscv.cc b/src/processor/stackwalker_riscv.cc index 3d8a64f4..c3681a61 100644 --- a/src/processor/stackwalker_riscv.cc +++ b/src/processor/stackwalker_riscv.cc @@ -33,6 +33,10 @@ * Author: Iacopo Colonnelli */ +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "common/scoped_ptr.h" #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/code_modules.h" diff --git a/src/processor/stackwalker_riscv64.cc b/src/processor/stackwalker_riscv64.cc index d97bad63..0ed7b5e6 100644 --- a/src/processor/stackwalker_riscv64.cc +++ b/src/processor/stackwalker_riscv64.cc @@ -33,6 +33,10 @@ * Author: Iacopo Colonnelli */ +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "common/scoped_ptr.h" #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/code_modules.h" diff --git a/src/processor/stackwalker_riscv64_unittest.cc b/src/processor/stackwalker_riscv64_unittest.cc index 73c06264..c8579b9b 100644 --- a/src/processor/stackwalker_riscv64_unittest.cc +++ b/src/processor/stackwalker_riscv64_unittest.cc @@ -31,6 +31,10 @@ * Author: Iacopo Colonnelli */ +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <string.h> #include <string> #include <vector> diff --git a/src/processor/stackwalker_riscv_unittest.cc b/src/processor/stackwalker_riscv_unittest.cc index f4a6b79c..37f0e233 100644 --- a/src/processor/stackwalker_riscv_unittest.cc +++ b/src/processor/stackwalker_riscv_unittest.cc @@ -31,6 +31,10 @@ * Author: Iacopo Colonnelli */ +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <string.h> #include <string> #include <vector> diff --git a/src/processor/stackwalker_selftest.cc b/src/processor/stackwalker_selftest.cc index 2737f64d..4f3483b4 100644 --- a/src/processor/stackwalker_selftest.cc +++ b/src/processor/stackwalker_selftest.cc @@ -48,6 +48,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <assert.h> #include "processor/logging.h" diff --git a/src/processor/stackwalker_sparc.cc b/src/processor/stackwalker_sparc.cc index fb76744c..ed7f7dc3 100644 --- a/src/processor/stackwalker_sparc.cc +++ b/src/processor/stackwalker_sparc.cc @@ -33,6 +33,10 @@ // Author: Michael Shang +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/memory_region.h" #include "google_breakpad/processor/stack_frame_cpu.h" diff --git a/src/processor/stackwalker_x86.cc b/src/processor/stackwalker_x86.cc index b598c5bd..9bda5f8c 100644 --- a/src/processor/stackwalker_x86.cc +++ b/src/processor/stackwalker_x86.cc @@ -32,6 +32,10 @@ // // Author: Mark Mentovai +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <assert.h> #include <string> diff --git a/src/processor/stackwalker_x86_unittest.cc b/src/processor/stackwalker_x86_unittest.cc index 3d786b8e..b614b0e4 100644 --- a/src/processor/stackwalker_x86_unittest.cc +++ b/src/processor/stackwalker_x86_unittest.cc @@ -30,6 +30,10 @@ // stackwalker_x86_unittest.cc: Unit tests for StackwalkerX86 class. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <string> #include <vector> diff --git a/src/processor/static_address_map_unittest.cc b/src/processor/static_address_map_unittest.cc index 2e206a09..aebab976 100644 --- a/src/processor/static_address_map_unittest.cc +++ b/src/processor/static_address_map_unittest.cc @@ -30,6 +30,10 @@ // // Author: Siyang Xie (lambxsy@google.com) +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <climits> #include <cstdlib> #include <ctime> diff --git a/src/processor/static_contained_range_map_unittest.cc b/src/processor/static_contained_range_map_unittest.cc index cdc11c1d..d0507a4b 100644 --- a/src/processor/static_contained_range_map_unittest.cc +++ b/src/processor/static_contained_range_map_unittest.cc @@ -31,6 +31,10 @@ // // Author: Siyang Xie (lambxsy@google.com) +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "breakpad_googletest_includes.h" #include "common/scoped_ptr.h" #include "processor/contained_range_map-inl.h" diff --git a/src/processor/static_map_unittest.cc b/src/processor/static_map_unittest.cc index 4360e8c6..67b201b6 100644 --- a/src/processor/static_map_unittest.cc +++ b/src/processor/static_map_unittest.cc @@ -30,6 +30,10 @@ // // Author: Siyang Xie (lambxsy@google.com) +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <climits> #include <map> diff --git a/src/processor/static_range_map_unittest.cc b/src/processor/static_range_map_unittest.cc index 3903e948..d4ddec0c 100644 --- a/src/processor/static_range_map_unittest.cc +++ b/src/processor/static_range_map_unittest.cc @@ -30,6 +30,10 @@ // // Author: Siyang Xie (lambxsy@google.com) +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "breakpad_googletest_includes.h" #include "common/scoped_ptr.h" #include "processor/range_map-inl.h" diff --git a/src/processor/symbolic_constants_win.cc b/src/processor/symbolic_constants_win.cc index 0c57b686..98c2b4dd 100644 --- a/src/processor/symbolic_constants_win.cc +++ b/src/processor/symbolic_constants_win.cc @@ -32,6 +32,10 @@ // // Author: Ben Wagner +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <string> #include "common/stdio_wrapper.h" diff --git a/src/processor/synth_minidump.cc b/src/processor/synth_minidump.cc index 9dacb395..e51d1060 100644 --- a/src/processor/synth_minidump.cc +++ b/src/processor/synth_minidump.cc @@ -30,6 +30,10 @@ // synth_minidump.cc: Implementation of SynthMinidump. See synth_minidump.h +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include "processor/synth_minidump.h" namespace google_breakpad { diff --git a/src/processor/synth_minidump_unittest.cc b/src/processor/synth_minidump_unittest.cc index 4bc46747..3b803afe 100644 --- a/src/processor/synth_minidump_unittest.cc +++ b/src/processor/synth_minidump_unittest.cc @@ -31,6 +31,10 @@ // synth_minidump_unittest.cc: Unit tests for google_breakpad::SynthMinidump // classes. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <sstream> #include <string> diff --git a/src/processor/testdata/linux_test_app.cc b/src/processor/testdata/linux_test_app.cc index 4ff4f707..b0bbb669 100644 --- a/src/processor/testdata/linux_test_app.cc +++ b/src/processor/testdata/linux_test_app.cc @@ -38,6 +38,10 @@ // generate an executable with STABS symbols (needs -m32), or -gdwarf-2 for one // with DWARF symbols (32- or 64-bit) +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <stdio.h> #include <sys/types.h> #include <unistd.h> diff --git a/src/processor/testdata/test_app.cc b/src/processor/testdata/test_app.cc index 79cabef0..83468fbb 100644 --- a/src/processor/testdata/test_app.cc +++ b/src/processor/testdata/test_app.cc @@ -31,6 +31,10 @@ // google_breakpad/src/client/windows/releasestaticcrt/exception_handler.lib // Then run test_app to generate a dump, and dump_syms to create the .sym file. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <stdio.h> #include "client/windows/handler/exception_handler.h" diff --git a/src/processor/tokenize.cc b/src/processor/tokenize.cc index 4e62f2ea..a46c9644 100644 --- a/src/processor/tokenize.cc +++ b/src/processor/tokenize.cc @@ -26,6 +26,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifdef HAVE_CONFIG_H +#include <config.h> // Must come first +#endif + #include <string.h> #include <string> |