From 11ec9c32888c06665b8838f709bd66c0be9789a6 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Tue, 5 Dec 2023 12:57:29 +0100 Subject: [PATCH 01/91] Fix stack walking using StackwalkerAddressList. When building a stack trace using StackwalkerAddressList, if there are inlined frames then the stack trace will skip over the following frames, leading to missing frames in the symbolized stacktraces. Bug: 314930064 Change-Id: I5c7a1b2e7c2f728e27b2082e77ebe953808f38bc Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5087692 Reviewed-by: Joshua Peraza --- src/processor/stackwalker_address_list.cc | 19 ++- src/processor/stackwalker_address_list.h | 1 + .../stackwalker_address_list_unittest.cc | 111 ++++++++++++++++-- 3 files changed, 110 insertions(+), 21 deletions(-) diff --git a/src/processor/stackwalker_address_list.cc b/src/processor/stackwalker_address_list.cc index 7c346c665..ca9f5cf9b 100644 --- a/src/processor/stackwalker_address_list.cc +++ b/src/processor/stackwalker_address_list.cc @@ -56,7 +56,8 @@ StackwalkerAddressList::StackwalkerAddressList( StackFrameSymbolizer* frame_symbolizer) : Stackwalker(NULL, NULL, modules, frame_symbolizer), frames_(frames), - frame_count_(frame_count) { + frame_count_(frame_count), + next_frame_index_(0) { assert(frames); assert(frame_symbolizer); } @@ -68,26 +69,22 @@ StackFrame* StackwalkerAddressList::GetContextFrame() { StackFrame* frame = new StackFrame(); frame->instruction = frames_[0]; frame->trust = StackFrame::FRAME_TRUST_PREWALKED; + + next_frame_index_ = 1; + return frame; } -StackFrame* StackwalkerAddressList::GetCallerFrame(const CallStack* stack, +StackFrame* StackwalkerAddressList::GetCallerFrame(const CallStack*, bool stack_scan_allowed) { - if (!stack) { - BPLOG(ERROR) << "Can't get caller frame without stack"; - return NULL; - } - - size_t frame_index = stack->frames()->size(); - // There are no more frames to fetch. - if (frame_index >= frame_count_) + if (next_frame_index_ >= frame_count_) return NULL; // All frames have the highest level of trust because they were // explicitly provided. StackFrame* frame = new StackFrame(); - frame->instruction = frames_[frame_index]; + frame->instruction = frames_[next_frame_index_++]; frame->trust = StackFrame::FRAME_TRUST_PREWALKED; return frame; } diff --git a/src/processor/stackwalker_address_list.h b/src/processor/stackwalker_address_list.h index d27f3fb2d..b024d2ca6 100644 --- a/src/processor/stackwalker_address_list.h +++ b/src/processor/stackwalker_address_list.h @@ -63,6 +63,7 @@ class StackwalkerAddressList : public Stackwalker { const uint64_t* frames_; size_t frame_count_; + size_t next_frame_index_; }; } // namespace google_breakpad diff --git a/src/processor/stackwalker_address_list_unittest.cc b/src/processor/stackwalker_address_list_unittest.cc index 1b5a4fc79..bbd033511 100644 --- a/src/processor/stackwalker_address_list_unittest.cc +++ b/src/processor/stackwalker_address_list_unittest.cc @@ -107,18 +107,32 @@ class StackwalkerAddressListTest : public testing::Test { Return(MockSymbolSupplier::FOUND))); } - void CheckCallStack(const CallStack& call_stack) { + void CheckCallStack(const CallStack& call_stack, bool allow_inline=false) { const std::vector* frames = call_stack.frames(); - ASSERT_EQ(arraysize(kDummyFrames), frames->size()); - for (size_t i = 0; i < arraysize(kDummyFrames); ++i) { - ASSERT_EQ(kDummyFrames[i], frames->at(i)->instruction); - ASSERT_EQ(StackFrame::FRAME_TRUST_PREWALKED, frames->at(i)->trust); + ASSERT_LE(arraysize(kDummyFrames), frames->size()); + + // Iterate through the produced stack frames, validating that all of the + // prewalked frames match the expected input frames. Inlined frames are only + // allowed if `allow_inline` is set to true. + + size_t j = 0; + for (size_t i = 0; i < frames->size(); ++i) { + if (j <= 2) { + ASSERT_EQ(static_cast(&module2), frames->at(i)->module); + } else { + ASSERT_EQ(static_cast(&module1), frames->at(i)->module); + } + + ASSERT_EQ(kDummyFrames[j], frames->at(i)->instruction); + if (frames->at(i)->trust == StackFrame::FRAME_TRUST_PREWALKED) { + // Only move on to the next "real" stack frame if this isn't an + // inlined stack frame. + ++j; + } else { + ASSERT_TRUE(allow_inline); + ASSERT_EQ(StackFrame::FRAME_TRUST_INLINE, frames->at(i)->trust); + } } - ASSERT_EQ(static_cast(&module2), frames->at(0)->module); - ASSERT_EQ(static_cast(&module2), frames->at(1)->module); - ASSERT_EQ(static_cast(&module2), frames->at(2)->module); - ASSERT_EQ(static_cast(&module1), frames->at(3)->module); - ASSERT_EQ(static_cast(&module1), frames->at(4)->module); } MockCodeModule module1; @@ -199,3 +213,80 @@ TEST_F(StackwalkerAddressListTest, ScanWithSymbols) { ASSERT_EQ("mod1func1", frames->at(4)->function_name); ASSERT_EQ(0x40001000u, frames->at(4)->function_base); } + +TEST_F(StackwalkerAddressListTest, ScanWithInlining) { + // File : FILE number(dex) name + // Function: FUNC address(hex) size(hex) parameter_size(hex) name + // Inline: : INLINE_ORIGIN number(dec) name + // : INLINE depth(dec) line(dec) filenum(dec) inlinenum(dec) + // address(hex) size(hex) + // Line : address(hex) size(hex) line(dec) filenum(dec) + SetModuleSymbols(&module2, + "FILE 1 module2.cc\n" + "INLINE_ORIGIN 0 mod2inlinefunc1\n" + "INLINE_ORIGIN 1 mod2inlinefunc2\n" + "INLINE_ORIGIN 2 mod2inlinefunc3\n" + "FUNC 3000 100 10 mod2func3\n" + "INLINE 0 1 1 1 3000 10\n" + "INLINE 1 1 1 2 3000 10\n" + "3000 10 1 1\n" + "FUNC 2000 200 10 mod2func2\n" + "INLINE 0 1 1 0 2000 10\n" + "FUNC 1000 300 10 mod2func1\n"); + SetModuleSymbols(&module1, + "FUNC 2000 200 10 mod1func2\n" + "FUNC 1000 300 10 mod1func1\n"); + + StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); + StackwalkerAddressList walker(kDummyFrames, arraysize(kDummyFrames), + &modules, &frame_symbolizer); + + CallStack call_stack; + vector modules_without_symbols; + vector modules_with_corrupt_symbols; + ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, + &modules_with_corrupt_symbols)); + + ASSERT_EQ(0u, modules_without_symbols.size()); + ASSERT_EQ(0u, modules_with_corrupt_symbols.size()); + + ASSERT_NO_FATAL_FAILURE(CheckCallStack(call_stack, /*allow_inline=*/true)); + + const std::vector* frames = call_stack.frames(); + + // We have full file/line information for the first function call, including + // inline functions + ASSERT_EQ("mod2inlinefunc3", frames->at(0)->function_name); + ASSERT_EQ(0x50003000u, frames->at(0)->function_base); + ASSERT_EQ("module2.cc", frames->at(0)->source_file_name); + ASSERT_EQ(1, frames->at(0)->source_line); + ASSERT_EQ(0x50003000u, frames->at(0)->source_line_base); + + ASSERT_EQ("mod2inlinefunc2", frames->at(1)->function_name); + ASSERT_EQ(0x50003000u, frames->at(1)->function_base); + ASSERT_EQ("module2.cc", frames->at(1)->source_file_name); + ASSERT_EQ(1, frames->at(1)->source_line); + ASSERT_EQ(0x50003000u, frames->at(1)->source_line_base); + + ASSERT_EQ("mod2func3", frames->at(2)->function_name); + ASSERT_EQ(0x50003000u, frames->at(2)->function_base); + ASSERT_EQ("module2.cc", frames->at(2)->source_file_name); + ASSERT_EQ(1, frames->at(2)->source_line); + ASSERT_EQ(0x50003000u, frames->at(2)->source_line_base); + + // Here we have inlining information, but no file/line information. + ASSERT_EQ("mod2inlinefunc1", frames->at(3)->function_name); + ASSERT_EQ(0x50002000u, frames->at(3)->function_base); + + ASSERT_EQ("mod2func2", frames->at(4)->function_name); + ASSERT_EQ(0x50002000u, frames->at(4)->function_base); + + ASSERT_EQ("mod2func1", frames->at(5)->function_name); + ASSERT_EQ(0x50001000u, frames->at(5)->function_base); + + ASSERT_EQ("mod1func2", frames->at(6)->function_name); + ASSERT_EQ(0x40002000u, frames->at(6)->function_base); + + ASSERT_EQ("mod1func1", frames->at(7)->function_name); + ASSERT_EQ(0x40001000u, frames->at(7)->function_base); +} From ed1d564c9edf88c2967474859d0c2b1f0400bf53 Mon Sep 17 00:00:00 2001 From: Nathan Moinvaziri Date: Fri, 29 Dec 2023 07:23:17 -0800 Subject: [PATCH 02/91] Fixed high AddressType variable used without being assigned In RangeMap::StoreRangeInternal, when size <= 0 and !high_ok then the high variable is passed to HexString uninitialized. Change-Id: I7e597cadaf248b607c646534a5d800c17ccdeda9 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5155712 Reviewed-by: Robert Sesek --- src/processor/range_map-inl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/processor/range_map-inl.h b/src/processor/range_map-inl.h index 860314f52..d1a194f31 100644 --- a/src/processor/range_map-inl.h +++ b/src/processor/range_map-inl.h @@ -57,7 +57,7 @@ template bool RangeMap::StoreRangeInternal( const AddressType& base, const AddressType& delta, const AddressType& size, const EntryType& entry) { - AddressType high; + AddressType high = AddressType(); bool high_ok = false; if (size > 0) { std::pair result = AddWithOverflowCheck(base, size - 1); From 898a997855168c0e6a689072fefba89246271a5d Mon Sep 17 00:00:00 2001 From: Nathan Moinvaziri Date: Tue, 19 Dec 2023 14:35:05 -0800 Subject: [PATCH 03/91] Fixed missing include for std::find_if. Throws an error when compiling on Windows. Change-Id: Ieb34c00cf199aaa1b45a440086c48b8ed363b3c7 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5137658 Reviewed-by: Ivan Penkov --- src/common/module.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/module.cc b/src/common/module.cc index 0eb5aad82..b6f5da7e6 100644 --- a/src/common/module.cc +++ b/src/common/module.cc @@ -42,6 +42,7 @@ #include #include +#include #include #include #include From 8e125760dc42bf6fc48725f4f9254a714662a3ac Mon Sep 17 00:00:00 2001 From: Nathan Moinvaziri Date: Tue, 2 Jan 2024 13:19:30 -0800 Subject: [PATCH 04/91] Fixed opening minidump on Windows in MinidumpTest.TestMinidumpFromStream Minidump file needs to be opened as binary. Change-Id: I15f148ec905c9491050b77a77e86e2749da93515 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5160989 Reviewed-by: Sterling Augustine --- src/processor/minidump_unittest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/processor/minidump_unittest.cc b/src/processor/minidump_unittest.cc index 719adf78a..c34ccd4d8 100644 --- a/src/processor/minidump_unittest.cc +++ b/src/processor/minidump_unittest.cc @@ -111,7 +111,7 @@ TEST_F(MinidumpTest, TestMinidumpFromFile) { TEST_F(MinidumpTest, TestMinidumpFromStream) { // read minidump contents into memory, construct a stringstream around them - ifstream file_stream(minidump_file_.c_str(), std::ios::in); + ifstream file_stream(minidump_file_.c_str(), std::ios::in | std::ios::binary); ASSERT_TRUE(file_stream.good()); vector bytes; file_stream.seekg(0, std::ios_base::end); From 446298620b39114612c971fa34ff22f0b1f1efca Mon Sep 17 00:00:00 2001 From: Nathan Moinvaziri Date: Tue, 2 Jan 2024 15:38:55 -0800 Subject: [PATCH 05/91] Disable ContextDeathTest on Windows due to regex support. Windows doesn't have posix regex support. This will disable these tests so long as Google's ABSL library is not also found. Change-Id: Ie6f96d5ea74b80b6128c2f1ec3ed54fcfaa17f47 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5160533 Reviewed-by: Ivan Penkov --- src/processor/synth_minidump_unittest.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/processor/synth_minidump_unittest.cc b/src/processor/synth_minidump_unittest.cc index 3b803afe3..582922719 100644 --- a/src/processor/synth_minidump_unittest.cc +++ b/src/processor/synth_minidump_unittest.cc @@ -147,7 +147,12 @@ TEST(Context, ARM) { == 0); } +#if GTEST_OS_WINDOWS && !GTEST_HAS_ABSL +// GTest on Windows does not support complex regular expressions. +TEST(ContextDeathTest, DISABLED_X86BadFlags) { +#else TEST(ContextDeathTest, X86BadFlags) { +#endif Dump dump(0, kLittleEndian); MDRawContextX86 raw; raw.context_flags = MD_CONTEXT_AMD64; @@ -155,7 +160,12 @@ TEST(ContextDeathTest, X86BadFlags) { "context\\.context_flags & (0x[0-9a-f]+|MD_CONTEXT_X86)"); } +#if GTEST_OS_WINDOWS && !GTEST_HAS_ABSL +// GTest on Windows does not support complex regular expressions. +TEST(ContextDeathTest, DISABLED_X86BadEndianness) { +#else TEST(ContextDeathTest, X86BadEndianness) { +#endif Dump dump(0, kBigEndian); MDRawContextX86 raw; raw.context_flags = MD_CONTEXT_X86; From 048e14caf83f9c7b400361dfd343c697e54e4c59 Mon Sep 17 00:00:00 2001 From: Nathan Moinvaziri Date: Tue, 2 Jan 2024 18:52:22 -0800 Subject: [PATCH 06/91] Add command line switch for reporting DWARF warnings. Change-Id: Ibcf1b0ddb93f1cf6bf12681ed82871328571f2aa Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5137659 Reviewed-by: Ivan Penkov --- src/common/dwarf_cu_to_module.h | 57 +++++++++++++++++++++++ src/common/mac/dump_syms.cc | 18 +++++-- src/common/mac/dump_syms.h | 9 +++- src/tools/mac/dump_syms/dump_syms_tool.cc | 9 +++- 4 files changed, 88 insertions(+), 5 deletions(-) diff --git a/src/common/dwarf_cu_to_module.h b/src/common/dwarf_cu_to_module.h index 1ff0ebc7f..c7ada306c 100644 --- a/src/common/dwarf_cu_to_module.h +++ b/src/common/dwarf_cu_to_module.h @@ -254,6 +254,63 @@ class DwarfCUToModule: public RootDIEHandler { void UncoveredHeading(); }; + class NullWarningReporter: public WarningReporter { + public: + NullWarningReporter(const string &filename, uint64_t cu_offset): + WarningReporter(filename, cu_offset) { } + + // Set the name of the compilation unit we're processing to NAME. + void SetCUName(const string &name) { } + + // Accessor and setter for uncovered_warnings_enabled_. + // UncoveredFunction and UncoveredLine only report a problem if that is + // true. By default, these warnings are disabled, because those + // conditions occur occasionally in healthy code. + void set_uncovered_warnings_enabled(bool value) { } + + // A DW_AT_specification in the DIE at OFFSET refers to a DIE we + // haven't processed yet, or that wasn't marked as a declaration, + // at TARGET. + void UnknownSpecification(uint64_t offset, uint64_t target) { } + + // A DW_AT_abstract_origin in the DIE at OFFSET refers to a DIE we + // haven't processed yet, or that wasn't marked as inline, at TARGET. + void UnknownAbstractOrigin(uint64_t offset, uint64_t target) { } + + // We were unable to find the DWARF section named SECTION_NAME. + void MissingSection(const string §ion_name) { } + + // The CU's DW_AT_stmt_list offset OFFSET is bogus. + void BadLineInfoOffset(uint64_t offset) { } + + // FUNCTION includes code covered by no line number data. + void UncoveredFunction(const Module::Function &function) { } + + // Line number NUMBER in LINE_FILE, of length LENGTH, includes code + // covered by no function. + void UncoveredLine(const Module::Line &line) { } + + // The DW_TAG_subprogram DIE at OFFSET has no name specified directly + // in the DIE, nor via a DW_AT_specification or DW_AT_abstract_origin + // link. + void UnnamedFunction(uint64_t offset) { } + + // __cxa_demangle() failed to demangle INPUT. + void DemangleError(const string &input) { } + + // The DW_FORM_ref_addr at OFFSET to TARGET was not handled because + // FilePrivate did not retain the inter-CU specification data. + void UnhandledInterCUReference(uint64_t offset, uint64_t target) { } + + // The DW_AT_ranges at offset is malformed (truncated or outside of the + // .debug_ranges section's bound). + void MalformedRangeList(uint64_t offset) { } + + // A DW_AT_ranges attribute was encountered but the no .debug_ranges + // section was found. + void MissingRanges() { } + }; + // Create a DWARF debugging info handler for a compilation unit // within FILE_CONTEXT. This uses information received from the // CompilationUnit DWARF parser to populate diff --git a/src/common/mac/dump_syms.cc b/src/common/mac/dump_syms.cc index c06945e48..bcb62413f 100644 --- a/src/common/mac/dump_syms.cc +++ b/src/common/mac/dump_syms.cc @@ -265,6 +265,10 @@ SuperFatArch* DumpSymbols::FindBestMatchForArchitecture( return nullptr; } +void DumpSymbols::SetReportWarnings(bool report_warnings) { + report_warnings_ = report_warnings; +} + string DumpSymbols::Identifier() { scoped_ptr file_id; @@ -524,10 +528,17 @@ void DumpSymbols::ReadDwarf(google_breakpad::Module* module, for (uint64_t offset = 0; offset < debug_info_length;) { // Make a handler for the root DIE that populates MODULE with the // debug info. - DwarfCUToModule::WarningReporter reporter(selected_object_name_, - offset); + DwarfCUToModule::WarningReporter *reporter = nullptr; + if (report_warnings_) { + reporter = new DwarfCUToModule::WarningReporter( + selected_object_name_, offset); + } else { + reporter = new DwarfCUToModule::NullWarningReporter( + selected_object_name_, offset); + } DwarfCUToModule root_handler(&file_context, &line_to_module, - &ranges_handler, &reporter, handle_inline); + &ranges_handler, reporter, + handle_inline); // Make a Dwarf2Handler that drives our DIEHandler. DIEDispatcher die_dispatcher(&root_handler); // Make a DWARF parser for the compilation unit at OFFSET. @@ -543,6 +554,7 @@ void DumpSymbols::ReadDwarf(google_breakpad::Module* module, StartProcessSplitDwarf(&dwarf_reader, module, endianness, handle_inter_cu_refs, handle_inline); } + delete reporter; } } diff --git a/src/common/mac/dump_syms.h b/src/common/mac/dump_syms.h index 5ccf49e3e..2b09e1663 100644 --- a/src/common/mac/dump_syms.h +++ b/src/common/mac/dump_syms.h @@ -71,7 +71,8 @@ class DumpSymbols { selected_object_name_(), enable_multiple_(enable_multiple), module_name_(module_name), - prefer_extern_name_(prefer_extern_name) {} + prefer_extern_name_(prefer_extern_name), + report_warnings_(true) {} ~DumpSymbols() = default; // Prepare to read debugging information from |filename|. |filename| may be @@ -103,6 +104,9 @@ class DumpSymbols { // architecture matches that of this dumper program. bool SetArchitecture(const ArchInfo& info); + // Set whether or not to report DWARF warnings + void SetReportWarnings(bool report_warnings); + // Return a pointer to an array of SuperFatArch structures describing the // object files contained in this dumper's file. Set *|count| to the number // of elements in the array. The returned array is owned by this DumpSymbols @@ -224,6 +228,9 @@ class DumpSymbols { // (which are placed in the Extern), not in the DWARF symbols (which are // placed in the Function). bool prefer_extern_name_; + + // Whether or not to report warnings + bool report_warnings_; }; } // namespace google_breakpad diff --git a/src/tools/mac/dump_syms/dump_syms_tool.cc b/src/tools/mac/dump_syms/dump_syms_tool.cc index 9fb8d13f2..ded4c10e5 100644 --- a/src/tools/mac/dump_syms/dump_syms_tool.cc +++ b/src/tools/mac/dump_syms/dump_syms_tool.cc @@ -77,6 +77,7 @@ struct Options { bool enable_multiple; string module_name; bool prefer_extern_name; + bool report_warnings; }; static bool StackFrameEntryComparator(const Module::StackFrameEntry* a, @@ -169,6 +170,8 @@ static bool Start(const Options& options) { const string& primary_file = split_module ? options.dsymPath : options.srcPath; + dump_symbols.SetReportWarnings(options.report_warnings); + if (!dump_symbols.Read(primary_file)) return false; @@ -250,6 +253,7 @@ static void Usage(int argc, const char *argv[]) { "[-n MODULE] [-x] \n", argv[0]); fprintf(stderr, "\t-i: Output module header information only.\n"); + fprintf(stderr, "\t-w: Output warning information.\n"); fprintf(stderr, "\t-a: Architecture type [default: native, or whatever is\n"); fprintf(stderr, "\t in the file, if it contains only one architecture]\n"); fprintf(stderr, "\t-g: Debug symbol file (dSYM) to dump in addition to the " @@ -275,11 +279,14 @@ static void SetupOptions(int argc, const char *argv[], Options *options) { extern int optind; signed char ch; - while ((ch = getopt(argc, (char* const*)argv, "ia:g:crdm?hn:x")) != -1) { + while ((ch = getopt(argc, (char* const*)argv, "iwa:g:crdm?hn:x")) != -1) { switch (ch) { case 'i': options->header_only = true; break; + case 'w': + options->report_warnings = true; + break; case 'a': { std::optional arch_info = GetArchInfoFromName(optarg); if (!arch_info) { From 225ed9172ea8e84c30ba9afcf6cca257bfb492fe Mon Sep 17 00:00:00 2001 From: Nathan Moinvaziri Date: Tue, 2 Jan 2024 15:38:02 -0800 Subject: [PATCH 07/91] Force dump_syms output to be checked out with LF line-ending. Otherwise, even with core.autocrlf=false, Windows will checkout these minidump output files with CRLF line-ending. It is necessary for these files to be checked out using LF line-ending for the unit tests to pass. Change-Id: I7cacf4b5fa56e007c8aa81202e0cef7ad42ae93a Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5160534 Reviewed-by: Ivan Penkov --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..1f5493729 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +src/processor/testdata/*.out text eol=lf From 7fb7589914705ea260e8f5291121510c19080b3d Mon Sep 17 00:00:00 2001 From: Nathan Moinvaziri Date: Wed, 3 Jan 2024 12:34:03 -0800 Subject: [PATCH 08/91] Allow breakpad to read extended x86 contexts Minidumps can contain extended contexts with xstate data for amd64 and x86. Support for amd64 contexts was added in fe35cd43f2c7386704837b686f91a4e3c882664d. With this change, breakpad can now read x86 minidumps that contain extended xstate data. Similar to the previously mentioned commit, this change does not yet add processing for this extra data, but will allow the minidumps to be read. Change-Id: Ie96e91168def774092e05908535a70fc5e2427e9 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5154022 Reviewed-by: Mike Frysinger --- src/processor/minidump.cc | 22 ++++++++++++++--- src/processor/minidump_processor_unittest.cc | 23 ++++++++++++++++++ .../testdata/tiny-exe-with-cet-xsave-x86.dmp | Bin 0 -> 20828 bytes 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 src/processor/testdata/tiny-exe-with-cet-xsave-x86.dmp diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 83f72b97b..83e5a8688 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -817,9 +817,19 @@ bool MinidumpContext::Read(uint32_t expected_size) { switch (cpu_type) { case MD_CONTEXT_X86: { if (expected_size != sizeof(MDRawContextX86)) { - BPLOG(ERROR) << "MinidumpContext x86 size mismatch, " << - expected_size << " != " << sizeof(MDRawContextX86); - return false; + // Context may include xsave registers and so be larger than + // sizeof(MDRawContextX86). For now we skip this extended data. + if (context_flags & MD_CONTEXT_X86_XSTATE) { + size_t bytes_left = expected_size - sizeof(MDRawContextX86); + if (bytes_left > kMaxXSaveAreaSize) { + BPLOG(ERROR) << "MinidumpContext oversized xstate area"; + return false; + } + } else { + BPLOG(ERROR) << "MinidumpContext x86 size mismatch, " + << expected_size << " != " << sizeof(MDRawContextX86); + return false; + } } scoped_ptr context_x86(new MDRawContextX86()); @@ -885,6 +895,12 @@ bool MinidumpContext::Read(uint32_t expected_size) { SetContextX86(context_x86.release()); + // Skip extended xstate data if present in X86 context. + if (context_flags & MD_CONTEXT_X86_XSTATE) { + minidump_->SeekSet((minidump_->Tell() - sizeof(MDRawContextX86)) + + expected_size); + } + break; } diff --git a/src/processor/minidump_processor_unittest.cc b/src/processor/minidump_processor_unittest.cc index de3cfdd59..c9cf9d2b2 100644 --- a/src/processor/minidump_processor_unittest.cc +++ b/src/processor/minidump_processor_unittest.cc @@ -764,6 +764,29 @@ TEST_F(MinidumpProcessorTest, Test32BitCrashingAddress) { ASSERT_EQ(state.crash_address(), 0x45U); } +TEST_F(MinidumpProcessorTest, TestXStateX86ContextMinidump) { + // This tests if we can passively process a minidump with cet registers in its + // context. Dump is captured from a toy executable and is readable by windbg. + MinidumpProcessor processor(nullptr, nullptr /*&supplier, &resolver*/); + + string minidump_file = GetTestDataPath() + + "tiny-exe-with-cet-xsave-x86.dmp"; + + ProcessState state; + ASSERT_EQ(processor.Process(minidump_file, &state), + google_breakpad::PROCESS_OK); + ASSERT_EQ(state.system_info()->os, "Windows NT"); + ASSERT_EQ(state.system_info()->os_version, "10.0.22631 "); + ASSERT_EQ(state.system_info()->cpu, "x86"); + ASSERT_EQ(state.system_info()->cpu_info, + "GenuineIntel family 6 model 151 stepping 2"); + ASSERT_FALSE(state.crashed()); + ASSERT_EQ(state.threads()->size(), size_t(3)); + + // TODO: verify cetumsr and cetussp once these are supported by + // breakpad. +} + TEST_F(MinidumpProcessorTest, TestXStateAmd64ContextMinidump) { // This tests if we can passively process a minidump with cet registers in its // context. Dump is captured from a toy executable and is readable by windbg. diff --git a/src/processor/testdata/tiny-exe-with-cet-xsave-x86.dmp b/src/processor/testdata/tiny-exe-with-cet-xsave-x86.dmp new file mode 100644 index 0000000000000000000000000000000000000000..f5a08ca863876637b8f225ee6c6fb890d591921e GIT binary patch literal 20828 zcmeHP34D}Amai}5g~*>;X5D zdhgY%>bff<<3}bu`};{tnh7B+@O0Hr|F_M+ngB0_j|vpRA22vrhzf)Q5Ke_Z-9?BX zz*zX-!ncGUi^Sc4t>KSqLhQOhh&Bi>g5Ma5PorI+@cUJm)>O|ob)pb{2wQK&2mJ51 zW#`+oZNszkY?;o$5aGUX!w;ad>GG4DQn5=4?n z5q2>JJ_Q70L>^+YQSKz+#MdImA|*?}SXXegswQ$a8pOBjkD*`xT;^Y?AIB?!>-M-s;$ zA)wFwG%Qd!p?d^-pO`9DUW-xe#8$EuOgs`P;nFZ6!lG2$S&WW*5uCX-9*pf~_P_`Nb*~w-2z#oaZpL)Lo#;}=!mA1JnjOu~rORKk1o zO#T>6l~p|aIwLsJEbCrRnhK@lE7($$w`nHUT`YX$d{P7mS3eTim9wu)}NFOE4qsFry@l8Z4ZSsM*}stjjE=~hJ^LmkYa*Z zINilv(l!n$8)7E+#-iq8Q`eVgSA}i7#H=w7! z)O^&a8^Q_j&(|xfQpqau6VuQ6iJ6OrlxCY``H4Ubt*UJhdSqSNZ?J8gs8`lF{r43p zGL{C45$m0{*S%ylw7z;kR%;qkcV(Bf!}2_tR1qW`KMxk$56tWm+}dM9maCy{o<$mL zl67gDZ>RTB%|%yB3-SD&?|$;2Nfu`=S1Olg6hMdUd#BbbYlV_!2^M4K2aBTW>ZB5r ztoq93EsOQ_RK2n)bER5ELOd~26Q89g|J!yiS&eBME9#Z?t*Wm?A-<^*Vp8WZkG5@7 zx4s%Gs}q#oW|lQnmcsOL>wT0EkF3(fjN+{$Cz@m#W26D=Yx5?imknxIi9Vc+5f`?bH1JCuWfs`H%Qf7b1{-s_v$WbRt5 zmzM{N7W|>Zy))?dnS^(?x|!e-w{6X1Ll}9srh|CvWf8Drix3^tf9E$adVuyvhrf8k zKTYILPs*BH)>NDrm@V@^ZC5j&{+LW|S>_V2AN)`ZyD+!u=X0OYKG|Vuam$gZ`V3Qu zkeCJja}>FF?O;cl|5u&Akg!K77V>a@sO#2a5J)VPxWF2SuB2L_Y7vdBj`6RUKq7>%`f zCdLap($hd`L+WtQO~E?Olcy)*r@;$w5@Lwt$2{DP$Pq5A=&jhFC9J_RBT>t}um{CmhpVq8&u)gnBcTx* zB}@AjqGWm4&2yq`S@L&gM|o{1wMVnYSUm~lDS*`-;8oY^jj4UZ>TJ&*JsQ&nxr>*A zJ|jo|>Ko2uf*6JVhWmq7X$L3r+rcHITn2hLFB0AX-}zGNq1O4jXCM z1({nACq49)ql&k#MHtl7yaGhm-xc}A)e)kXu1?%_LDZ1yVf|6@=7`Gu z&%T{7=s@DkxX&;j`Ek3LZ{6-`{@6VO+{$)=;$oqBO`X4*5EWfhraw()-`VxREZ^79 z*1PM8TAZ#qwxw&WysD=8g@s!8Cp=xxFl?~uU5^)~Lciy(=dwEZBCo#%*yUg?R@?QA zg~)5w_4vA+YhHi<>RnIpSC@7@i8agWbUiQNtj5>%T=S;!gJa09C(YFLjJO6}kFU$Q zZp~oynD{XrFU;$`{DnD#SN>(d%ST)0-^V#>`~Yj7J-g7FoNv!ewT`xBPO#^t#oLmH zXHUtIDLoyj$%45@KM?uh6L-bgkM&;mYV%k7VVhS7S9V@%W@atPfj!TxxT!R3=Z^4_ zzpPk2w5ue^usO4BnZ2WHsg~`XH~id=p{KVWd@QW`^9XL;3YVfvPRg~_(%rM*(B!23 zLk}lC`RvW^4l(^nm!IOyt3z}$(vkZ>)t>E^;^WP?J@xLhBuY)5nr6#%)G}J!YG3aX zzgFkYtzNo3;@k(lNRyJ2Rfo^+FW-1+zRUj67k5~v&OdWXDdluPTud#W7doXs7C5S6 zNRJ&I`nfmnlZV+knYN_-JX7g1UOCq0i7$H(+VJY3m(G0j@>vSY$}LE7Om^9`YgwKD zpyR>A_iz8%;LVA@F1}&#YEq#plB|!IniuIYvM_uo~y{?qQ^N6wypm^1}8XRbZRW49+44t-_DTjL&l`^=N$Yx-}VN*YHl z)RB_7S>GHhbO5=7FcJI0%V(SL2w2(cZi4sS2JgEFLa4KZSZuf7hArRso*6FIo&^85 zzb*-Jxwrjas3=)`3OfKgF4Iq&(wigwj0yJ#{*4I_2G0F#gI`OVZgD|QcF+y+|V%cGhH*`Ebnd;PJVk#IOTtC!oz{@ zHR04}pB7llpZI=LI{E)yYh9a8ywa3TeGX_%YSSt23orajFZzQXT-vM3gUk9mWWuS> zVG~aNM?5%}VdY1fxOTy0t18kpZf_hwn_7B)p;r0GE5}Q!nz-n>l#};ia3_X4M!0Dy z=3p7eIJv_m2tu*Sxa0TKCy|-SZPKejw_)WdA zOdA{BO3MUHqrPyw(__#P|7SaH1~$}j=}cPvR7bEr67}DEDr{eLEXcKUb*JY7Kobu9 z509qiv#ce6dBD4^50v%xYveOzHq;gotXsJ0x}3e`ot`5;8~Dm~fi9lSl`jZUeG}qq z+X#t#&SwFi1$-9xo-Dwd1GmF3xu`~)Cvh#R2)HKFIWPzd{MfdyA7{Ej zE3@hO7X0-|$)^lB_;pP@8mT#uZv=4a%REOB$3Fewo1LCRQQW1#_xP(m);}P`rB40R zHR|N(n4zt-WN5444@p7k+E(b}hB5kn?eC%<4@?P{{XS136OTt~+re)d{D`z5*Dlaf z*2*nPRuS;`2FBK&616=RsZ{_kLp<3ZJvmIKk&n>hq*#1Pfk!%&o}|0wkr0>p{@J&G)Xv_pU^>iXZ>i_pZcK$HC!!wBXi8zvGGbg|6NLd{=VzRHSyL`&$p;-o;ql zCK@Sk+gNe?rtUkZc-$+K`^x(G!udrF_)()+_~6r#TG@uMEgVZM{sZ$F<~$$~@fpa& zF>EQqq_qMX`HB!8ms@Ey(qz0ohWr*t6~>mu&v?>}@#R&-U1@yW2cFZB&%EZYIxu~M zd3-e9FH#=q%8}=2dXQ^+(13id54jhW*fK`rJDXte;y4%sn02hu>YW~?r&Bl5l>mPy z&qGHU2Cu5HXpQZgadhNQ&$m3oM2s9ejeRf!8tF}j7e2(X_U0LtR??c&6*u)|-Ef>e z4Oxc0NYA`#OvVmKNQ`zf2ubG;e`1B=Ne*Rg4`3{}$TX%$osHC*toNiVDMDl-jW(^& z=Ln8)F)4J)5o==bQES{}w>9o}N5Dsa3!-OQ3tGMvWggm5sM{1`pF3J3Kl&2LqaDec z*{C~dna_wPAM)r9dg|)!Mj&=gXLbLd_AurbLPTqP+bU-tlDm52^a5gfILK?GDBqif^*`K5RT1IU(uktUpumN?(IN z(;4P%UA`+`1YEueHbK(R{ZD-1L%UITT{cx(z3Yi}s;JbL{XtYutT(V%)(26nPv&8& zQSYpC)-my5^eZZ-`Wp5owidh>E%kG4TGX;94or+_0gJcf?3*+#hT#2hM{>N_t*%=Ezl zG!bIj3&BwfVt55bT|)sT13E2JWrT@YtpwhWk$WCRM%2?r0FcXI(exfE6Wd!77WX`8 z=R0xH1ouL8mhb6#iWYKb;mWR}!~56?@wf#;yS+m!*k6r)OJ2TrIq{~y=q!If24oyu zk^BN`xbEcbT6;%a0l%CTlHb~Sp8E%?jI+efj5oSmybHhAk~iP{oAXl*TSd|tFb-wM zpL9#`rKfS?Sd7aFV0t~S2pe1a7Fs=2zNCLS3*dhfm|X=L#S%ua4P2oe6d}o|YYY#f aExh6QPos=9Bkl(Yy$V6Q&_yY5$@d=~+bCK9 literal 0 HcmV?d00001 From 83d9816eb455e6b59c085688ce443098086c2a1b Mon Sep 17 00:00:00 2001 From: Nathan Moinvaziri Date: Tue, 2 Jan 2024 18:48:55 -0800 Subject: [PATCH 09/91] Fixed compilation if mach-o/utils.h is unavailable. Change-Id: Id22814308542503754600c2fa41e76bd6d1492c0 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5143028 Reviewed-by: Ivan Penkov --- src/common/mac/arch_utilities.cc | 37 ++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/common/mac/arch_utilities.cc b/src/common/mac/arch_utilities.cc index af6c36356..0afa6c460 100644 --- a/src/common/mac/arch_utilities.cc +++ b/src/common/mac/arch_utilities.cc @@ -37,9 +37,21 @@ #include #include #include +#include +#include #ifdef __APPLE__ +#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && defined(__IPHONE_16_0) && \ + __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_16_0) || \ + (defined(MAC_OS_X_VERSION_MIN_REQUIRED) && defined(MAC_OS_VERSION_13_0) && \ + MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_13_0) || \ + (defined(__TV_OS_VERSION_MIN_REQUIRED) && defined(__TV_OS_VERSION_16_0) && \ + __TV_OS_VERSION_MIN_REQUIRED >= __TVOS_16_0) +#define HAS_MACHO_UTILS 1 #include +#else +#define HAS_MACHO_UTILS 0 +#endif #endif namespace { @@ -95,40 +107,43 @@ ArchInfo GetLocalArchInfo(void) { #ifdef __APPLE__ std::optional GetArchInfoFromName(const char* arch_name) { +#if HAS_MACHO_UTILS if (__builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, *)) { cpu_type_t type; cpu_subtype_t subtype; if (macho_cpu_type_for_arch_name(arch_name, &type, &subtype)) { return ArchInfo{type, subtype}; } - } else { + return std::nullopt; + } +#endif #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - const NXArchInfo* info = NXGetArchInfoFromName(arch_name); + const NXArchInfo* info = NXGetArchInfoFromName(arch_name); #pragma clang diagnostic pop - if (info) { - return ArchInfo{info->cputype, info->cpusubtype}; - } + if (info) { + return ArchInfo{info->cputype, info->cpusubtype}; } return std::nullopt; } const char* GetNameFromCPUType(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) { +#if HAS_MACHO_UTILS if (__builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, *)) { const char* name = macho_arch_name_for_cpu_type(cpu_type, cpu_subtype); if (name) { return name; } - } else { + return kUnknownArchName; + } +#endif #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - const NXArchInfo* info = NXGetArchInfoFromCpuType(cpu_type, cpu_subtype); + const NXArchInfo* info = NXGetArchInfoFromCpuType(cpu_type, cpu_subtype); #pragma clang diagnostic pop - if (info) { - return info->name; - } + if (info) { + return info->name; } - return kUnknownArchName; } From 062f7124f60493a3a81ec38ac46441e4b7e08de5 Mon Sep 17 00:00:00 2001 From: Nathan Moinvaziri Date: Thu, 4 Jan 2024 15:02:11 -0800 Subject: [PATCH 10/91] Fixed arch_utilities.cc compilation for Linux. Availability.h and AvailabilityMacros.h are only available when compiling on Apple. Change-Id: I820c74a7fa15560c358366418a503b911dde3d86 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5171145 Reviewed-by: Ivan Penkov --- src/common/mac/arch_utilities.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/mac/arch_utilities.cc b/src/common/mac/arch_utilities.cc index 0afa6c460..cfa2e2d70 100644 --- a/src/common/mac/arch_utilities.cc +++ b/src/common/mac/arch_utilities.cc @@ -37,10 +37,11 @@ #include #include #include + +#ifdef __APPLE__ #include #include -#ifdef __APPLE__ #if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && defined(__IPHONE_16_0) && \ __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_16_0) || \ (defined(MAC_OS_X_VERSION_MIN_REQUIRED) && defined(MAC_OS_VERSION_13_0) && \ From 22f54f197fe5be28abda6e00bdfaaed9e87f9851 Mon Sep 17 00:00:00 2001 From: Zequan Wu Date: Fri, 5 Jan 2024 12:29:29 -0500 Subject: [PATCH 11/91] [dump_syms] Handle DW_TAG_lexical_block to caputre inline info inside. Bug: b/317143556 Change-Id: Iba82712fedf7d126c2392cfc0f157ded2bca5219 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5171059 Reviewed-by: Ivan Penkov --- src/common/dwarf_cu_to_module.cc | 52 ++++++++++++++++++++++++++++++++ src/common/dwarf_cu_to_module.h | 1 + 2 files changed, 53 insertions(+) diff --git a/src/common/dwarf_cu_to_module.cc b/src/common/dwarf_cu_to_module.cc index 94a0d428e..613f97854 100644 --- a/src/common/dwarf_cu_to_module.cc +++ b/src/common/dwarf_cu_to_module.cc @@ -562,6 +562,29 @@ static bool IsEmptyRange(const vector& ranges) { return size == 0; } +// A handler for DW_TAG_lexical_block DIEs. +class DwarfCUToModule::LexicalBlockHandler : public GenericDIEHandler { + public: + LexicalBlockHandler(CUContext* cu_context, + uint64_t offset, + int inline_nest_level, + vector>& inlines) + : GenericDIEHandler(cu_context, nullptr, offset), + inline_nest_level_(inline_nest_level), + inlines_(inlines) {} + + DIEHandler* FindChildHandler(uint64_t offset, enum DwarfTag tag); + bool EndAttributes() { return true; } + void Finish(); + + private: + int inline_nest_level_; + // A vector of inlines in the same nest level. It's owned by its parent + // function/inline. At Finish(), add this inline into the vector. + vector>& inlines_; + // A vector of child inlines. + vector> child_inlines_; +}; // A handler for DW_TAG_inlined_subroutine DIEs. class DwarfCUToModule::InlineHandler : public GenericDIEHandler { @@ -645,6 +668,9 @@ DIEHandler* DwarfCUToModule::InlineHandler::FindChildHandler( case DW_TAG_inlined_subroutine: return new InlineHandler(cu_context_, nullptr, offset, inline_nest_level_ + 1, child_inlines_); + case DW_TAG_lexical_block: + return new LexicalBlockHandler(cu_context_, offset, + inline_nest_level_ + 1, child_inlines_); default: return NULL; } @@ -715,6 +741,29 @@ void DwarfCUToModule::InlineHandler::Finish() { inlines_.push_back(std::move(in)); } +DIEHandler* DwarfCUToModule::LexicalBlockHandler::FindChildHandler( + uint64_t offset, + enum DwarfTag tag) { + switch (tag) { + case DW_TAG_inlined_subroutine: + return new InlineHandler(cu_context_, nullptr, offset, inline_nest_level_, + child_inlines_); + case DW_TAG_lexical_block: + return new LexicalBlockHandler(cu_context_, offset, inline_nest_level_, + child_inlines_); + default: + return nullptr; + } +} + +void DwarfCUToModule::LexicalBlockHandler::Finish() { + // Insert child inlines inside the lexical block into the inline vector from + // parent as if the block does not exit. + inlines_.insert(inlines_.end(), + std::make_move_iterator(child_inlines_.begin()), + std::make_move_iterator(child_inlines_.end())); +} + // A handler for DIEs that contain functions and contribute a // component to their names: namespaces, classes, etc. class DwarfCUToModule::NamedScopeHandler: public GenericDIEHandler { @@ -831,6 +880,9 @@ DIEHandler* DwarfCUToModule::FuncHandler::FindChildHandler( case DW_TAG_union_type: return new NamedScopeHandler(cu_context_, &child_context_, offset, handle_inline_); + case DW_TAG_lexical_block: + if (handle_inline_) + return new LexicalBlockHandler(cu_context_, offset, 0, child_inlines_); default: return NULL; } diff --git a/src/common/dwarf_cu_to_module.h b/src/common/dwarf_cu_to_module.h index c7ada306c..d83108437 100644 --- a/src/common/dwarf_cu_to_module.h +++ b/src/common/dwarf_cu_to_module.h @@ -357,6 +357,7 @@ class DwarfCUToModule: public RootDIEHandler { struct Specification; class GenericDIEHandler; class FuncHandler; + class LexicalBlockHandler; class InlineHandler; class NamedScopeHandler; From 62ecd463583d09eb7d15b1d410055f30b2c7bcb4 Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Thu, 11 Jan 2024 11:05:43 -0500 Subject: [PATCH 12/91] Mac: teach upload_system_symbols to extract installers and IPSWs This change introduces two new flags: `--ipsw` and `--installer` which are mutually exclusive with `--system-root` and each other. Each takes a file path as an argument, which is expected to be an IPSW for `--ipsw` and an Apple installer for `--installer`. Calling `upload_system_symbols` with these arguments will cause it to find any dyld shared caches present inside the given IPSW or installer, extract them via `dsc_extractor` in `--breakpad-tools`, then behave as if it had been called with the resulting libraries as `--system-root`. Bug: chromium:1400770 Change-Id: I7f98e0c6ab069a2e960f12773d800d8a5a37221f Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5089008 Reviewed-by: Robert Sesek --- .../mac/upload_system_symbols/extract.go | 514 ++++++++++++++++++ .../upload_system_symbols.go | 134 ++++- 2 files changed, 621 insertions(+), 27 deletions(-) create mode 100644 src/tools/mac/upload_system_symbols/extract.go diff --git a/src/tools/mac/upload_system_symbols/extract.go b/src/tools/mac/upload_system_symbols/extract.go new file mode 100644 index 000000000..acd674ef3 --- /dev/null +++ b/src/tools/mac/upload_system_symbols/extract.go @@ -0,0 +1,514 @@ +package main + +// #cgo LDFLAGS: -lParallelCompression +// #include +// #include +// #include +// +// typedef struct +// { +// int64_t unknown1; +// int64_t unknown2; +// char *input; +// char *output; +// char *patch; +// uint32_t not_cryptex_cache; +// uint32_t threads; +// uint32_t verbose; +// } RawImage; +// +// extern int32_t RawImagePatch(RawImage *); +import "C" + +import ( + "archive/zip" + "bytes" + "errors" + "fmt" + "io" + "log" + "os" + "os/exec" + "path" + "path/filepath" + "strconv" + "strings" + "unsafe" +) + +type ArchiveFormat int + +const ( + IPSW ArchiveFormat = iota + Installer +) + +// ExtractCaches extracts any dyld shared caches from `archive` to `destination`. +func ExtractCaches(format ArchiveFormat, archive string, destination string, verbose bool) error { + opts := ExtractorOptions{Verbose: true, Source: archive, Destination: destination} + var e *Extractor + switch format { + case IPSW: + e = NewIPSWExtractor(opts) + case Installer: + e = NewInstallAssistantExtractor(opts) + default: + return fmt.Errorf("unknown format %v", format) + } + return e.Extract() +} + +// NewIPSWExtractor returns an `Extractor` that can handle `.ipsw` files. +func NewIPSWExtractor(opts ExtractorOptions) *Extractor { + ie := &ipswExtractor{} + ie.Extractor = &Extractor{opts: opts, impl: ie} + return ie.Extractor +} + +// NewInstallAssistantExtractor returns an extractor that can handle Apple installers. +func NewInstallAssistantExtractor(opts ExtractorOptions) *Extractor { + ie := &installAssistantExtractor{} + ie.Extractor = &Extractor{opts: opts, impl: ie} + return ie.Extractor +} + +// ExtractorOptions are provided to an extractor to specify source file, destination, +// and whether verbose logging should be used. +type ExtractorOptions struct { + Verbose bool + Source string + Destination string +} + +// Extractor encapsulates the process of extracting dyld shared caches from an IPSW or installer. +type Extractor struct { + opts ExtractorOptions + impl extractorImpl + + scratchDir string + + // If non-empty, the path at which the DMG was mounted. This will + // be un-mounted at the end of Extract(). + dmgMountPaths []string +} + +// Extract extracts any dyld shared caches in `opts.Source` to `opts.Destination`. +func (e *Extractor) Extract() error { + scratchDir, err := os.MkdirTemp("", "extracted_system") + if err != nil { + return fmt.Errorf("couldn't create scratch directory to extract: %v", err) + } + defer os.RemoveAll(scratchDir) + e.scratchDir = scratchDir + + err = e.impl.doExtract() + + for _, path := range e.dmgMountPaths { + unmountErr := unmountDMG(path) + if unmountErr != nil { + err = errors.Join(err, unmountErr) + } + } + + return err +} + +// vlog logs if `opts.Verbose` is set and is a no-op otherwise. +func (e *Extractor) vlog(format string, args ...interface{}) { + if e.opts.Verbose { + fmt.Printf(format+"\n", args...) + } +} + +// mountDMG mounts the disk image at `dmgPath` to mountpoint and tracks it so that +// it can be unmounted by the end of `Extract` +func (e *Extractor) mountDMG(dmgPath string, mountpoint string) error { + cmd := exec.Command("hdiutil", "attach", dmgPath, "-mountpoint", mountpoint, "-quiet", "-nobrowse", "-readonly") + err := cmd.Run() + if err != nil { + e.dmgMountPaths = append(e.dmgMountPaths, mountpoint) + } + return err +} + +// extractorImpl is a private interface implemented by the backend +// extractors. +type extractorImpl interface { + doExtract() error +} + +// ipswExtractor extracts IPSWs +type ipswExtractor struct { + *Extractor +} + +// doExtract extracts dyld shared caches from an IPSW. +// It: +// Extracts the system disk image from the IPSW and mounts it. +// Copies any dyld shared caches from /System/Library/dyld on the mounted +// image to `opts.Destination`. +func (e *ipswExtractor) doExtract() error { + e.vlog("Extracting and mounting system disk:\n") + system, err := e.mountSystemDMG(e.opts.Source) + if err != nil { + return fmt.Errorf("couldn't mount system DMG: %v", err) + } + e.vlog("System mounted at %v\n", system) + e.vlog("Extracting shared caches:\n") + cachesPath := path.Join(system, "System/Library/dyld") + if !pathExists(cachesPath) { + return errors.New("couldn't find /System/Library/dyld") + } + + caches, err := filepath.Glob(path.Join(cachesPath, "dyld_shared_cache*")) + if err != nil { + // "The only possible returned error is ErrBadPattern" so treat + // this like a programmer error. + log.Fatalf("Failed to glob %v", path.Join(cachesPath, "dyld_shared_cache*")) + } + + for _, cache := range caches { + src, err := os.Open(cache) + if err != nil { + return err + } + defer src.Close() + filename := path.Base(cache) + dst, err := os.Create(path.Join(e.opts.Destination, filename)) + if err != nil { + return err + } + defer dst.Close() + e.vlog("Extracted %v\n", filename) + if _, err := io.Copy(dst, src); err != nil { + return err + } + } + + return nil +} + +// mountSystemDMG finds the name of the system image disk in the build manifest inside the +// IPSW at `ipswPath`, mounts it inside `e.scratchDir` and returns the mountpoint. +func (e *ipswExtractor) mountSystemDMG(ipswPath string) (string, error) { + r, err := zip.OpenReader(ipswPath) + if err != nil { + return "", fmt.Errorf("couldn't open ipsw at %s: %v", ipswPath, err) + } + defer r.Close() + dmgPath := "" + for _, f := range r.File { + if f.Name == "BuildManifest.plist" { + manifest, err := os.Create(path.Join(e.scratchDir, f.Name)) + if err != nil { + return "", err + } + if err := extractFileToPath(f, path.Join(e.scratchDir, f.Name)); err != nil { + return "", err + } + path, err := e.getSystemDMGPath(manifest.Name()) + if err != nil { + return "", err + } + dmgPath = path + } + } + if dmgPath == "" { + return "", errors.New("couldn't find build manifest") + } + for _, f := range r.File { + if filepath.Base(f.Name) == dmgPath { + dmgPath := path.Join(e.scratchDir, f.Name) + if err := extractFileToPath(f, dmgPath); err != nil { + return "", err + } + dmgMountpoint := path.Join(e.scratchDir, "Root") + e.vlog("Mounting %v at %v\n", dmgPath, dmgMountpoint) + if err := e.mountDMG(dmgPath, dmgMountpoint); err != nil { + return "", err + } + return dmgMountpoint, nil + } + } + return "", fmt.Errorf("%v not present in %v", dmgPath, ipswPath) +} + +// getSystemDMGPath finds the system disk image inside a IPSW from the build manifest +// at `manifest`. +func (e *ipswExtractor) getSystemDMGPath(manifest string) (string, error) { + print_cmd := "print :BuildIdentities:1:Manifest:Cryptex1,SystemOS:Info:Path" + result, err := exec.Command("PlistBuddy", "-c", print_cmd, manifest).Output() + if err != nil { + return "", err + } + return strings.TrimSpace(string(result)), nil +} + +// installAssistantExtractor extracts Apple installers. +type installAssistantExtractor struct { + *Extractor +} + +// doExtract extracts dyld shared caches from an Apple installer. +// It: +// 1. Expands the installer to disk +// 2. Finds and mounts SharedSupport.dmg +// 3. Determines based on system version whether this installer contains cryptexes or not. +// 4. If cryptexes are present, extracts them to disk images, mounts them, then copies any shared caches +// to `opts.Destination`. Otherwise, finds any payload zips containing shared caches, extracts them, and +// copies the caches to `opts.Destination` +func (e *installAssistantExtractor) doExtract() error { + expandedPath := path.Join(e.scratchDir, "installer") + e.vlog("Expanding installer to %v\n", expandedPath) + if err := e.expandInstaller(e.opts.Source, expandedPath); err != nil { + return fmt.Errorf("expand installer: %v", err) + } + + dmgPath := path.Join(expandedPath, "SharedSupport.dmg") + if !pathExists(dmgPath) { + return fmt.Errorf("couldn't find SharedSupport.dmg at %v", dmgPath) + } + dmgMountpoint := path.Join(e.scratchDir, "shared_support") + e.vlog("Mounting %v at %v\n", dmgPath, dmgMountpoint) + if err := e.mountDMG(dmgPath, dmgMountpoint); err != nil { + return fmt.Errorf("mount %v: %v", dmgPath, err) + } + + zipsPath := path.Join(dmgMountpoint, "com_apple_MobileAsset_MacSoftwareUpdate") + if !pathExists(zipsPath) { + return fmt.Errorf("couldn't find com_apple_MobileAsset_MacSoftwareUpdate on SharedSupport.dmg") + } + hasCryptexes, err := e.hasCryptexes(path.Join(zipsPath, "com_apple_MobileAsset_MacSoftwareUpdate.xml")) + if err != nil { + return fmt.Errorf("couldn't determine system version: %v", err) + } + zips, err := filepath.Glob(path.Join(zipsPath, "*.zip")) + if err != nil { + // "The only possible returned error is ErrBadPattern" so treat + // this like a programmer error. + log.Fatalf("Failed to glob %v", path.Join(zipsPath, "*.zip")) + } + return e.extractCachesFromZips(zips, e.opts.Destination, hasCryptexes) +} + +// expandInstaller expands the installer at `installerPath` to `destinaton`. +func (e *installAssistantExtractor) expandInstaller(installerPath string, destination string) error { + return exec.Command("pkgutil", "--expand-full", installerPath, destination).Run() +} + +// hasCryptexes returns true if the installer containing the plist at `plistPath` is for +// macOS version 13 or higher, and accordingly stores dyld shared caches inside cryptexes. +func (e *installAssistantExtractor) hasCryptexes(plistPath string) (bool, error) { + print_cmd := "print :Assets:1:OSVersion" + result, err := exec.Command("PlistBuddy", "-c", print_cmd, plistPath).Output() + if err != nil { + return false, fmt.Errorf("couldn't read OS version from %s: %v", plistPath, err) + } + majorVersion := strings.Split(string(result), ".")[0] + if v, err := strconv.Atoi(majorVersion); err != nil { + return false, fmt.Errorf("couldn't parse major version %s:%v", majorVersion, err) + } else { + return v >= 13, nil + } +} + +// extractCachesFromZips extracts zips that contain dyld shared caches, and extracts the dyld shared caches from them. +// The specifics depend on whether this installer uses cryptexes or payload files. +func (e *installAssistantExtractor) extractCachesFromZips(zips []string, destination string, hasCryptexes bool) error { + containerPath := path.Join(e.scratchDir, "container") + if !hasCryptexes { + if err := e.unarchiveZipsMatching(zips, containerPath, "AssetData/payloadv2/payload.0??"); err != nil { + return err + } + if err := e.extractCachesFromPayloads(containerPath, destination); err != nil { + return fmt.Errorf("couldn't extract caches from %v: %v", containerPath, err) + } + } else { + if err := e.unarchiveZipsMatching(zips, containerPath, "AssetData/payloadv2/image_patches/cryptex-system-*"); err != nil { + return err + } + if err := e.extractCachesFromCryptexes(containerPath, destination); err != nil { + return fmt.Errorf("couldn't extract caches from %v: %v", containerPath, err) + } + } + return nil +} + +// unarchiveZipsMatching unarchives all files matching `glob` from the zip files in `zips` to destination. +func (e *installAssistantExtractor) unarchiveZipsMatching(zips []string, destination string, glob string) error { + for _, zipFile := range zips { + archive, err := zip.OpenReader(zipFile) + if err != nil { + return fmt.Errorf("couldn't read %v: %v", zipFile, err) + } + defer archive.Close() + e.vlog("Unarchiving %v\n", zipFile) + if err := e.unarchiveFilesMatching(archive, destination, glob); err != nil { + return fmt.Errorf("couldn't unarchive files matching %v from %v", glob, zipFile) + } + } + return nil +} + +// unarchiveFilesMatching unarchives all files matching `glob` from `r` to destination. +func (e *installAssistantExtractor) unarchiveFilesMatching(r *zip.ReadCloser, destination string, glob string) error { + if err := os.MkdirAll(destination, 0755); err != nil { + return err + } + for _, file := range r.File { + if file.FileInfo().IsDir() { + continue + } + if ok, err := path.Match(glob, file.Name); !ok || err != nil { + continue + } + _, filename := path.Split(file.Name) + writePath := path.Join(destination, filename) + if err := extractFileToPath(file, writePath); err != nil { + return err + } + } + return nil +} + +// extractCachesFromPayloads unarchives any files containing dyld shared caches from `payloadsPath` +// then copies any shared caches to `destination`. +func (e *installAssistantExtractor) extractCachesFromPayloads(payloadsPath string, destination string) error { + scratchDir, err := os.MkdirTemp(e.scratchDir, "payload") + if err != nil { + return err + } + files, err := os.ReadDir(payloadsPath) + if err != nil { + return err + } + for _, f := range files { + payload := path.Join(payloadsPath, f.Name()) + if e.payloadHasSharedCache(payload) { + e.vlog("Extracting %v\n", payload) + e.extractPayload(payload, scratchDir) + } + } + return e.copySharedCaches(scratchDir, destination) +} + +// payloadHasSharedCache returns true if the archive at `payloadPath` contains a dyld shared cache. +func (e *installAssistantExtractor) payloadHasSharedCache(payloadPath string) bool { + out, err := exec.Command("yaa", "list", "-i", payloadPath).Output() + return err == nil && bytes.Contains(out, []byte("/dyld_shared_cache")) +} + +// extractPayload extracts the apple archive at `payloadPath` to `destination`. +func (e *installAssistantExtractor) extractPayload(payloadPath string, destination string) error { + return exec.Command("yaa", "extract", "-i", payloadPath, "-d", destination).Run() +} + +// copySharedCaches copies the contents of `System/Library/dyld` in `from` to `to`. +func (e *installAssistantExtractor) copySharedCaches(from, to string) error { + dyldPath := path.Join(from, "System/Library/dyld") + if !pathExists(dyldPath) { + return fmt.Errorf("couldn't find System/Library/dyld in %s", dyldPath) + } + cacheFiles, err := os.ReadDir(dyldPath) + if err != nil { + return err + } + for _, cacheFile := range cacheFiles { + name := cacheFile.Name() + src := path.Join(dyldPath, name) + dst := path.Join(to, name) + e.vlog("Copying %v to %v\n", src, dst) + if err := copyFile(src, dst); err != nil { + return fmt.Errorf("couldn't copy %s to %s: %v", src, dst, err) + } + } + return nil +} + +// extractCachesFromCryptexes extracts disk images from any cryptexes at `cryptexesPath`, mounts them, +// and extracts any dyld shared caches to `destination`. +func (e *installAssistantExtractor) extractCachesFromCryptexes(cryptexesPath string, destination string) error { + scratchDir, err := os.MkdirTemp(e.scratchDir, "cryptex_dmg") + if err != nil { + return err + } + files, err := os.ReadDir(cryptexesPath) + if err != nil { + return err + } + for _, f := range files { + cryptexMountpoint := path.Join(scratchDir, "cryptex_"+f.Name()) + cryptex := path.Join(cryptexesPath, f.Name()) + dmgPath := path.Join(scratchDir, f.Name()+".dmg") + e.extractCryptexDMG(cryptex, dmgPath) + e.vlog("Mounting %s at %s\n", cryptex, dmgPath) + e.mountDMG(dmgPath, cryptexMountpoint) + if err := e.copySharedCaches(cryptexMountpoint, destination); err != nil { + return err + } + } + return nil +} + +// extractCryptexDMG extracts the cryptex at `cryptexPath` to `dmgPath` using libParallelCompression. +func (e *installAssistantExtractor) extractCryptexDMG(cryptexPath, dmgPath string) error { + inp := C.CString("") + defer C.free(unsafe.Pointer(inp)) + cryptex := C.CString(cryptexPath) + defer C.free(unsafe.Pointer(cryptex)) + result := C.CString(dmgPath) + defer C.free(unsafe.Pointer(result)) + + ri := C.RawImage{unknown1: 0, unknown2: 0, input: inp, output: result, patch: cryptex, not_cryptex_cache: 0, threads: 0, verbose: 1} + if exitCode := C.RawImagePatch(&ri); exitCode != 0 { + return fmt.Errorf("RawImagePatch failed with %d", exitCode) + } + return nil +} + +// pathExists returns true if `path` exists. +func pathExists(path string) bool { + _, err := os.Stat(path) + return !os.IsNotExist(err) +} + +// extractFileToPath extracts the contents of `f` to `path`. +func extractFileToPath(f *zip.File, path string) error { + w, err := os.Create(path) + if err != nil { + return err + } + defer w.Close() + reader, err := f.Open() + if err != nil { + return err + } + + if _, err := io.Copy(w, reader); err != nil { + return err + } + return nil +} + +// copyFile copies `src` to `dst`, which can be on different volumes. +func copyFile(src, dst string) error { + w, err := os.Create(dst) + if err != nil { + return err + } + defer w.Close() + + reader, err := os.Open(src) + if err != nil { + return err + } + if _, err := io.Copy(w, reader); err != nil { + return err + } + return nil +} + +// unmountDMG unmounts the disk image at `mountpoint`. +func unmountDMG(mountpoint string) error { + return exec.Command("hdiutil", "detach", mountpoint).Run() +} diff --git a/src/tools/mac/upload_system_symbols/upload_system_symbols.go b/src/tools/mac/upload_system_symbols/upload_system_symbols.go index f34c288ae..b7b3cb556 100644 --- a/src/tools/mac/upload_system_symbols/upload_system_symbols.go +++ b/src/tools/mac/upload_system_symbols/upload_system_symbols.go @@ -46,11 +46,11 @@ import ( "flag" "fmt" "io" - "io/ioutil" "log" "os" "os/exec" "path" + "path/filepath" "regexp" "strings" "sync" @@ -61,9 +61,11 @@ var ( breakpadTools = flag.String("breakpad-tools", "out/Release/", "Path to the Breakpad tools directory, containing dump_syms and symupload.") uploadOnlyPath = flag.String("upload-from", "", "Upload a directory of symbol files that has been dumped independently.") dumpOnlyPath = flag.String("dump-to", "", "Dump the symbols to the specified directory, but do not upload them.") - systemRoot = flag.String("system-root", "", "Path to the root of the Mac OS X system whose symbols will be dumped.") + systemRoot = flag.String("system-root", "", "Path to the root of the macOS system whose symbols will be dumped. Mutually exclusive with --installer and --ipsw.") dumpArchitecture = flag.String("arch", "", "The CPU architecture for which symbols should be dumped. If not specified, dumps all architectures.") apiKey = flag.String("api-key", "", "API key to use. If this is present, the `sym-upload-v2` protocol is used.\nSee https://chromium.googlesource.com/breakpad/breakpad/+/HEAD/docs/sym_upload_v2_protocol.md or\n`symupload`'s help for more information.") + installer = flag.String("installer", "", "Path to macOS installer. Mutually exclusive with --system-root and --ipsw.") + ipsw = flag.String("ipsw", "", "Path to macOS IPSW. Mutually exclusive with --system-root and --installer.") ) var ( @@ -129,26 +131,13 @@ func main() { return } - if *systemRoot == "" { - log.Fatal("Need a -system-root to dump symbols for") - } - - if *dumpOnlyPath != "" { - // -dump-to specified, so make sure that the path is a directory. - if fi, err := os.Stat(*dumpOnlyPath); err != nil { - log.Fatalf("-dump-to location: %v", err) - } else if !fi.IsDir() { - log.Fatal("-dump-to location is not a directory") - } - } - dumpPath := *dumpOnlyPath if *dumpOnlyPath == "" { // If -dump-to was not specified, then run the upload pipeline and create // a temporary dump output directory. uq = StartUploadQueue() - if p, err := ioutil.TempDir("", "upload_system_symbols"); err != nil { + if p, err := os.MkdirTemp("", "upload_system_symbols"); err != nil { log.Fatalf("Failed to create temporary directory: %v", err) } else { dumpPath = p @@ -156,13 +145,61 @@ func main() { } } - dq := StartDumpQueue(*systemRoot, dumpPath, uq) + tempDir, err := os.MkdirTemp("", "systemRoots") + if err != nil { + log.Fatalf("Failed to create temporary directory: %v", err) + } + defer os.RemoveAll(tempDir) + roots := getSystemRoots(tempDir) + + if *dumpOnlyPath != "" { + // -dump-to specified, so make sure that the path is a directory. + if fi, err := os.Stat(*dumpOnlyPath); err != nil { + log.Fatalf("-dump-to location: %v", err) + } else if !fi.IsDir() { + log.Fatal("-dump-to location is not a directory") + } + } + + dq := StartDumpQueue(roots, dumpPath, uq) dq.Wait() if uq != nil { uq.Wait() } } +// getSystemRoots returns which system roots should be dumped from the parsed +// flags, extracting them if necessary. +func getSystemRoots(tempDir string) []string { + hasInstaller := len(*installer) > 0 + hasIPSW := len(*ipsw) > 0 + hasRoot := len(*systemRoot) > 0 + + if hasInstaller { + if hasIPSW || hasRoot { + log.Fatalf("--installer, --ipsw, and --system-root are mutually exclusive") + } + if rs, err := extractSystems(Installer, *installer, tempDir); err != nil { + log.Fatalf("Couldn't extract installer at %s: %v", *installer, err) + } else { + return rs + } + } else if hasIPSW { + if hasRoot { + log.Fatalf("--installer, --ipsw, and --system-root are mutually exclusive") + } + if rs, err := extractSystems(IPSW, *ipsw, tempDir); err != nil { + log.Fatalf("Couldn't extract IPSW at %s: %v", *ipsw, err) + } else { + return rs + } + } else if hasRoot { + return []string{*systemRoot} + } + log.Fatal("Need a --system-root, --installer, or --ipsw to dump symbols for") + return []string{} +} + // manglePath reduces an absolute filesystem path to a string suitable as the // base for a file name which encodes some of the original path. The result // concatenates the leading initial from each path component except the last to @@ -282,7 +319,7 @@ type dumpRequest struct { // StartDumpQueue creates a new worker pool to find all the Mach-O libraries in // root and dump their symbols to dumpPath. If an UploadQueue is passed, the // path to the symbol file will be enqueued there, too. -func StartDumpQueue(root, dumpPath string, uq *UploadQueue) *DumpQueue { +func StartDumpQueue(roots []string, dumpPath string, uq *UploadQueue) *DumpQueue { dq := &DumpQueue{ dumpPath: dumpPath, queue: make(chan dumpRequest), @@ -290,7 +327,7 @@ func StartDumpQueue(root, dumpPath string, uq *UploadQueue) *DumpQueue { } dq.WorkerPool = StartWorkerPool(12, dq.worker) - findLibsInRoot(root, dq) + findLibsInRoots(roots, dq) return dq } @@ -369,21 +406,22 @@ type findQueue struct { dq *DumpQueue } -// findLibsInRoot looks in all the pathsToScan in the root and manages the +// findLibsInRoot looks in all the pathsToScan in all roots and manages the // interaction between findQueue and DumpQueue. -func findLibsInRoot(root string, dq *DumpQueue) { +func findLibsInRoots(roots []string, dq *DumpQueue) { fq := &findQueue{ queue: make(chan string, 10), dq: dq, } fq.WorkerPool = StartWorkerPool(12, fq.worker) + for _, root := range roots { + for _, p := range pathsToScan { + fq.findLibsInPath(path.Join(root, p), true) + } - for _, p := range pathsToScan { - fq.findLibsInPath(path.Join(root, p), true) - } - - for _, p := range optionalPathsToScan { - fq.findLibsInPath(path.Join(root, p), false) + for _, p := range optionalPathsToScan { + fq.findLibsInPath(path.Join(root, p), false) + } } close(fq.queue) @@ -482,3 +520,45 @@ func (fq *findQueue) dumpMachOFile(fp string, image *macho.File) { fq.dq.DumpSymbols(fp, arch) } } + +// extractSystems extracts any dyld shared caches from `archive`, then extracts the caches +// into macOS system libraries, returning the locations on disk of any systems extracted. +func extractSystems(format ArchiveFormat, archive string, extractPath string) ([]string, error) { + cachesPath := path.Join(extractPath, "caches") + if err := os.MkdirAll(cachesPath, 0755); err != nil { + return nil, err + } + if err := ExtractCaches(format, archive, cachesPath, true); err != nil { + return nil, err + } + files, err := os.ReadDir(cachesPath) + if err != nil { + return nil, err + } + cachePrefix := "dyld_shared_cache_" + extractedDirPath := path.Join(extractPath, "extracted") + roots := make([]string, len(files)) + for _, file := range files { + fileName := file.Name() + if filepath.Ext(fileName) == "" && strings.HasPrefix(fileName, cachePrefix) { + arch := strings.TrimPrefix(fileName, cachePrefix) + extractedSystemPath := path.Join(extractedDirPath, arch) + // XXX: Maybe this shouldn't be fatal? + if err := extractDyldSharedCache(path.Join(cachesPath, fileName), extractedSystemPath); err != nil { + return nil, err + } + roots = append(roots, extractedSystemPath) + } + } + return roots, nil +} + +// extractDyldSharedCache extracts the dyld shared cache at `cachePath` to `destination`. +func extractDyldSharedCache(cachePath string, destination string) error { + dscExtractor := path.Join(*breakpadTools, "dsc_extractor") + cmd := exec.Command(dscExtractor, cachePath, destination) + if output, err := cmd.Output(); err != nil { + return fmt.Errorf("extracting shared cache at %s: %v. dsc_extractor said %v", cachePath, err, output) + } + return nil +} From 255dbbd061a400e7a3f601e82a62e65058b39e5e Mon Sep 17 00:00:00 2001 From: Ivan Penkov Date: Thu, 11 Jan 2024 11:25:57 -0800 Subject: [PATCH 13/91] Fixing a buffer overflow in the Breakpad symbol serialization code caused by an integer overflow. We started getting Breakpad symbol files that exceed some of the 32-bit limits. Change-Id: I1f81905c0b7f88a0c93f10b651e5e160876487fd Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5186360 Reviewed-by: Joshua Peraza --- src/processor/fast_source_line_resolver.cc | 13 +++++++------ src/processor/module_serializer.cc | 20 +++++++++++++++----- src/processor/module_serializer.h | 3 ++- src/processor/source_line_resolver_base.cc | 1 - 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/processor/fast_source_line_resolver.cc b/src/processor/fast_source_line_resolver.cc index 79803f2ca..1c329772d 100644 --- a/src/processor/fast_source_line_resolver.cc +++ b/src/processor/fast_source_line_resolver.cc @@ -44,6 +44,7 @@ #include "processor/fast_source_line_resolver_types.h" #include +#include #include #include #include @@ -154,7 +155,7 @@ void FastSourceLineResolver::Module::ConstructInlineFrames( } } - // Use the starting adress of the inlined range as inlined function base. + // Use the starting address of the inlined range as inlined function base. new_frame->function_base = new_frame->module->base_address(); for (const auto& range : in->inline_ranges) { if (address >= range.first && address < range.first + range.second) { @@ -228,21 +229,21 @@ bool FastSourceLineResolver::Module::LoadMapFromMemory( const char* mem_buffer = memory_buffer; mem_buffer = SimpleSerializer::Read(mem_buffer, &is_corrupt_); - const uint32_t* map_sizes = reinterpret_cast(mem_buffer); + const uint64_t* map_sizes = reinterpret_cast(mem_buffer); - unsigned int header_size = kNumberMaps_ * sizeof(unsigned int); + unsigned int header_size = kNumberMaps_ * sizeof(uint64_t); // offsets[]: an array of offset addresses (with respect to mem_buffer), // for each "Static***Map" component of Module. // "Static***Map": static version of std::map or map wrapper, i.e., StaticMap, // StaticAddressMap, StaticContainedRangeMap, and StaticRangeMap. - unsigned int offsets[kNumberMaps_]; + uint64_t offsets[kNumberMaps_]; offsets[0] = header_size; for (int i = 1; i < kNumberMaps_; ++i) { offsets[i] = offsets[i - 1] + map_sizes[i - 1]; } - unsigned int expected_size = sizeof(bool) + offsets[kNumberMaps_ - 1] + - map_sizes[kNumberMaps_ - 1] + 1; + size_t expected_size = sizeof(bool) + offsets[kNumberMaps_ - 1] + + map_sizes[kNumberMaps_ - 1] + 1; if (expected_size != memory_buffer_size && // Allow for having an extra null terminator. expected_size != memory_buffer_size - 1) { diff --git a/src/processor/module_serializer.cc b/src/processor/module_serializer.cc index 05519958f..33130353a 100644 --- a/src/processor/module_serializer.cc +++ b/src/processor/module_serializer.cc @@ -38,11 +38,21 @@ #include "processor/module_serializer.h" +#include +#include #include #include +#include "common/scoped_ptr.h" +#include "google_breakpad/processor/basic_source_line_resolver.h" +#include "google_breakpad/processor/code_module.h" +#include "google_breakpad/processor/fast_source_line_resolver.h" #include "processor/basic_code_module.h" +#include "processor/linked_ptr.h" #include "processor/logging.h" +#include "processor/map_serializers.h" +#include "processor/simple_serializer.h" +#include "processor/windows_frame_info.h" namespace google_breakpad { @@ -78,7 +88,7 @@ size_t ModuleSerializer::SizeOf(const BasicSourceLineResolver::Module& module) { inline_origin_serializer_.SizeOf(module.inline_origins_); // Header size. - total_size_alloc_ += kNumberMaps_ * sizeof(uint32_t); + total_size_alloc_ += kNumberMaps_ * sizeof(uint64_t); for (int i = 0; i < kNumberMaps_; ++i) { total_size_alloc_ += map_sizes_[i]; @@ -95,8 +105,8 @@ char* ModuleSerializer::Write(const BasicSourceLineResolver::Module& module, // Write the is_corrupt flag. dest = SimpleSerializer::Write(module.is_corrupt_, dest); // Write header. - memcpy(dest, map_sizes_, kNumberMaps_ * sizeof(uint32_t)); - dest += kNumberMaps_ * sizeof(uint32_t); + memcpy(dest, map_sizes_, kNumberMaps_ * sizeof(uint64_t)); + dest += kNumberMaps_ * sizeof(uint64_t); // Write each map. dest = files_serializer_.Write(module.files_, dest); dest = functions_serializer_.Write(module.functions_, dest); @@ -161,7 +171,7 @@ bool ModuleSerializer::SerializeModuleAndLoadIntoFastResolver( // Copy the data into string. // Must pass string to LoadModuleUsingMapBuffer(), instead of passing char* to - // LoadModuleUsingMemoryBuffer(), becaused of data ownership/lifetime issue. + // LoadModuleUsingMemoryBuffer(), because of data ownership/lifetime issue. string symbol_data_string(symbol_data.get(), size); symbol_data.reset(); @@ -213,7 +223,7 @@ char* ModuleSerializer::SerializeSymbolFileData(const string& symbol_data, return NULL; } buffer.reset(NULL); - return Serialize(*(module.get()), size); + return Serialize(*module, size); } } // namespace google_breakpad diff --git a/src/processor/module_serializer.h b/src/processor/module_serializer.h index fd387cbbc..675d78488 100644 --- a/src/processor/module_serializer.h +++ b/src/processor/module_serializer.h @@ -36,6 +36,7 @@ #ifndef PROCESSOR_MODULE_SERIALIZER_H__ #define PROCESSOR_MODULE_SERIALIZER_H__ +#include #include #include @@ -110,7 +111,7 @@ class ModuleSerializer { FastSourceLineResolver::Module::kNumberMaps_; // Memory sizes required to serialize map components in Module. - uint32_t map_sizes_[kNumberMaps_]; + uint64_t map_sizes_[kNumberMaps_]; // Serializers for each individual map component in Module class. StdMapSerializer files_serializer_; diff --git a/src/processor/source_line_resolver_base.cc b/src/processor/source_line_resolver_base.cc index da9ff7624..351157cea 100644 --- a/src/processor/source_line_resolver_base.cc +++ b/src/processor/source_line_resolver_base.cc @@ -253,7 +253,6 @@ bool SourceLineResolverBase::LoadModuleUsingMemoryBuffer( // Returning false from here would be an indication that the symbols for // this module are missing which would be wrong. Intentionally fall through // and add the module to both the modules_ and the corrupt_modules_ lists. - assert(basic_module->IsCorrupt()); } modules_->insert(make_pair(module->code_file(), basic_module)); From 2481554490026ab9386ebc654343132d06194ce5 Mon Sep 17 00:00:00 2001 From: Ian McKellar Date: Tue, 16 Jan 2024 17:21:10 +0000 Subject: [PATCH 14/91] Regenerate Makefile.in for zstd dependency The version of Makefile.in that landed in https://crrev.com/c/4722191 had a Makefile.in that was generated from a previous version of Makefile.am where the libzstd dependency wasn't optional. That's causing some problems (see: https://crrev.com/c/5193965) and is a simple mistake. I generated this CL by simply running `automake`, so it simply makes the checked in generated Makefile.in based on the checked in source Makefile.am Change-Id: Iabb4a99bfac3f5ef6067a140bd373c9fb894878a Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5200626 Reviewed-by: Mike Frysinger --- Makefile.in | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Makefile.in b/Makefile.in index 0c47bf87d..7637800c0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -2691,11 +2691,13 @@ src_tools_linux_dump_syms_dump_syms_SOURCES = \ src/tools/linux/dump_syms/dump_syms.cc src_tools_linux_dump_syms_dump_syms_CXXFLAGS = \ - $(RUSTC_DEMANGLE_CFLAGS) + $(RUSTC_DEMANGLE_CFLAGS) \ + $(ZSTD_CFLAGS) src_tools_linux_dump_syms_dump_syms_LDADD = \ $(RUSTC_DEMANGLE_LIBS) \ - -lz -lzstd + $(ZSTD_CFLAGS) \ + -lz src_tools_linux_md2core_minidump_2_core_SOURCES = \ src/common/linux/memory_mapped_file.cc \ @@ -2822,13 +2824,15 @@ src_common_dumper_unittest_SOURCES = \ src_common_dumper_unittest_CPPFLAGS = \ $(AM_CPPFLAGS) $(TEST_CFLAGS) \ $(RUSTC_DEMANGLE_CFLAGS) \ - $(PTHREAD_CFLAGS) + $(PTHREAD_CFLAGS) \ + $(ZSTD_CFLAGS) src_common_dumper_unittest_LDADD = \ $(TEST_LIBS) \ $(RUSTC_DEMANGLE_LIBS) \ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) \ - -lz -lzstd + $(ZSTD_LIBS) \ + -lz src_common_mac_macho_reader_unittest_SOURCES = \ src/common/dwarf_cfi_to_module.cc \ From 38365ae4ec3a5fec5a1ead13bcaa0025b32cbb24 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Wed, 17 Jan 2024 12:15:06 +0000 Subject: [PATCH 15/91] Process symbols provided by NV Access Change-Id: I862905a164370298ca2f21d2030a0aab860cc08c Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5204606 Reviewed-by: Nelson Billing --- src/tools/windows/converter_exe/winsymconv.cmd | 2 ++ src/tools/windows/converter_exe/winsymconv_test.cmd | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/tools/windows/converter_exe/winsymconv.cmd b/src/tools/windows/converter_exe/winsymconv.cmd index bea84b589..ca1847847 100644 --- a/src/tools/windows/converter_exe/winsymconv.cmd +++ b/src/tools/windows/converter_exe/winsymconv.cmd @@ -39,6 +39,7 @@ google_converter.exe ^ -n https://download.amd.com/dir/bin ^ -n https://driver-symbols.nvidia.com ^ -n https://software.intel.com/sites/downloads/symbols ^ + -n https://www.nvaccess.org/files/nvda/symbols ^ -l %SYMBOL_DIR% ^ -s https://clients2.google.com/cr/staging_symbol ^ -m https://clients2.google.com/cr/staging_symbol/missingsymbols ^ @@ -58,6 +59,7 @@ google_converter.exe ^ -n https://download.amd.com/dir/bin ^ -n https://driver-symbols.nvidia.com ^ -n https://software.intel.com/sites/downloads/symbols ^ + -n https://www.nvaccess.org/files/nvda/symbols ^ -l %SYMBOL_DIR% ^ -s https://clients2.google.com/cr/symbol ^ -m https://clients2.google.com/cr/symbol/missingsymbols ^ diff --git a/src/tools/windows/converter_exe/winsymconv_test.cmd b/src/tools/windows/converter_exe/winsymconv_test.cmd index c17770660..448244d84 100644 --- a/src/tools/windows/converter_exe/winsymconv_test.cmd +++ b/src/tools/windows/converter_exe/winsymconv_test.cmd @@ -37,6 +37,7 @@ google_converter.exe ^ -n https://download.amd.com/dir/bin ^ -n https://driver-symbols.nvidia.com ^ -n https://software.intel.com/sites/downloads/symbols ^ + -n https://www.nvaccess.org/files/nvda/symbols ^ -l %SYMBOL_DIR% ^ -s https://clients2.google.com/cr/staging_symbol ^ -mf %SCRIPT_LOCATION%missing_symbols_test.txt ^ @@ -56,6 +57,7 @@ google_converter.exe ^ -n https://download.amd.com/dir/bin ^ -n https://driver-symbols.nvidia.com ^ -n https://software.intel.com/sites/downloads/symbols ^ + -n https://www.nvaccess.org/files/nvda/symbols ^ -l %SYMBOL_DIR% ^ -s https://clients2.google.com/cr/symbol ^ -mf %SCRIPT_LOCATION%missing_symbols_test.txt ^ From 6551ac3632eb7236642366f70a2eb865b87a3329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Bostr=C3=B6m?= Date: Mon, 29 Jan 2024 09:09:39 -0800 Subject: [PATCH 16/91] Fix uninitialized report_warnings in Mac dump_syms This uninitialized-memory use breaks the Mac ubsan build as dump_syms runs during the build step. Bug: chromium:1324701 Change-Id: Id4e0a7d38893b2ceb49e58d1f5c99a056d84a921 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5243705 Reviewed-by: Lei Zhang --- src/tools/mac/dump_syms/dump_syms_tool.cc | 26 +++++++---------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/src/tools/mac/dump_syms/dump_syms_tool.cc b/src/tools/mac/dump_syms/dump_syms_tool.cc index ded4c10e5..cd8e565d7 100644 --- a/src/tools/mac/dump_syms/dump_syms_tool.cc +++ b/src/tools/mac/dump_syms/dump_syms_tool.cc @@ -55,29 +55,19 @@ using google_breakpad::scoped_ptr; using std::vector; struct Options { - Options() - : srcPath(), - dsymPath(), - arch(), - header_only(false), - cfi(true), - handle_inter_cu_refs(true), - handle_inlines(false), - enable_multiple(false), - module_name(), - prefer_extern_name(false) {} + Options() = default; string srcPath; string dsymPath; std::optional arch; - bool header_only; - bool cfi; - bool handle_inter_cu_refs; - bool handle_inlines; - bool enable_multiple; + bool header_only = false; + bool cfi = true; + bool handle_inter_cu_refs = true; + bool handle_inlines = false; + bool enable_multiple = false; string module_name; - bool prefer_extern_name; - bool report_warnings; + bool prefer_extern_name = false; + bool report_warnings = false; }; static bool StackFrameEntryComparator(const Module::StackFrameEntry* a, From 5a0e1e34b0c456dec03b9f114d918a6dea7bb553 Mon Sep 17 00:00:00 2001 From: Volodymyr Riazantsev Date: Mon, 29 Jan 2024 18:24:08 -0800 Subject: [PATCH 17/91] linux_ptrace_dumper: Handle ARMEABI binaries on ARM64 kernels For ARM32 binaries running on ARM64 Linux (kernel) reading of FP registers fails. It's guarded for Android as well as softap platforms, but other ARM platforms can suffer from this issue. The ARMEABI linux_ptrace_dumper_unittest fails on system that runs under ARM64 kernel. In order to mitigate the issue, we adding a VFP registers read. The Breakpad does not support include of VFP registers into a minidump file, so that read is noop for the backend, but just a fix for broken systems. Bug: internal 322205293 Test: Run linux_ptrace_dumper_unittest on following [userland:kernel] combinations: armeabi-hardfp:armeabi armeabi-softfp:armeabi armeabi-hardfp:aarch64 aarch64:aarch64 Signed-off-by: Volodymyr Riazantsev Change-Id: I0709ae9a7ff913340ebc89de703ab2cb9c823b14 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5247149 Reviewed-by: Joshua Peraza --- .../minidump_writer/linux_ptrace_dumper.cc | 70 ++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc index 2adc39e12..ba73e3669 100644 --- a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc +++ b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc @@ -62,6 +62,20 @@ #include "common/linux/linux_libc_support.h" #include "third_party/lss/linux_syscall_support.h" +#if defined(__arm__) +/* + * https://elixir.bootlin.com/linux/v6.8-rc2/source/arch/arm/include/asm/user.h#L81 + * User specific VFP registers. If only VFPv2 is present, registers 16 to 31 + * are ignored by the ptrace system call and the signal handler. + */ +typedef struct user_vfp { + unsigned long long fpregs[32]; + unsigned long fpscr; +// Kernel just appends fpscr to the copy of fpregs, so we need to force +// compiler to build the same layout. +} __attribute__((packed, aligned(4))) user_vfp_t; +#endif // defined(__arm__) + // Suspends a thread by attaching to it. static bool SuspendThread(pid_t pid) { // This may fail if the thread has just died or debugged. @@ -152,6 +166,24 @@ bool LinuxPtraceDumper::CopyFromProcess(void* dest, pid_t child, return true; } +// This read VFP registers via either PTRACE_GETREGSET or PTRACE_GETREGS +#if defined(__arm__) +static bool ReadVFPRegistersArm32(pid_t tid, struct iovec* io) { +#ifdef PTRACE_GETREGSET + if (sys_ptrace(PTRACE_GETREGSET, tid, reinterpret_cast(NT_ARM_VFP), + io) == 0 && io->iov_len == sizeof(user_vfp_t)) { + return true; + } +#endif // PTRACE_GETREGSET +#ifdef PTRACE_GETVFPREGS + if (sys_ptrace(PTRACE_GETVFPREGS, tid, nullptr, io->iov_base) == 0) { + return true; + } +#endif // PTRACE_GETVFPREGS + return false; +} +#endif // defined(__arm__) + bool LinuxPtraceDumper::ReadRegisterSet(ThreadInfo* info, pid_t tid) { #ifdef PTRACE_GETREGSET @@ -163,7 +195,24 @@ bool LinuxPtraceDumper::ReadRegisterSet(ThreadInfo* info, pid_t tid) info->GetFloatingPointRegisters(&io.iov_base, &io.iov_len); if (sys_ptrace(PTRACE_GETREGSET, tid, (void*)NT_FPREGSET, (void*)&io) == -1) { - return false; + // We are going to check if we can read VFP registers on ARM32. + // Currently breakpad does not support VFP registers to be a part of minidump, + // so this is only to confirm that we can actually read FP registers. + // That is needed to prevent a false-positive minidumps failures with ARM32 + // binaries running on top of ARM64 Linux kernels. +#if defined(__arm__) + switch (errno) { + case EIO: + case EINVAL: + user_vfp vfp; + struct iovec io; + io.iov_base = &vfp; + io.iov_len = sizeof(vfp); + return ReadVFPRegistersArm32(tid, &io); + default: + return false; + } +#endif // defined(__arm__) } return true; #else @@ -194,7 +243,24 @@ bool LinuxPtraceDumper::ReadRegisters(ThreadInfo* info, pid_t tid) { void* fp_addr; info->GetFloatingPointRegisters(&fp_addr, NULL); if (sys_ptrace(PTRACE_GETFPREGS, tid, NULL, fp_addr) == -1) { - return false; + // We are going to check if we can read VFP registers on ARM32. + // Currently breakpad does not support VFP registers to be a part of minidump, + // so this is only to confirm that we can actually read FP registers. + // That is needed to prevent a false-positive minidumps failures with ARM32 + // binaries running on top of ARM64 Linux kernels. +#if defined(__arm__) + switch (errno) { + case EIO: + case EINVAL: + user_vfp vfp; + struct iovec io; + io.iov_base = &vfp; + io.iov_len = sizeof(vfp); + return ReadVFPRegistersArm32(tid, &io); + default: + return false; + } +#endif // defined(__arm__) } #endif // !(defined(__ANDROID__) && defined(__ARM_EABI__)) #endif // !defined(__SOFTFP__) From 38ac9ae56f9a46919f3898aee4c1a8e848e4e197 Mon Sep 17 00:00:00 2001 From: Volodymyr Riazantsev Date: Tue, 30 Jan 2024 15:32:04 -0800 Subject: [PATCH 18/91] linux_ptrace_dumper: Fix type definition Fix a type definition, so it doesn't collide if the similar type is already defined in the sysroot headers. Test: Build for Android/Linux. Bug: Internal 322205293 Change-Id: I3453de725083b01f2e69a61a7fc948f9f8ca5eca Signed-off-by: Volodymyr Riazantsev Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5251488 Reviewed-by: Joshua Peraza --- src/client/linux/minidump_writer/linux_ptrace_dumper.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc index ba73e3669..e5850063c 100644 --- a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc +++ b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc @@ -68,7 +68,7 @@ * User specific VFP registers. If only VFPv2 is present, registers 16 to 31 * are ignored by the ptrace system call and the signal handler. */ -typedef struct user_vfp { +typedef struct { unsigned long long fpregs[32]; unsigned long fpscr; // Kernel just appends fpscr to the copy of fpregs, so we need to force @@ -204,7 +204,7 @@ bool LinuxPtraceDumper::ReadRegisterSet(ThreadInfo* info, pid_t tid) switch (errno) { case EIO: case EINVAL: - user_vfp vfp; + user_vfp_t vfp; struct iovec io; io.iov_base = &vfp; io.iov_len = sizeof(vfp); @@ -252,7 +252,7 @@ bool LinuxPtraceDumper::ReadRegisters(ThreadInfo* info, pid_t tid) { switch (errno) { case EIO: case EINVAL: - user_vfp vfp; + user_vfp_t vfp; struct iovec io; io.iov_base = &vfp; io.iov_len = sizeof(vfp); From 6b871f4bd8b6e28191289d19e8ef074a11648a18 Mon Sep 17 00:00:00 2001 From: Nathan Moinvaziri Date: Mon, 5 Feb 2024 13:44:35 -0800 Subject: [PATCH 19/91] Code cleanup for DwarfCUToModule::NullWarningReporter changes. Updated code to use Google's modern C++ style. * Use std::unique_ptr to allocate DwarfCUToModule::WarningReporter. * Fixed reference alignment in NullWarningReporter. Change-Id: I230dac445a07b4023a64284b907010f31eadcdf4 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5265662 Reviewed-by: Lei Zhang Reviewed-by: Ivan Penkov --- src/common/dwarf_cu_to_module.h | 32 ++++++++++++++++---------------- src/common/mac/dump_syms.cc | 11 +++++------ 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/common/dwarf_cu_to_module.h b/src/common/dwarf_cu_to_module.h index d83108437..82c25091d 100644 --- a/src/common/dwarf_cu_to_module.h +++ b/src/common/dwarf_cu_to_module.h @@ -254,61 +254,61 @@ class DwarfCUToModule: public RootDIEHandler { void UncoveredHeading(); }; - class NullWarningReporter: public WarningReporter { + class NullWarningReporter : public WarningReporter { public: - NullWarningReporter(const string &filename, uint64_t cu_offset): - WarningReporter(filename, cu_offset) { } + NullWarningReporter(const string& filename, uint64_t cu_offset) + : WarningReporter(filename, cu_offset) {} // Set the name of the compilation unit we're processing to NAME. - void SetCUName(const string &name) { } + void SetCUName(const string& name) {} // Accessor and setter for uncovered_warnings_enabled_. // UncoveredFunction and UncoveredLine only report a problem if that is // true. By default, these warnings are disabled, because those // conditions occur occasionally in healthy code. - void set_uncovered_warnings_enabled(bool value) { } + void set_uncovered_warnings_enabled(bool value) {} // A DW_AT_specification in the DIE at OFFSET refers to a DIE we // haven't processed yet, or that wasn't marked as a declaration, // at TARGET. - void UnknownSpecification(uint64_t offset, uint64_t target) { } + void UnknownSpecification(uint64_t offset, uint64_t target) {} // A DW_AT_abstract_origin in the DIE at OFFSET refers to a DIE we // haven't processed yet, or that wasn't marked as inline, at TARGET. - void UnknownAbstractOrigin(uint64_t offset, uint64_t target) { } + void UnknownAbstractOrigin(uint64_t offset, uint64_t target) {} // We were unable to find the DWARF section named SECTION_NAME. - void MissingSection(const string §ion_name) { } + void MissingSection(const string& section_name) {} // The CU's DW_AT_stmt_list offset OFFSET is bogus. - void BadLineInfoOffset(uint64_t offset) { } + void BadLineInfoOffset(uint64_t offset) {} // FUNCTION includes code covered by no line number data. - void UncoveredFunction(const Module::Function &function) { } + void UncoveredFunction(const Module::Function& function) {} // Line number NUMBER in LINE_FILE, of length LENGTH, includes code // covered by no function. - void UncoveredLine(const Module::Line &line) { } + void UncoveredLine(const Module::Line& line) {} // The DW_TAG_subprogram DIE at OFFSET has no name specified directly // in the DIE, nor via a DW_AT_specification or DW_AT_abstract_origin // link. - void UnnamedFunction(uint64_t offset) { } + void UnnamedFunction(uint64_t offset) {} // __cxa_demangle() failed to demangle INPUT. - void DemangleError(const string &input) { } + void DemangleError(const string& input) {} // The DW_FORM_ref_addr at OFFSET to TARGET was not handled because // FilePrivate did not retain the inter-CU specification data. - void UnhandledInterCUReference(uint64_t offset, uint64_t target) { } + void UnhandledInterCUReference(uint64_t offset, uint64_t target) {} // The DW_AT_ranges at offset is malformed (truncated or outside of the // .debug_ranges section's bound). - void MalformedRangeList(uint64_t offset) { } + void MalformedRangeList(uint64_t offset) {} // A DW_AT_ranges attribute was encountered but the no .debug_ranges // section was found. - void MissingRanges() { } + void MissingRanges() {} }; // Create a DWARF debugging info handler for a compilation unit diff --git a/src/common/mac/dump_syms.cc b/src/common/mac/dump_syms.cc index bcb62413f..3c56734d6 100644 --- a/src/common/mac/dump_syms.cc +++ b/src/common/mac/dump_syms.cc @@ -528,13 +528,13 @@ void DumpSymbols::ReadDwarf(google_breakpad::Module* module, for (uint64_t offset = 0; offset < debug_info_length;) { // Make a handler for the root DIE that populates MODULE with the // debug info. - DwarfCUToModule::WarningReporter *reporter = nullptr; + std::unique_ptr reporter; if (report_warnings_) { - reporter = new DwarfCUToModule::WarningReporter( - selected_object_name_, offset); + reporter = std::make_unique( + selected_object_name_, offset); } else { - reporter = new DwarfCUToModule::NullWarningReporter( - selected_object_name_, offset); + reporter = std::make_unique( + selected_object_name_, offset); } DwarfCUToModule root_handler(&file_context, &line_to_module, &ranges_handler, reporter, @@ -554,7 +554,6 @@ void DumpSymbols::ReadDwarf(google_breakpad::Module* module, StartProcessSplitDwarf(&dwarf_reader, module, endianness, handle_inter_cu_refs, handle_inline); } - delete reporter; } } From 55036ddccf04ba096c2d133f80a7baf9c0b91e1d Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Tue, 13 Feb 2024 17:09:01 -0500 Subject: [PATCH 20/91] Mac: Installer extraction bug fixes - Mark `RawImagePatch` weak - Fix reversed condition in disk image unmounting - Ensure source files are closed when copying - Use 0-based indexing when determining installer OS version Bug: None Change-Id: I015f2b0d9c88a5ec128822d55c974e22723a1a6e Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5291963 Reviewed-by: Mark Mentovai --- src/tools/mac/upload_system_symbols/extract.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tools/mac/upload_system_symbols/extract.go b/src/tools/mac/upload_system_symbols/extract.go index acd674ef3..f991e3aa8 100644 --- a/src/tools/mac/upload_system_symbols/extract.go +++ b/src/tools/mac/upload_system_symbols/extract.go @@ -17,7 +17,7 @@ package main // uint32_t verbose; // } RawImage; // -// extern int32_t RawImagePatch(RawImage *); +// extern int32_t RawImagePatch(RawImage *) __attribute__((weak)); import "C" import ( @@ -125,7 +125,7 @@ func (e *Extractor) vlog(format string, args ...interface{}) { func (e *Extractor) mountDMG(dmgPath string, mountpoint string) error { cmd := exec.Command("hdiutil", "attach", dmgPath, "-mountpoint", mountpoint, "-quiet", "-nobrowse", "-readonly") err := cmd.Run() - if err != nil { + if err == nil { e.dmgMountPaths = append(e.dmgMountPaths, mountpoint) } return err @@ -299,7 +299,7 @@ func (e *installAssistantExtractor) expandInstaller(installerPath string, destin // hasCryptexes returns true if the installer containing the plist at `plistPath` is for // macOS version 13 or higher, and accordingly stores dyld shared caches inside cryptexes. func (e *installAssistantExtractor) hasCryptexes(plistPath string) (bool, error) { - print_cmd := "print :Assets:1:OSVersion" + print_cmd := "print :Assets:0:OSVersion" result, err := exec.Command("PlistBuddy", "-c", print_cmd, plistPath).Output() if err != nil { return false, fmt.Errorf("couldn't read OS version from %s: %v", plistPath, err) @@ -502,6 +502,7 @@ func copyFile(src, dst string) error { if err != nil { return err } + defer reader.Close() if _, err := io.Copy(w, reader); err != nil { return err } From f80f2888031b0570783011476a5e862fb7d848a1 Mon Sep 17 00:00:00 2001 From: Ivan Penkov Date: Thu, 15 Feb 2024 17:29:51 -0800 Subject: [PATCH 21/91] Fixing integer overflows in Breakpad Processor map/range code. Recently, Breakpad symbol files have exceeded the various 32-bit limits in these utils and we started seeing integer overflows. This is also fixing a build issue in src/common/mac/dump_syms.cc. Change-Id: Ibd913816c3b2b1171ac9991718c8911ac31eda86 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5299472 Reviewed-by: Ivan Penkov Reviewed-by: Joshua Peraza --- src/common/mac/dump_syms.cc | 4 +- .../fast_source_line_resolver_types.h | 2 +- src/processor/logging.h | 11 +- src/processor/map_serializers-inl.h | 56 +++++----- src/processor/map_serializers.h | 8 +- src/processor/map_serializers_unittest.cc | 103 +++++++++--------- src/processor/range_map-inl.h | 8 +- src/processor/range_map.h | 5 +- src/processor/range_map_unittest.cc | 10 +- src/processor/static_address_map_unittest.cc | 2 +- .../static_contained_range_map-inl.h | 2 +- src/processor/static_contained_range_map.h | 2 +- .../static_contained_range_map_unittest.cc | 17 +-- src/processor/static_map-inl.h | 40 +++---- src/processor/static_map.h | 23 ++-- src/processor/static_map_iterator-inl.h | 6 +- src/processor/static_map_iterator.h | 8 +- src/processor/static_map_unittest.cc | 37 ++++--- src/processor/static_range_map-inl.h | 2 +- src/processor/static_range_map.h | 4 +- 20 files changed, 178 insertions(+), 172 deletions(-) diff --git a/src/common/mac/dump_syms.cc b/src/common/mac/dump_syms.cc index 3c56734d6..c3ea1b82c 100644 --- a/src/common/mac/dump_syms.cc +++ b/src/common/mac/dump_syms.cc @@ -406,7 +406,7 @@ bool DumpSymbols::CreateEmptyModule(scoped_ptr& module) { selected_object_name_ = object_filename_; if (object_files_.size() > 1) { selected_object_name_ += ", architecture "; - selected_object_name_ + selected_arch_name; + selected_object_name_ += selected_arch_name; } // Compute a module name, to appear in the MODULE record. @@ -537,7 +537,7 @@ void DumpSymbols::ReadDwarf(google_breakpad::Module* module, selected_object_name_, offset); } DwarfCUToModule root_handler(&file_context, &line_to_module, - &ranges_handler, reporter, + &ranges_handler, reporter.get(), handle_inline); // Make a Dwarf2Handler that drives our DIEHandler. DIEDispatcher die_dispatcher(&root_handler); diff --git a/src/processor/fast_source_line_resolver_types.h b/src/processor/fast_source_line_resolver_types.h index 75b9004f6..14913518b 100644 --- a/src/processor/fast_source_line_resolver_types.h +++ b/src/processor/fast_source_line_resolver_types.h @@ -107,7 +107,7 @@ struct FastSourceLineResolver::Inline : public SourceLineResolverBase::Inline { // De-serialize the memory data of a Inline. void CopyFrom(const char* raw) { - DESERIALIZE(raw, has_call_site_file_id); + raw = SimpleSerializer::Read(raw, &has_call_site_file_id); DESERIALIZE(raw, inline_nest_level); DESERIALIZE(raw, call_site_line); DESERIALIZE(raw, call_site_file_id); diff --git a/src/processor/logging.h b/src/processor/logging.h index 8c040837f..519c852f5 100644 --- a/src/processor/logging.h +++ b/src/processor/logging.h @@ -57,7 +57,9 @@ #define PROCESSOR_LOGGING_H__ #include +#include #include +#include #include "common/using_std_string.h" #include "google_breakpad/common/breakpad_types.h" @@ -119,9 +121,12 @@ class LogMessageVoidify { }; // Returns number formatted as a hexadecimal string, such as "0x7b". -string HexString(uint32_t number); -string HexString(uint64_t number); -string HexString(int number); +template +string HexString(T number) { + std::stringstream stream; + stream << "0x" << std::hex << number; + return stream.str(); +} // Returns the error code as set in the global errno variable, and sets // error_string, a required argument, to a string describing that error diff --git a/src/processor/map_serializers-inl.h b/src/processor/map_serializers-inl.h index 577b95f7b..5dfb0a752 100644 --- a/src/processor/map_serializers-inl.h +++ b/src/processor/map_serializers-inl.h @@ -54,7 +54,7 @@ template size_t StdMapSerializer::SizeOf( const std::map& m) const { size_t size = 0; - size_t header_size = (1 + m.size()) * sizeof(uint32_t); + size_t header_size = (1 + m.size()) * sizeof(uint64_t); size += header_size; typename std::map::const_iterator iter; @@ -76,19 +76,19 @@ char* StdMapSerializer::Write(const std::map& m, // Write header: // Number of nodes. - dest = SimpleSerializer::Write(m.size(), dest); + dest = SimpleSerializer::Write(m.size(), dest); // Nodes offsets. - uint32_t* offsets = reinterpret_cast(dest); - dest += sizeof(uint32_t) * m.size(); + uint64_t* offsets = reinterpret_cast(dest); + dest += sizeof(uint64_t) * m.size(); char* key_address = dest; dest += sizeof(Key) * m.size(); // Traverse map. typename std::map::const_iterator iter; - int index = 0; + int64_t index = 0; for (iter = m.begin(); iter != m.end(); ++iter, ++index) { - offsets[index] = static_cast(dest - start_address); + offsets[index] = static_cast(dest - start_address); key_address = key_serializer_.Write(iter->first, key_address); dest = value_serializer_.Write(iter->second, dest); } @@ -97,9 +97,9 @@ char* StdMapSerializer::Write(const std::map& m, template char* StdMapSerializer::Serialize( - const std::map& m, unsigned int* size) const { + const std::map& m, uint64_t* size) const { // Compute size of memory to be allocated. - unsigned int size_to_alloc = SizeOf(m); + uint64_t size_to_alloc = SizeOf(m); // Allocate memory. char* serialized_data = new char[size_to_alloc]; if (!serialized_data) { @@ -118,7 +118,7 @@ template size_t RangeMapSerializer::SizeOf( const RangeMap& m) const { size_t size = 0; - size_t header_size = (1 + m.map_.size()) * sizeof(uint32_t); + size_t header_size = (1 + m.map_.size()) * sizeof(uint64_t); size += header_size; typename std::map::const_iterator iter; @@ -144,19 +144,19 @@ char* RangeMapSerializer::Write( // Write header: // Number of nodes. - dest = SimpleSerializer::Write(m.map_.size(), dest); + dest = SimpleSerializer::Write(m.map_.size(), dest); // Nodes offsets. - uint32_t* offsets = reinterpret_cast(dest); - dest += sizeof(uint32_t) * m.map_.size(); + uint64_t* offsets = reinterpret_cast(dest); + dest += sizeof(uint64_t) * m.map_.size(); char* key_address = dest; dest += sizeof(Address) * m.map_.size(); // Traverse map. typename std::map::const_iterator iter; - int index = 0; + int64_t index = 0; for (iter = m.map_.begin(); iter != m.map_.end(); ++iter, ++index) { - offsets[index] = static_cast(dest - start_address); + offsets[index] = static_cast(dest - start_address); key_address = address_serializer_.Write(iter->first, key_address); dest = address_serializer_.Write(iter->second.base(), dest); dest = entry_serializer_.Write(iter->second.entry(), dest); @@ -166,9 +166,9 @@ char* RangeMapSerializer::Write( template char* RangeMapSerializer::Serialize( - const RangeMap& m, unsigned int* size) const { + const RangeMap& m, uint64_t* size) const { // Compute size of memory to be allocated. - unsigned int size_to_alloc = SizeOf(m); + uint64_t size_to_alloc = SizeOf(m); // Allocate memory. char* serialized_data = new char[size_to_alloc]; if (!serialized_data) { @@ -191,12 +191,12 @@ size_t ContainedRangeMapSerializer::SizeOf( size_t size = 0; size_t header_size = addr_serializer_.SizeOf(m->base_) + entry_serializer_.SizeOf(m->entry_) - + sizeof(uint32_t); + + sizeof(uint64_t); size += header_size; // In case m.map_ == NULL, we treat it as an empty map: - size += sizeof(uint32_t); + size += sizeof(uint64_t); if (m->map_) { - size += m->map_->size() * sizeof(uint32_t); + size += m->map_->size() * sizeof(uint64_t); typename Map::const_iterator iter; for (iter = m->map_->begin(); iter != m->map_->end(); ++iter) { size += addr_serializer_.SizeOf(iter->first); @@ -215,27 +215,27 @@ char* ContainedRangeMapSerializer::Write( return NULL; } dest = addr_serializer_.Write(m->base_, dest); - dest = SimpleSerializer::Write(entry_serializer_.SizeOf(m->entry_), + dest = SimpleSerializer::Write(entry_serializer_.SizeOf(m->entry_), dest); dest = entry_serializer_.Write(m->entry_, dest); // Write map<: char* map_address = dest; if (m->map_ == NULL) { - dest = SimpleSerializer::Write(0, dest); + dest = SimpleSerializer::Write(0, dest); } else { - dest = SimpleSerializer::Write(m->map_->size(), dest); - uint32_t* offsets = reinterpret_cast(dest); - dest += sizeof(uint32_t) * m->map_->size(); + dest = SimpleSerializer::Write(m->map_->size(), dest); + uint64_t* offsets = reinterpret_cast(dest); + dest += sizeof(uint64_t) * m->map_->size(); char* key_address = dest; dest += sizeof(AddrType) * m->map_->size(); // Traverse map. typename Map::const_iterator iter; - int index = 0; + int64_t index = 0; for (iter = m->map_->begin(); iter != m->map_->end(); ++iter, ++index) { - offsets[index] = static_cast(dest - map_address); + offsets[index] = static_cast(dest - map_address); key_address = addr_serializer_.Write(iter->first, key_address); // Recursively write. dest = Write(iter->second, dest); @@ -246,8 +246,8 @@ char* ContainedRangeMapSerializer::Write( template char* ContainedRangeMapSerializer::Serialize( - const ContainedRangeMap* m, unsigned int* size) const { - unsigned int size_to_alloc = SizeOf(m); + const ContainedRangeMap* m, uint64_t* size) const { + uint64_t size_to_alloc = SizeOf(m); // Allocating memory. char* serialized_data = new char[size_to_alloc]; if (!serialized_data) { diff --git a/src/processor/map_serializers.h b/src/processor/map_serializers.h index 54153f8a2..933ff6fde 100644 --- a/src/processor/map_serializers.h +++ b/src/processor/map_serializers.h @@ -65,7 +65,7 @@ class StdMapSerializer { // Returns a pointer to the serialized data. If size != NULL, *size is set // to the size of serialized data, i.e., SizeOf(m). // Caller has the ownership of memory allocated as "new char[]". - char* Serialize(const std::map& m, unsigned int* size) const; + char* Serialize(const std::map& m, uint64_t* size) const; private: SimpleSerializer key_serializer_; @@ -93,7 +93,7 @@ class AddressMapSerializer { // Returns a pointer to the serialized data. If size != NULL, *size is set // to the size of serialized data, i.e., SizeOf(m). // Caller has the ownership of memory allocated as "new char[]". - char* Serialize(const AddressMap& m, unsigned int* size) const { + char* Serialize(const AddressMap& m, uint64_t* size) const { return std_map_serializer_.Serialize(m.map_, size); } @@ -120,7 +120,7 @@ class RangeMapSerializer { // Returns a pointer to the serialized data. If size != NULL, *size is set // to the size of serialized data, i.e., SizeOf(m). // Caller has the ownership of memory allocated as "new char[]". - char* Serialize(const RangeMap& m, unsigned int* size) const; + char* Serialize(const RangeMap& m, uint64_t* size) const; private: // Convenient type name for Range. @@ -151,7 +151,7 @@ class ContainedRangeMapSerializer { // to the size of serialized data, i.e., SizeOf(m). // Caller has the ownership of memory allocated as "new char[]". char* Serialize(const ContainedRangeMap* m, - unsigned int* size) const; + uint64_t* size) const; private: // Convenient type name for the underlying map type. diff --git a/src/processor/map_serializers_unittest.cc b/src/processor/map_serializers_unittest.cc index cd31ddc83..855c4dae1 100644 --- a/src/processor/map_serializers_unittest.cc +++ b/src/processor/map_serializers_unittest.cc @@ -31,6 +31,7 @@ // // Author: Siyang Xie (lambxsy@google.com) +#include #ifdef HAVE_CONFIG_H #include // Must come first #endif @@ -49,8 +50,8 @@ #include "processor/range_map-inl.h" #include "processor/contained_range_map-inl.h" -typedef int32_t AddrType; -typedef int32_t EntryType; +typedef int64_t AddrType; +typedef int64_t EntryType; class TestStdMapSerializer : public ::testing::Test { protected: @@ -65,13 +66,13 @@ class TestStdMapSerializer : public ::testing::Test { std::map std_map_; google_breakpad::StdMapSerializer serializer_; - uint32_t serialized_size_; + uint64_t serialized_size_; char* serialized_data_; }; TEST_F(TestStdMapSerializer, EmptyMapTestCase) { - const int32_t correct_data[] = { 0 }; - uint32_t correct_size = sizeof(correct_data); + const int64_t correct_data[] = { 0 }; + uint64_t correct_size = sizeof(correct_data); // std_map_ is empty. serialized_data_ = serializer_.Serialize(std_map_, &serialized_size_); @@ -81,17 +82,17 @@ TEST_F(TestStdMapSerializer, EmptyMapTestCase) { } TEST_F(TestStdMapSerializer, MapWithTwoElementsTestCase) { - const int32_t correct_data[] = { + const int64_t correct_data[] = { // # of nodes 2, // Offsets - 20, 24, + 40, 48, // Keys 1, 3, // Values 2, 6 }; - uint32_t correct_size = sizeof(correct_data); + uint64_t correct_size = sizeof(correct_data); std_map_.insert(std::make_pair(1, 2)); std_map_.insert(std::make_pair(3, 6)); @@ -103,17 +104,17 @@ TEST_F(TestStdMapSerializer, MapWithTwoElementsTestCase) { } TEST_F(TestStdMapSerializer, MapWithFiveElementsTestCase) { - const int32_t correct_data[] = { + const int64_t correct_data[] = { // # of nodes 5, // Offsets - 44, 48, 52, 56, 60, + 88, 96, 104, 112, 120, // Keys 1, 2, 3, 4, 5, // Values 11, 12, 13, 14, 15 }; - uint32_t correct_size = sizeof(correct_data); + uint64_t correct_size = sizeof(correct_data); for (int i = 1; i < 6; ++i) std_map_.insert(std::make_pair(i, 10 + i)); @@ -137,13 +138,13 @@ class TestAddressMapSerializer : public ::testing::Test { google_breakpad::AddressMap address_map_; google_breakpad::AddressMapSerializer serializer_; - uint32_t serialized_size_; + uint64_t serialized_size_; char* serialized_data_; }; TEST_F(TestAddressMapSerializer, EmptyMapTestCase) { - const int32_t correct_data[] = { 0 }; - uint32_t correct_size = sizeof(correct_data); + const int64_t correct_data[] = { 0 }; + uint64_t correct_size = sizeof(correct_data); // std_map_ is empty. serialized_data_ = serializer_.Serialize(address_map_, &serialized_size_); @@ -153,17 +154,17 @@ TEST_F(TestAddressMapSerializer, EmptyMapTestCase) { } TEST_F(TestAddressMapSerializer, MapWithTwoElementsTestCase) { - const int32_t correct_data[] = { + const int64_t correct_data[] = { // # of nodes 2, // Offsets - 20, 24, + 40, 48, // Keys 1, 3, // Values 2, 6 }; - uint32_t correct_size = sizeof(correct_data); + uint64_t correct_size = sizeof(correct_data); address_map_.Store(1, 2); address_map_.Store(3, 6); @@ -175,17 +176,17 @@ TEST_F(TestAddressMapSerializer, MapWithTwoElementsTestCase) { } TEST_F(TestAddressMapSerializer, MapWithFourElementsTestCase) { - const int32_t correct_data[] = { + const int64_t correct_data[] = { // # of nodes 4, // Offsets - 36, 40, 44, 48, + 72, 80, 88, 96, // Keys -6, -4, 8, 123, // Values 2, 3, 5, 8 }; - uint32_t correct_size = sizeof(correct_data); + uint64_t correct_size = sizeof(correct_data); address_map_.Store(-6, 2); address_map_.Store(-4, 3); @@ -212,13 +213,13 @@ class TestRangeMapSerializer : public ::testing::Test { google_breakpad::RangeMap range_map_; google_breakpad::RangeMapSerializer serializer_; - uint32_t serialized_size_; + uint64_t serialized_size_; char* serialized_data_; }; TEST_F(TestRangeMapSerializer, EmptyMapTestCase) { - const int32_t correct_data[] = { 0 }; - uint32_t correct_size = sizeof(correct_data); + const int64_t correct_data[] = { 0 }; + uint64_t correct_size = sizeof(correct_data); // range_map_ is empty. serialized_data_ = serializer_.Serialize(range_map_, &serialized_size_); @@ -228,17 +229,17 @@ TEST_F(TestRangeMapSerializer, EmptyMapTestCase) { } TEST_F(TestRangeMapSerializer, MapWithOneRangeTestCase) { - const int32_t correct_data[] = { + const int64_t correct_data[] = { // # of nodes 1, // Offsets - 12, + 24, // Keys: high address 10, // Values: (low address, entry) pairs 1, 6 }; - uint32_t correct_size = sizeof(correct_data); + uint64_t correct_size = sizeof(correct_data); range_map_.StoreRange(1, 10, 6); @@ -249,17 +250,17 @@ TEST_F(TestRangeMapSerializer, MapWithOneRangeTestCase) { } TEST_F(TestRangeMapSerializer, MapWithThreeRangesTestCase) { - const int32_t correct_data[] = { + const int64_t correct_data[] = { // # of nodes 3, // Offsets - 28, 36, 44, + 56, 72, 88, // Keys: high address - 5, 9, 20, + 5, 9, 20, // Values: (low address, entry) pairs - 2, 1, 6, 2, 10, 3 + 2, 1, 6, 2, 10, 3 }; - uint32_t correct_size = sizeof(correct_data); + uint64_t correct_size = sizeof(correct_data); ASSERT_TRUE(range_map_.StoreRange(2, 4, 1)); ASSERT_TRUE(range_map_.StoreRange(6, 4, 2)); @@ -285,18 +286,18 @@ class TestContainedRangeMapSerializer : public ::testing::Test { google_breakpad::ContainedRangeMap crm_map_; google_breakpad::ContainedRangeMapSerializer serializer_; - uint32_t serialized_size_; + uint64_t serialized_size_; char* serialized_data_; }; TEST_F(TestContainedRangeMapSerializer, EmptyMapTestCase) { - const int32_t correct_data[] = { + const int64_t correct_data[] = { 0, // base address of root - 4, // size of entry + 8, // size of entry 0, // entry stored at root 0 // empty map stored at root }; - uint32_t correct_size = sizeof(correct_data); + uint64_t correct_size = sizeof(correct_data); // crm_map_ is empty. serialized_data_ = serializer_.Serialize(&crm_map_, &serialized_size_); @@ -306,21 +307,21 @@ TEST_F(TestContainedRangeMapSerializer, EmptyMapTestCase) { } TEST_F(TestContainedRangeMapSerializer, MapWithOneRangeTestCase) { - const int32_t correct_data[] = { + const int64_t correct_data[] = { 0, // base address of root - 4, // size of entry + 8, // size of entry 0, // entry stored at root // Map stored at root node: 1, // # of nodes - 12, // offset + 24, // offset 9, // key // value: a child ContainedRangeMap 3, // base address of child CRM - 4, // size of entry + 8, // size of entry -1, // entry stored in child CRM 0 // empty sub-map stored in child CRM }; - uint32_t correct_size = sizeof(correct_data); + uint64_t correct_size = sizeof(correct_data); crm_map_.StoreRange(3, 7, -1); @@ -342,27 +343,27 @@ TEST_F(TestContainedRangeMapSerializer, MapWithTwoLevelsTestCase) { // / \ | // 3~4 6~7 16-20 level 2: grandchild1, grandchild2, grandchild3 - const int32_t correct_data[] = { + const int64_t correct_data[] = { // root: base, entry_size, entry - 0, 4, 0, + 0, 8, 0, // root's map: # of nodes, offset1, offset2, key1, key2 - 2, 20, 84, 8, 20, + 2, 40, 168, 8, 20, // child1: base, entry_size, entry: - 2, 4, -1, + 2, 8, -1, // child1's map: # of nodes, offset1, offset2, key1, key2 - 2, 20, 36, 4, 7, + 2, 40, 72, 4, 7, // grandchild1: base, entry_size, entry, empty_map - 3, 4, -1, 0, + 3, 8, -1, 0, // grandchild2: base, entry_size, entry, empty_map - 6, 4, -1, 0, + 6, 8, -1, 0, // child2: base, entry_size, entry: - 10, 4, -1, + 10, 8, -1, // child2's map: # of nodes, offset1, key1 - 1, 12, 20, + 1, 24, 20, // grandchild3: base, entry_size, entry, empty_map - 16, 4, -1, 0 + 16, 8, -1, 0 }; - uint32_t correct_size = sizeof(correct_data); + uint64_t correct_size = sizeof(correct_data); // Store child1. ASSERT_TRUE(crm_map_.StoreRange(2, 7, -1)); diff --git a/src/processor/range_map-inl.h b/src/processor/range_map-inl.h index d1a194f31..e38fe50a7 100644 --- a/src/processor/range_map-inl.h +++ b/src/processor/range_map-inl.h @@ -250,7 +250,7 @@ bool RangeMap::RetrieveNearestRange( template bool RangeMap::RetrieveRangeAtIndex( - int index, EntryType* entry, AddressType* entry_base, + int64_t index, EntryType* entry, AddressType* entry_base, AddressType* entry_delta, AddressType* entry_size) const { BPLOG_IF(ERROR, !entry) << "RangeMap::RetrieveRangeAtIndex requires |entry|"; assert(entry); @@ -263,7 +263,7 @@ bool RangeMap::RetrieveRangeAtIndex( // Walk through the map. Although it's ordered, it's not a vector, so it // can't be addressed directly by index. MapConstIterator iterator = map_.begin(); - for (int this_index = 0; this_index < index; ++this_index) + for (int64_t this_index = 0; this_index < index; ++this_index) ++iterator; *entry = iterator->second.entry(); @@ -279,8 +279,8 @@ bool RangeMap::RetrieveRangeAtIndex( template -int RangeMap::GetCount() const { - return static_cast(map_.size()); +int64_t RangeMap::GetCount() const { + return static_cast(map_.size()); } diff --git a/src/processor/range_map.h b/src/processor/range_map.h index 578bd1442..1499ff296 100644 --- a/src/processor/range_map.h +++ b/src/processor/range_map.h @@ -40,6 +40,7 @@ #define PROCESSOR_RANGE_MAP_H__ +#include #include @@ -109,12 +110,12 @@ class RangeMap { // entry was shrunk down (original start address was increased by delta). // // RetrieveRangeAtIndex is not optimized for speedy operation. - bool RetrieveRangeAtIndex(int index, EntryType* entry, + bool RetrieveRangeAtIndex(int64_t index, EntryType* entry, AddressType* entry_base, AddressType* entry_delta, AddressType* entry_size) const; // Returns the number of ranges stored in the RangeMap. - int GetCount() const; + int64_t GetCount() const; // Empties the range map, restoring it to the state it was when it was // initially created. diff --git a/src/processor/range_map_unittest.cc b/src/processor/range_map_unittest.cc index 8735bb095..1bf9af24e 100644 --- a/src/processor/range_map_unittest.cc +++ b/src/processor/range_map_unittest.cc @@ -332,11 +332,11 @@ static bool RetrieveIndexTest(TestMap* range_map, int set) { return true; } -// Additional RetriveAtIndex test to expose the bug in RetrieveRangeAtIndex(). +// Additional RetrieveAtIndex test to expose the bug in RetrieveRangeAtIndex(). // Bug info: RetrieveRangeAtIndex() previously retrieves the high address of // entry, however, it is supposed to retrieve the base address of entry as // stated in the comment in range_map.h. -static bool RetriveAtIndexTest2() { +static bool RetrieveAtIndexTest2() { scoped_ptr range_map(new TestMap()); // Store ranges with base address = 2 * object_id: @@ -360,7 +360,7 @@ static bool RetriveAtIndexTest2() { int expected_base = 2 * object->id(); if (base != expected_base) { - fprintf(stderr, "FAILED: RetriveAtIndexTest2 index %d, " + fprintf(stderr, "FAILED: RetrieveAtIndexTest2 index %d, " "expected base %d, observed base %d", object_index, expected_base, base); return false; @@ -504,7 +504,7 @@ static bool RunTests() { // The RangeMap's own count of objects should also match. if (range_map->GetCount() != stored_count) { fprintf(stderr, "FAILED: stored object count doesn't match GetCount, " - "expected %d, observed %d\n", + "expected %d, observed %ld\n", stored_count, range_map->GetCount()); return false; @@ -542,7 +542,7 @@ static bool RunTests() { } } - if (!RetriveAtIndexTest2()) { + if (!RetrieveAtIndexTest2()) { fprintf(stderr, "FAILED: did not pass RetrieveAtIndexTest2()\n"); return false; } diff --git a/src/processor/static_address_map_unittest.cc b/src/processor/static_address_map_unittest.cc index aebab976c..2e8461675 100644 --- a/src/processor/static_address_map_unittest.cc +++ b/src/processor/static_address_map_unittest.cc @@ -124,7 +124,7 @@ class TestStaticAddressMap : public ::testing::Test { srand(time(0)); for (int data_item = 0; data_item < testsize[testcase]; ++data_item) { - // Retrive (aka, search) for target address and compare results from + // Retrieve (aka, search) for target address and compare results from // AddressMap and StaticAddressMap. // First, assign the search target to be one of original testdata that is diff --git a/src/processor/static_contained_range_map-inl.h b/src/processor/static_contained_range_map-inl.h index 60606ddc6..589bce4bf 100644 --- a/src/processor/static_contained_range_map-inl.h +++ b/src/processor/static_contained_range_map-inl.h @@ -45,7 +45,7 @@ template StaticContainedRangeMap::StaticContainedRangeMap( const char *base) : base_(*(reinterpret_cast(base))), - entry_size_(*(reinterpret_cast(base + sizeof(base_)))), + entry_size_(*(reinterpret_cast(base + sizeof(base_)))), entry_ptr_(reinterpret_cast( base + sizeof(base_) + sizeof(entry_size_))), map_(base + sizeof(base_) + sizeof(entry_size_) + entry_size_) { diff --git a/src/processor/static_contained_range_map.h b/src/processor/static_contained_range_map.h index 86e54666d..eea03db72 100644 --- a/src/processor/static_contained_range_map.h +++ b/src/processor/static_contained_range_map.h @@ -86,7 +86,7 @@ class StaticContainedRangeMap { // actually contain an entry, so its entry_ field is meaningless. For // this reason, the entry_ field should only be accessed on child // ContainedRangeMap objects, and never on |this|. - uint32_t entry_size_; + uint64_t entry_size_; const EntryType *entry_ptr_; // The map containing child ranges, keyed by each child range's high diff --git a/src/processor/static_contained_range_map_unittest.cc b/src/processor/static_contained_range_map_unittest.cc index d0507a4b1..c6d78400d 100644 --- a/src/processor/static_contained_range_map_unittest.cc +++ b/src/processor/static_contained_range_map_unittest.cc @@ -31,6 +31,7 @@ // // Author: Siyang Xie (lambxsy@google.com) +#include #ifdef HAVE_CONFIG_H #include // Must come first #endif @@ -161,7 +162,7 @@ class TestStaticCRMMap : public ::testing::Test { protected: void SetUp(); - // A referrence map for testing StaticCRMMap. + // A reference map for testing StaticCRMMap. google_breakpad::ContainedRangeMap crm_map_; // Static version of crm_map using serialized data of crm_map. @@ -177,7 +178,7 @@ class TestStaticCRMMap : public ::testing::Test { void TestStaticCRMMap::SetUp() { // First, do the StoreRange tests. This validates the containment // rules. - // We confirm the referrence map correctly stores data during setup. + // We confirm the reference map correctly stores data during setup. ASSERT_TRUE (crm_map_.StoreRange(10, 10, 1)); ASSERT_FALSE(crm_map_.StoreRange(10, 10, 2)); // exactly equal to 1 ASSERT_FALSE(crm_map_.StoreRange(11, 10, 3)); // begins inside 1 and extends up @@ -228,7 +229,7 @@ void TestStaticCRMMap::SetUp() { ASSERT_FALSE(crm_map_.StoreRange(86, 2, 48)); // Serialize crm_map to generate serialized data. - unsigned int size; + uint64_t size; serialized_data_.reset(serializer_.Serialize(&crm_map_, &size)); BPLOG(INFO) << "Serialized data size: " << size << " Bytes."; @@ -239,12 +240,12 @@ void TestStaticCRMMap::SetUp() { TEST_F(TestStaticCRMMap, TestEmptyMap) { CRMMap empty_crm_map; - unsigned int size; + uint64_t size; scoped_array serialized_data; serialized_data.reset(serializer_.Serialize(&empty_crm_map, &size)); scoped_ptr test_map(new TestMap(serialized_data.get())); - const unsigned int kCorrectSizeForEmptyMap = 16; + const unsigned int kCorrectSizeForEmptyMap = 24; ASSERT_EQ(kCorrectSizeForEmptyMap, size); const int *entry_test; @@ -259,12 +260,12 @@ TEST_F(TestStaticCRMMap, TestSingleElementMap) { int entry = 1; crm_map.StoreRange(10, 10, entry); - unsigned int size; + uint64_t size; scoped_array serialized_data; serialized_data.reset(serializer_.Serialize(&crm_map, &size)); scoped_ptr test_map(new TestMap(serialized_data.get())); - const unsigned int kCorrectSizeForSingleElementMap = 40; + const unsigned int kCorrectSizeForSingleElementMap = 60; ASSERT_EQ(kCorrectSizeForSingleElementMap, size); const int *entry_test; @@ -283,7 +284,7 @@ TEST_F(TestStaticCRMMap, TestRetrieveRangeEntries) { crm_map.StoreRange(2, 6, 1); crm_map.StoreRange(2, 7, 2); - unsigned int size; + uint64_t size; scoped_array serialized_data; serialized_data.reset(serializer_.Serialize(&crm_map, &size)); scoped_ptr test_map(new TestMap(serialized_data.get())); diff --git a/src/processor/static_map-inl.h b/src/processor/static_map-inl.h index f9929efe9..2e827b9f7 100644 --- a/src/processor/static_map-inl.h +++ b/src/processor/static_map-inl.h @@ -47,23 +47,23 @@ StaticMap::StaticMap(const char* raw_data) : raw_data_(raw_data), compare_() { // First 4 Bytes store the number of nodes. - num_nodes_ = *(reinterpret_cast(raw_data_)); + num_nodes_ = *(reinterpret_cast(raw_data_)); - offsets_ = reinterpret_cast( + offsets_ = reinterpret_cast( raw_data_ + sizeof(num_nodes_)); keys_ = reinterpret_cast( - raw_data_ + (1 + num_nodes_) * sizeof(uint32_t)); + raw_data_ + (1 + num_nodes_) * sizeof(uint64_t)); } // find(), lower_bound() and upper_bound() implement binary search algorithm. template StaticMapIterator StaticMap::find(const Key& key) const { - int begin = 0; - int end = num_nodes_; - int middle; - int compare_result; + int64_t begin = 0; + int64_t end = num_nodes_; + int64_t middle; + int64_t compare_result; while (begin < end) { middle = begin + (end - begin) / 2; compare_result = compare_(key, GetKeyAtIndex(middle)); @@ -81,10 +81,10 @@ StaticMap::find(const Key& key) const { template StaticMapIterator StaticMap::lower_bound(const Key& key) const { - int begin = 0; - int end = num_nodes_; - int middle; - int comp_result; + int64_t begin = 0; + int64_t end = num_nodes_; + int64_t middle; + int64_t comp_result; while (begin < end) { middle = begin + (end - begin) / 2; comp_result = compare_(key, GetKeyAtIndex(middle)); @@ -102,10 +102,10 @@ StaticMap::lower_bound(const Key& key) const { template StaticMapIterator StaticMap::upper_bound(const Key& key) const { - int begin = 0; - int end = num_nodes_; - int middle; - int compare_result; + int64_t begin = 0; + int64_t end = num_nodes_; + int64_t middle; + int64_t compare_result; while (begin < end) { middle = begin + (end - begin) / 2; compare_result = compare_(key, GetKeyAtIndex(middle)); @@ -124,22 +124,22 @@ template bool StaticMap::ValidateInMemoryStructure() const { // check the number of nodes is non-negative: if (!raw_data_) return false; - int32_t num_nodes = *(reinterpret_cast(raw_data_)); + int64_t num_nodes = *(reinterpret_cast(raw_data_)); if (num_nodes < 0) { BPLOG(INFO) << "StaticMap check failed: negative number of nodes"; return false; } - int node_index = 0; + int64_t node_index = 0; if (num_nodes_) { - uint64_t first_offset = sizeof(int32_t) * (num_nodes_ + 1) + uint64_t first_offset = sizeof(int64_t) * (num_nodes_ + 1) + sizeof(Key) * num_nodes_; // Num_nodes_ is too large. if (first_offset > 0xffffffffUL) { BPLOG(INFO) << "StaticMap check failed: size exceeds limit"; return false; } - if (offsets_[node_index] != static_cast(first_offset)) { + if (offsets_[node_index] != static_cast(first_offset)) { BPLOG(INFO) << "StaticMap check failed: first node offset is incorrect"; return false; } @@ -162,7 +162,7 @@ bool StaticMap::ValidateInMemoryStructure() const { } template -const Key StaticMap::GetKeyAtIndex(int index) const { +const Key StaticMap::GetKeyAtIndex(int64_t index) const { if (index < 0 || index >= num_nodes_) { BPLOG(ERROR) << "Key index out of range error"; // Key type is required to be primitive type. Return 0 if index is invalid. diff --git a/src/processor/static_map.h b/src/processor/static_map.h index a8f495820..be2c7d55a 100644 --- a/src/processor/static_map.h +++ b/src/processor/static_map.h @@ -34,11 +34,11 @@ // // The chunk of memory should contain data with pre-defined pattern: // **************** header *************** -// uint32 (4 bytes): number of nodes -// uint32 (4 bytes): address offset of node1's mapped_value -// uint32 (4 bytes): address offset of node2's mapped_value +// int64 (8 bytes): number of nodes +// uint64 (8 bytes): address offset of node1's mapped_value +// uint64 (8 bytes): address offset of node2's mapped_value // ... -// uint32 (4 bytes): address offset of nodeN's mapped_value +// uint64 (8 bytes): address offset of nodeN's mapped_value // // ************* Key array ************ // (X bytes): node1's key @@ -54,9 +54,6 @@ // // REQUIREMENT: Key type MUST be primitive type or pointers so that: // X = sizeof(typename Key); -// -// Note: since address offset is stored as uint32, user should keep in mind that -// StaticMap only supports up to 4GB size of memory data. // Author: Siyang Xie (lambxsy@google.com) @@ -72,7 +69,7 @@ namespace google_breakpad { template class DefaultCompare { public: - int operator()(const Key& k1, const Key& k2) const { + int64_t operator()(const Key& k1, const Key& k2) const { if (k1 < k2) return -1; if (k1 == k2) return 0; return 1; @@ -93,13 +90,13 @@ class StaticMap { explicit StaticMap(const char* raw_data); inline bool empty() const { return num_nodes_ == 0; } - inline unsigned int size() const { return num_nodes_; } + inline uint64_t size() const { return num_nodes_; } // Return iterators. inline iterator begin() const { return IteratorAtIndex(0); } inline iterator last() const { return IteratorAtIndex(num_nodes_ - 1); } inline iterator end() const { return IteratorAtIndex(num_nodes_); } - inline iterator IteratorAtIndex(int index) const { + inline iterator IteratorAtIndex(int64_t index) const { return iterator(raw_data_, index); } @@ -120,18 +117,18 @@ class StaticMap { bool ValidateInMemoryStructure() const; private: - const Key GetKeyAtIndex(int i) const; + const Key GetKeyAtIndex(int64_t i) const; // Start address of a raw memory chunk with serialized data. const char* raw_data_; // Number of nodes in the static map. - int32_t num_nodes_; + int64_t num_nodes_; // Array of offset addresses for stored values. // For example: // address_of_i-th_node_value = raw_data_ + offsets_[i] - const uint32_t* offsets_; + const uint64_t* offsets_; // keys_[i] = key of i_th node const Key* keys_; diff --git a/src/processor/static_map_iterator-inl.h b/src/processor/static_map_iterator-inl.h index 01a1b7f7b..e24a70963 100644 --- a/src/processor/static_map_iterator-inl.h +++ b/src/processor/static_map_iterator-inl.h @@ -43,12 +43,12 @@ namespace google_breakpad { template StaticMapIterator::StaticMapIterator(const char* base, - const int& index): + int64_t index): index_(index), base_(base) { // See static_map.h for documentation on // bytes format of serialized StaticMap data. - num_nodes_ = *(reinterpret_cast(base_)); - offsets_ = reinterpret_cast(base_ + sizeof(num_nodes_)); + num_nodes_ = *(reinterpret_cast(base_)); + offsets_ = reinterpret_cast(base_ + sizeof(num_nodes_)); keys_ = reinterpret_cast( base_ + (1 + num_nodes_) * sizeof(num_nodes_)); } diff --git a/src/processor/static_map_iterator.h b/src/processor/static_map_iterator.h index 6c190e975..8cfe9e080 100644 --- a/src/processor/static_map_iterator.h +++ b/src/processor/static_map_iterator.h @@ -87,21 +87,21 @@ class StaticMapIterator { friend class StaticMap; // Only StaticMap can call this constructor. - explicit StaticMapIterator(const char* base, const int32_t& index); + explicit StaticMapIterator(const char* base, int64_t index); // Index of node that the iterator is pointing to. - int32_t index_; + int64_t index_; // Beginning address of the serialized map data. const char* base_; // Number of nodes in the map. Use it to identify end() iterator. - int32_t num_nodes_; + int64_t num_nodes_; // offsets_ is an array of offset addresses of mapped values. // For example: // address_of_i-th_node_value = base_ + offsets_[i] - const uint32_t* offsets_; + const uint64_t* offsets_; // keys_[i] = key of i_th node. const Key* keys_; diff --git a/src/processor/static_map_unittest.cc b/src/processor/static_map_unittest.cc index 67b201b63..1fbb9a498 100644 --- a/src/processor/static_map_unittest.cc +++ b/src/processor/static_map_unittest.cc @@ -30,6 +30,7 @@ // // Author: Siyang Xie (lambxsy@google.com) +#include #ifdef HAVE_CONFIG_H #include // Must come first #endif @@ -52,8 +53,8 @@ class SimpleMapSerializer { static char* Serialize(const std::map& stdmap, unsigned int* size = NULL) { unsigned int size_per_node = - sizeof(uint32_t) + sizeof(Key) + sizeof(Value); - unsigned int memsize = sizeof(int32_t) + size_per_node * stdmap.size(); + sizeof(uint64_t) + sizeof(Key) + sizeof(Value); + unsigned int memsize = sizeof(int64_t) + size_per_node * stdmap.size(); if (size) *size = memsize; // Allocate memory for serialized data: @@ -61,12 +62,12 @@ class SimpleMapSerializer { char* address = mem; // Writer the number of nodes: - new (address) uint32_t(static_cast(stdmap.size())); - address += sizeof(uint32_t); + new (address) uint64_t(static_cast(stdmap.size())); + address += sizeof(uint64_t); // Nodes' offset: - uint32_t* offsets = reinterpret_cast(address); - address += sizeof(uint32_t) * stdmap.size(); + uint64_t* offsets = reinterpret_cast(address); + address += sizeof(uint64_t) * stdmap.size(); // Keys: Key* keys = reinterpret_cast(address); @@ -98,16 +99,16 @@ class TestInvalidMap : public ::testing::Test { }; TEST_F(TestInvalidMap, TestNegativeNumberNodes) { - memset(data, 0xff, sizeof(uint32_t)); // Set the number of nodes = -1 + memset(data, 0xff, sizeof(uint64_t)); // Set the number of nodes = -1 test_map = TestMap(data); ASSERT_FALSE(test_map.ValidateInMemoryStructure()); } TEST_F(TestInvalidMap, TestWrongOffsets) { - uint32_t* header = reinterpret_cast(data); - const uint32_t kNumNodes = 2; - const uint32_t kHeaderOffset = - sizeof(uint32_t) + kNumNodes * (sizeof(uint32_t) + sizeof(KeyType)); + uint64_t* header = reinterpret_cast(data); + const uint64_t kNumNodes = 2; + const uint64_t kHeaderOffset = + sizeof(uint64_t) + kNumNodes * (sizeof(uint64_t) + sizeof(KeyType)); header[0] = kNumNodes; header[1] = kHeaderOffset + 3; // Wrong offset for first node @@ -121,16 +122,16 @@ TEST_F(TestInvalidMap, TestWrongOffsets) { } TEST_F(TestInvalidMap, TestUnSortedKeys) { - uint32_t* header = reinterpret_cast(data); - const uint32_t kNumNodes = 2; - const uint32_t kHeaderOffset = - sizeof(uint32_t) + kNumNodes * (sizeof(uint32_t) + sizeof(KeyType)); + uint64_t* header = reinterpret_cast(data); + const uint64_t kNumNodes = 2; + const uint64_t kHeaderOffset = + sizeof(uint64_t) + kNumNodes * (sizeof(uint64_t) + sizeof(KeyType)); header[0] = kNumNodes; header[1] = kHeaderOffset; header[2] = kHeaderOffset + sizeof(ValueType); KeyType* keys = reinterpret_cast( - data + (kNumNodes + 1) * sizeof(uint32_t)); + data + (kNumNodes + 1) * sizeof(uint64_t)); // Set keys in non-increasing order. keys[0] = 10; keys[1] = 7; @@ -174,10 +175,10 @@ class TestValidMap : public ::testing::Test { // Set correct size of memory allocation for each test case. unsigned int size_per_node = - sizeof(uint32_t) + sizeof(KeyType) + sizeof(ValueType); + sizeof(uint64_t) + sizeof(KeyType) + sizeof(ValueType); for (testcase = 0; testcase < kNumberTestCases; ++testcase) { correct_size[testcase] = - sizeof(uint32_t) + std_map[testcase].size() * size_per_node; + sizeof(uint64_t) + std_map[testcase].size() * size_per_node; } } diff --git a/src/processor/static_range_map-inl.h b/src/processor/static_range_map-inl.h index b0a327479..3ffeec975 100644 --- a/src/processor/static_range_map-inl.h +++ b/src/processor/static_range_map-inl.h @@ -102,7 +102,7 @@ bool StaticRangeMap::RetrieveNearestRange( template bool StaticRangeMap::RetrieveRangeAtIndex( - int index, const EntryType*& entry, + int64_t index, const EntryType*& entry, AddressType* entry_base, AddressType* entry_size) const { if (index >= GetCount()) { diff --git a/src/processor/static_range_map.h b/src/processor/static_range_map.h index 319085db2..c63d2fa94 100644 --- a/src/processor/static_range_map.h +++ b/src/processor/static_range_map.h @@ -73,12 +73,12 @@ class StaticRangeMap { // range. // // RetrieveRangeAtIndex is not optimized for speedy operation. - bool RetrieveRangeAtIndex(int index, const EntryType*& entry, + bool RetrieveRangeAtIndex(int64_t index, const EntryType*& entry, AddressType* entry_base, AddressType* entry_size) const; // Returns the number of ranges stored in the RangeMap. - inline int GetCount() const { return map_.size(); } + inline int64_t GetCount() const { return map_.size(); } private: friend class ModuleComparer; From a1169061a81adc88a326261294b0af9d53caf18a Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Fri, 16 Feb 2024 12:08:14 -0500 Subject: [PATCH 22/91] Fix bad pointer comparison Bug: None Change-Id: I7f3709ee7e8b7e9e938850b1bbe24925e3e03c9b Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5300127 Reviewed-by: Mark Mentovai --- src/common/mac/dump_syms.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/mac/dump_syms.cc b/src/common/mac/dump_syms.cc index c3ea1b82c..3d3413a2b 100644 --- a/src/common/mac/dump_syms.cc +++ b/src/common/mac/dump_syms.cc @@ -394,7 +394,7 @@ bool DumpSymbols::CreateEmptyModule(scoped_ptr& module) { // In certain cases, it is possible that architecture info can't be reliably // determined, e.g. new architectures that breakpad is unware of. In that // case, avoid crashing and return false instead. - if (selected_arch_name == kUnknownArchName) { + if (strcmp(selected_arch_name, kUnknownArchName) == 0) { return false; } From b48a2d4a8ed40024d38502db5aeabd3ab6876687 Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Fri, 16 Feb 2024 12:19:44 -0500 Subject: [PATCH 23/91] Fix string format specifier Split out from https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5300127/1..4/src/processor/range_map_unittest.cc#b507 Bug: None Change-Id: Iedc8508b6c123a54fdd1de2e2719dcd70adb03a6 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5300128 Reviewed-by: Ivan Penkov --- src/processor/range_map.h | 2 +- src/processor/range_map_unittest.cc | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/processor/range_map.h b/src/processor/range_map.h index 1499ff296..05c659758 100644 --- a/src/processor/range_map.h +++ b/src/processor/range_map.h @@ -40,7 +40,7 @@ #define PROCESSOR_RANGE_MAP_H__ -#include +#include #include diff --git a/src/processor/range_map_unittest.cc b/src/processor/range_map_unittest.cc index 1bf9af24e..568df3673 100644 --- a/src/processor/range_map_unittest.cc +++ b/src/processor/range_map_unittest.cc @@ -35,6 +35,7 @@ #include // Must come first #endif +#include #include #include @@ -504,7 +505,7 @@ static bool RunTests() { // The RangeMap's own count of objects should also match. if (range_map->GetCount() != stored_count) { fprintf(stderr, "FAILED: stored object count doesn't match GetCount, " - "expected %d, observed %ld\n", + "expected %d, observed %" PRId64 "\n", stored_count, range_map->GetCount()); return false; From f032e4c3b4eaef64432482cb00eb0c3df33cde48 Mon Sep 17 00:00:00 2001 From: Ivan Penkov Date: Wed, 21 Feb 2024 15:38:10 -0800 Subject: [PATCH 24/91] Addressing a potential integer underflow in minidump.cc and stackwalker_arm64.cc Also, defining __STDC_FORMAT_MACROS before including Change-Id: Ia25c4353412ca70512efef5e98670687ab575750 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5310977 Reviewed-by: Joshua Peraza --- src/processor/minidump.cc | 8 +++++++- src/processor/proc_maps_linux.cc | 3 ++- src/processor/range_map_unittest.cc | 4 ++++ src/processor/stackwalker_arm64.cc | 7 ++++++- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 83e5a8688..3de36784e 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -32,6 +32,11 @@ // // Author: Mark Mentovai +// For PRI* macros, before anything else might #include it. +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif /* __STDC_FORMAT_MACROS */ + #ifdef HAVE_CONFIG_H #include // Must come first #endif @@ -39,6 +44,7 @@ #include "google_breakpad/processor/minidump.h" #include +#include #include #include #include @@ -820,7 +826,7 @@ bool MinidumpContext::Read(uint32_t expected_size) { // Context may include xsave registers and so be larger than // sizeof(MDRawContextX86). For now we skip this extended data. if (context_flags & MD_CONTEXT_X86_XSTATE) { - size_t bytes_left = expected_size - sizeof(MDRawContextX86); + int64_t bytes_left = expected_size - sizeof(MDRawContextX86); if (bytes_left > kMaxXSaveAreaSize) { BPLOG(ERROR) << "MinidumpContext oversized xstate area"; return false; diff --git a/src/processor/proc_maps_linux.cc b/src/processor/proc_maps_linux.cc index 6fcb909a1..5234633e6 100644 --- a/src/processor/proc_maps_linux.cc +++ b/src/processor/proc_maps_linux.cc @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// For PRI* macros, before anything else might #include it. #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS -#endif +#endif /* __STDC_FORMAT_MACROS */ #ifdef HAVE_CONFIG_H #include // Must come first diff --git a/src/processor/range_map_unittest.cc b/src/processor/range_map_unittest.cc index 568df3673..f8e3dfbe5 100644 --- a/src/processor/range_map_unittest.cc +++ b/src/processor/range_map_unittest.cc @@ -30,6 +30,10 @@ // // Author: Mark Mentovai +// For PRI* macros, before anything else might #include it. +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif /* __STDC_FORMAT_MACROS */ #ifdef HAVE_CONFIG_H #include // Must come first diff --git a/src/processor/stackwalker_arm64.cc b/src/processor/stackwalker_arm64.cc index 0fa02e04f..8ab22ba94 100644 --- a/src/processor/stackwalker_arm64.cc +++ b/src/processor/stackwalker_arm64.cc @@ -36,6 +36,7 @@ #include // Must come first #endif +#include #include #include "common/scoped_ptr.h" @@ -269,11 +270,15 @@ void StackwalkerARM64::CorrectRegLRByFramePointer( // Searching for a real callee frame. Skipping inline frames since they // don't contain context (and cannot be downcasted to StackFrameARM64). - size_t last_frame_callee_id = frames.size() - 2; + int64_t last_frame_callee_id = frames.size() - 2; while (last_frame_callee_id >= 0 && frames[last_frame_callee_id]->trust == StackFrame::FRAME_TRUST_INLINE) { last_frame_callee_id--; } + // last_frame_callee_id should not become negative because at the top of the + // stack trace we always have a context frame (FRAME_TRUST_CONTEXT) so the + // above loop should end before last_frame_callee_id gets negative. But we are + // being extra defensive here and bail if it ever becomes negative. if (last_frame_callee_id < 0) return; StackFrameARM64* last_frame_callee = static_cast(frames[last_frame_callee_id]); From 26666b80bac3254787976bb7be52db3f4a303663 Mon Sep 17 00:00:00 2001 From: Nathan Moinvaziri Date: Fri, 8 Mar 2024 18:19:33 -0800 Subject: [PATCH 25/91] Check for failed seek when skipping x86 xstate data After reading minidump context with x86 xstate data, we seek past it, so there needs to be a check to see that the seek operation did not fail. Change-Id: I8ed4394e452c435234116d97fd65856345cb618a Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5324600 Reviewed-by: Mike Frysinger --- src/processor/minidump.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 3de36784e..22dce7626 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -903,8 +903,12 @@ bool MinidumpContext::Read(uint32_t expected_size) { // Skip extended xstate data if present in X86 context. if (context_flags & MD_CONTEXT_X86_XSTATE) { - minidump_->SeekSet((minidump_->Tell() - sizeof(MDRawContextX86)) + - expected_size); + if (!minidump_->SeekSet( + (minidump_->Tell() - sizeof(MDRawContextX86)) + + expected_size)) { + BPLOG(ERROR) << "MinidumpContext cannot seek to past xstate data"; + return false; + } } break; From 76788faa4ef163081f82273bfca7fae8a734b971 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Tue, 12 Mar 2024 13:25:00 -0700 Subject: [PATCH 26/91] Print better error messages in parts of CompilationUnit Change CompilationUnit::SkipAttribute() and CompilationUnit::ProcessOffsetBaseAttribute() to print the unknown form types they encounter. Along the way, fix various formatting issues, stray trailing spaces, and update some NULLs to nullptrs. Change-Id: I5b3e72c9c6c9cb31e8a930e54418adb74b02f6c2 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5366242 Reviewed-by: Joshua Peraza --- src/common/dwarf/dwarf2reader.cc | 24 ++++++++++----------- src/common/dwarf/dwarf2reader.h | 36 ++++++++++++++++---------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc index 8a8bf6f86..51228f745 100644 --- a/src/common/dwarf/dwarf2reader.cc +++ b/src/common/dwarf/dwarf2reader.cc @@ -285,8 +285,8 @@ const uint8_t* CompilationUnit::SkipAttribute(const uint8_t* start, case DW_FORM_sec_offset: return start + reader_->OffsetSize(); } - fprintf(stderr,"Unhandled form type"); - return NULL; + fprintf(stderr,"Unhandled form type 0x%x\n", form); + return nullptr; } // Read the abbreviation offset from a compilation unit header. @@ -369,7 +369,7 @@ void CompilationUnit::ReadHeader() { break; case DW_UT_type: case DW_UT_split_type: - is_type_unit_ = true; + is_type_unit_ = true; headerptr += ReadTypeSignature(headerptr); headerptr += ReadTypeOffset(headerptr); break; @@ -512,7 +512,7 @@ const uint8_t* CompilationUnit::ProcessOffsetBaseAttribute( &len)); start += len; return ProcessOffsetBaseAttribute(dieoffset, start, attr, form, - implicit_const); + implicit_const); case DW_FORM_flag_present: return start; @@ -568,10 +568,10 @@ const uint8_t* CompilationUnit::ProcessOffsetBaseAttribute( // offset size. assert(header_.version >= 2); if (header_.version == 2) { - reader_->ReadAddress(start); + reader_->ReadAddress(start); return start + reader_->AddressSize(); } else if (header_.version >= 3) { - reader_->ReadOffset(start); + reader_->ReadOffset(start); return start + reader_->OffsetSize(); } break; @@ -647,8 +647,8 @@ const uint8_t* CompilationUnit::ProcessOffsetBaseAttribute( reader_->ReadUnsignedLEB128(start, &len); return start + len; } - fprintf(stderr, "Unhandled form type\n"); - return NULL; + fprintf(stderr,"Unhandled form type 0x%x\n", form); + return nullptr; } // If one really wanted, you could merge SkipAttribute and @@ -896,11 +896,11 @@ const uint8_t* CompilationUnit::ProcessDIE(uint64_t dieoffset, uint64_t dieoffset_copy = dieoffset; const uint8_t* start_copy = start; for (AttributeList::const_iterator i = abbrev.attributes.begin(); - i != abbrev.attributes.end(); - i++) { + i != abbrev.attributes.end(); + i++) { start_copy = ProcessOffsetBaseAttribute(dieoffset_copy, start_copy, - i->attr_, i->form_, - i->value_); + i->attr_, i->form_, + i->value_); } } diff --git a/src/common/dwarf/dwarf2reader.h b/src/common/dwarf/dwarf2reader.h index b6bd2f31a..c023211e7 100644 --- a/src/common/dwarf/dwarf2reader.h +++ b/src/common/dwarf/dwarf2reader.h @@ -570,10 +570,10 @@ class CompilationUnit { // Special version of ProcessAttribute, for finding str_offsets_base and // DW_AT_addr_base in DW_TAG_compile_unit, for DWARF v5. const uint8_t* ProcessOffsetBaseAttribute(uint64_t dieoffset, - const uint8_t* start, - enum DwarfAttribute attr, - enum DwarfForm form, - uint64_t implicit_const); + const uint8_t* start, + enum DwarfAttribute attr, + enum DwarfForm form, + uint64_t implicit_const); // Called when we have an attribute with unsigned data to give to // our handler. The attribute is for the DIE at OFFSET from the @@ -909,11 +909,11 @@ class DwpReader { // // For example, here is a complete (uncompressed) table describing the // function above: -// +// // insn cfa r0 r1 ... ra // ======================================= // func+0: sp cfa[0] -// func+1: sp+16 cfa[0] +// func+1: sp+16 cfa[0] // func+2: sp+16 cfa[-4] cfa[0] // func+11: sp+20 cfa[-4] cfa[0] // func+21: sp+20 cfa[0] @@ -947,7 +947,7 @@ class DwpReader { // save them, caller-saves registers are probably dead in the caller // anyway, so compilers usually don't generate CFA for caller-saves // registers.) -// +// // - Exactly where the CFA points is a matter of convention that // depends on the architecture and ABI in use. In the example, the // CFA is the value the stack pointer had upon entry to the @@ -968,7 +968,7 @@ class DwpReader { // reduces the size of the data by mentioning only the addresses and // columns at which changes take place. So for the above, DWARF CFI // data would only actually mention the following: -// +// // insn cfa r0 r1 ... ra // ======================================= // func+0: sp cfa[0] @@ -976,7 +976,7 @@ class DwpReader { // func+2: cfa[-4] // func+11: sp+20 // func+21: r0 -// func+22: sp +// func+22: sp // // In fact, this is the way the parser reports CFI to the consumer: as // a series of statements of the form, "At address X, column Y changed @@ -1094,7 +1094,7 @@ class CallFrameInfo { // handling are described here, rather poorly: // http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html // http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html - // + // // The mechanics of C++ exception handling, personality routines, // and language-specific data areas are described here, rather nicely: // http://www.codesourcery.com/public/cxx-abi/abi-eh.html @@ -1127,7 +1127,7 @@ class CallFrameInfo { // The start of this entry in the buffer. const uint8_t* start; - + // Which kind of entry this is. // // We want to be able to use this for error reporting even while we're @@ -1161,13 +1161,13 @@ class CallFrameInfo { struct CIE: public Entry { uint8_t version; // CFI data version number string augmentation; // vendor format extension markers - uint64_t code_alignment_factor; // scale for code address adjustments + uint64_t code_alignment_factor; // scale for code address adjustments int data_alignment_factor; // scale for stack pointer adjustments unsigned return_address_register; // which register holds the return addr // True if this CIE includes Linux C++ ABI 'z' augmentation data. bool has_z_augmentation; - + // Parsed 'z' augmentation data. These are meaningful only if // has_z_augmentation is true. bool has_z_lsda; // The 'z' augmentation included 'L'. @@ -1221,7 +1221,7 @@ class CallFrameInfo { class ValExpressionRule; class RuleMap; class State; - + // Parse the initial length and id of a CFI entry, either a CIE, an FDE, // or a .eh_frame end-of-data mark. CURSOR points to the beginning of the // data to parse. On success, populate ENTRY as appropriate, and return @@ -1308,7 +1308,7 @@ class CallFrameInfo::Handler { // Immediately after a call to Entry, the handler should assume that // the rule for each callee-saves register is "unchanged" --- that // is, that the register still has the value it had in the caller. - // + // // If a *Rule function returns true, we continue processing this entry's // instructions. If a *Rule function returns false, we stop evaluating // instructions, and skip to the next entry. Either way, we call End @@ -1497,13 +1497,13 @@ class CallFrameInfo::Reporter { // The instruction at INSN_OFFSET in the entry at OFFSET, of kind // KIND, establishes a rule that cites the CFA, but we have not // established a CFA rule yet. - virtual void NoCFARule(uint64_t offset, CallFrameInfo::EntryKind kind, + virtual void NoCFARule(uint64_t offset, CallFrameInfo::EntryKind kind, uint64_t insn_offset); // The instruction at INSN_OFFSET in the entry at OFFSET, of kind // KIND, is a DW_CFA_restore_state instruction, but the stack of // saved states is empty. - virtual void EmptyStateStack(uint64_t offset, CallFrameInfo::EntryKind kind, + virtual void EmptyStateStack(uint64_t offset, CallFrameInfo::EntryKind kind, uint64_t insn_offset); // The DW_CFA_remember_state instruction at INSN_OFFSET in the entry @@ -1511,7 +1511,7 @@ class CallFrameInfo::Reporter { // rule, whereas the current state does have a CFA rule. This is // bogus input, which the CallFrameInfo::Handler interface doesn't // (and shouldn't) have any way to report. - virtual void ClearingCFARule(uint64_t offset, CallFrameInfo::EntryKind kind, + virtual void ClearingCFARule(uint64_t offset, CallFrameInfo::EntryKind kind, uint64_t insn_offset); protected: From a86123f1e7cc27d0e3de185467b3495cf0851f54 Mon Sep 17 00:00:00 2001 From: Joshua Peraza Date: Tue, 19 Mar 2024 09:04:19 -0700 Subject: [PATCH 27/91] Fix some undefined behavior It is undefined behavior to access mis-aligned pointers. Change-Id: I06f676c6a4b92a4bb58db76b8f23750d18148940 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5380937 Reviewed-by: Ivan Penkov --- src/third_party/libdisasm/ia32_modrm.c | 9 +++++++-- src/third_party/libdisasm/x86_imm.c | 25 ++----------------------- 2 files changed, 9 insertions(+), 25 deletions(-) diff --git a/src/third_party/libdisasm/ia32_modrm.c b/src/third_party/libdisasm/ia32_modrm.c index b0fe2ed3d..c80c1b95e 100644 --- a/src/third_party/libdisasm/ia32_modrm.c +++ b/src/third_party/libdisasm/ia32_modrm.c @@ -2,6 +2,9 @@ #include "ia32_reg.h" #include "x86_imm.h" +#include +#include + /* NOTE: when decoding ModR/M and SIB, we have to add 1 to all register * values obtained from decoding the ModR/M or SIB byte, since they * are encoded with eAX = 0 and the tables in ia32_reg.c use eAX = 1. @@ -72,16 +75,18 @@ static unsigned int imm32_signsized( unsigned char *buf, size_t buf_len, return 0; } + int16_t local_short; switch (size) { case 1: *dest = *((signed char *) buf); break; case 2: - *dest = *((signed short *) buf); + memcpy(&local_short, buf, 2); + *dest = local_short; break; case 4: default: - *dest = *((signed int *) buf); + memcpy(dest, buf, 4); break; } diff --git a/src/third_party/libdisasm/x86_imm.c b/src/third_party/libdisasm/x86_imm.c index cd59bfc9a..11c8a7de9 100644 --- a/src/third_party/libdisasm/x86_imm.c +++ b/src/third_party/libdisasm/x86_imm.c @@ -2,36 +2,15 @@ #include "x86_imm.h" #include +#include unsigned int x86_imm_signsized( unsigned char * buf, size_t buf_len, void *dest, unsigned int size ) { - signed char *cp = (signed char *) dest; - signed short *sp = (signed short *) dest; - int32_t *lp = (int32_t *) dest; - qword_t *qp = (qword_t *) dest; - if ( size > buf_len ) { return 0; } - /* Copy 'size' bytes from *buf to *op - * return number of bytes copied */ - switch (size) { - case 1: /* BYTE */ - *cp = *((signed char *) buf); - break; - case 2: /* WORD */ - *sp = *((signed short *) buf); - break; - case 6: - case 8: /* QWORD */ - *qp = *((qword_t *) buf); - break; - case 4: /* DWORD */ - default: - *lp = *((int32_t *) buf); - break; - } + memcpy(dest, buf, size); return (size); } From e5dc1f86b2defc8f76b56fb473b804e42e75c41d Mon Sep 17 00:00:00 2001 From: Joshua Peraza Date: Wed, 27 Mar 2024 13:46:24 -0700 Subject: [PATCH 28/91] Reduce logging during minidump processing Change-Id: Ie62795137770cff7cda7494c5527457b1e355897 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5402921 Reviewed-by: Ivan Penkov --- src/processor/minidump_processor.cc | 2 -- src/processor/stackwalker_amd64.cc | 1 - src/processor/stackwalker_arm64.cc | 2 -- 3 files changed, 5 deletions(-) diff --git a/src/processor/minidump_processor.cc b/src/processor/minidump_processor.cc index 5d2dea6d8..c8d4d4c9a 100644 --- a/src/processor/minidump_processor.cc +++ b/src/processor/minidump_processor.cc @@ -823,8 +823,6 @@ static void CalculateFaultAddressFromInstruction(Minidump* dump, DisassemblerObjdump disassembler(context->GetContextCPU(), memory_region, instruction_ptr); - fprintf(stderr, "%s %s %s\n", disassembler.operation().c_str(), - disassembler.src().c_str(), disassembler.dest().c_str()); if (!disassembler.IsValid()) { BPLOG(INFO) << "Disassembling fault instruction failed."; return; diff --git a/src/processor/stackwalker_amd64.cc b/src/processor/stackwalker_amd64.cc index b934e73b4..f3d7f119e 100644 --- a/src/processor/stackwalker_amd64.cc +++ b/src/processor/stackwalker_amd64.cc @@ -147,7 +147,6 @@ StackFrameAMD64* StackwalkerAMD64::GetCallerByCFIFrameInfo( return NULL; if (!frame->context.rip || !frame->context.rsp) { - BPLOG(ERROR) << "invalid rip/rsp"; return NULL; } diff --git a/src/processor/stackwalker_arm64.cc b/src/processor/stackwalker_arm64.cc index 8ab22ba94..6c3168ecc 100644 --- a/src/processor/stackwalker_arm64.cc +++ b/src/processor/stackwalker_arm64.cc @@ -289,8 +289,6 @@ void StackwalkerARM64::CorrectRegLRByFramePointer( uint64_t last_fp = 0; if (last_frame_callee_fp && !memory_->GetMemoryAtAddress(last_frame_callee_fp, &last_fp)) { - BPLOG(ERROR) << "Unable to read last_fp from last_last_fp: 0x" << std::hex - << last_frame_callee_fp; return; } // Give up if STACK CFI doesn't agree with frame pointer. From a8a43bad6fdb2d63b623862bea8f6bc959d8edc9 Mon Sep 17 00:00:00 2001 From: Sim Sun Date: Wed, 17 Apr 2024 16:52:25 -0700 Subject: [PATCH 29/91] Prefer to use .note.gnu.build-id section as ElfBuildId Summary: Android prefers `.note.gnu-build-id`[0] as BuildId than anyother PT_NOTE phdrs. This CL tries to read ElfBuildId from `.note.gnu.build-id` first to fix the BuildId mismatch issue between Android tombstone report and breakpad symbol file. e.g ``` Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .note.androi[...] NOTE 0000000000000270 00000270 0000000000000018 0000000000000000 A 0 0 4 [ 2] .note.hwasan[...] NOTE 0000000000000288 00000288 000000000000001c 0000000000000000 A 0 0 4 [ 3] .note.gnu.bu[...] NOTE 00000000000002a4 000002a4 0000000000000020 0000000000000000 A 0 0 4 $ readelf -x .note.hwasan.globals Hex dump of section '.note.hwasan.globals': 0x00000288 08000000 08000000 03000000 4c4c564d ............LLVM 0x00000298 00000000 98890100 409d0100 ........@... $ readelf -x .note.gnu.build-id Hex dump of section '.note.gnu.build-id': 0x000002a4 04000000 10000000 03000000 474e5500 ............GNU. 0x000002b4 a4eb3625 c1db6452 1e881973 bfdff9bd ..6%..dR...s.... ``` The BuildId in tombstone: ``` libartbase.so (BuildId: c7e463b51b0898d442269a421353bdbd) ``` But the breakpad dump_syms got: ``` MODULE Linux arm64 000189989D40000100000000000000000 libartbase.so INFO CODE_ID 98890100409D0100 ````` [0] https://cs.android.com/android/platform/superproject/main/+/main:system/unwinding/libunwindstack/ElfInterface.cpp;l=423-427;drc=3d19fbcc09b1b44928639b06cd0b88f735cd988d Change-Id: I01e3514e0e2a1ea163c03093055284448ed4e89c Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5463566 Reviewed-by: Joshua Peraza --- src/common/linux/file_id.cc | 14 +++++----- src/common/linux/file_id_unittest.cc | 39 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/common/linux/file_id.cc b/src/common/linux/file_id.cc index d8fcbd8d6..296531608 100644 --- a/src/common/linux/file_id.cc +++ b/src/common/linux/file_id.cc @@ -99,6 +99,13 @@ static bool ElfClassBuildIDNoteIdentifier(const void* section, size_t length, // and copy it into |identifier|. static bool FindElfBuildIDNote(const void* elf_mapped_base, wasteful_vector& identifier) { + void* note_section; + size_t note_size; + if (FindElfSection(elf_mapped_base, ".note.gnu.build-id", SHT_NOTE, + (const void**)¬e_section, ¬e_size)) { + return ElfClassBuildIDNoteIdentifier(note_section, note_size, identifier); + } + PageAllocator allocator; // lld normally creates 2 PT_NOTEs, gold normally creates 1. auto_wasteful_vector segs(&allocator); @@ -110,13 +117,6 @@ static bool FindElfBuildIDNote(const void* elf_mapped_base, } } - void* note_section; - size_t note_size; - if (FindElfSection(elf_mapped_base, ".note.gnu.build-id", SHT_NOTE, - (const void**)¬e_section, ¬e_size)) { - return ElfClassBuildIDNoteIdentifier(note_section, note_size, identifier); - } - return false; } diff --git a/src/common/linux/file_id_unittest.cc b/src/common/linux/file_id_unittest.cc index 0ef453532..7be239f60 100644 --- a/src/common/linux/file_id_unittest.cc +++ b/src/common/linux/file_id_unittest.cc @@ -326,6 +326,45 @@ TYPED_TEST(FileIDTest, BuildIDMultiplePH) { EXPECT_EQ(expected_identifier_string, identifier_string); } +TYPED_TEST(FileIDTest, BuildIDMultiplePHPreferGNU) { + const uint8_t kExpectedIdentifierBytes[] = + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13}; + const string expected_identifier_string = + this->get_file_id(kExpectedIdentifierBytes); + + ELF elf(EM_386, TypeParam::kClass, kLittleEndian); + Section text(kLittleEndian); + text.Append(4096, 0); + elf.AddSection(".text", text, SHT_PROGBITS); + Notes notes1(kLittleEndian); + notes1.AddNote(0, "Linux", + reinterpret_cast("\0x42\0x02\0\0"), 4); + Notes notes2(kLittleEndian); + notes2.AddNote(NT_GNU_BUILD_ID, "GNU", + reinterpret_cast("\0x42\0x02\0\0"), 4); + Notes notes3(kLittleEndian); + notes3.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes, + sizeof(kExpectedIdentifierBytes)); + int note1_idx = elf.AddSection(".note1", notes1, SHT_NOTE); + int note2_idx = elf.AddSection(".note2", notes2, SHT_NOTE); + int note3_idx = elf.AddSection(".note.gnu.build-id", notes3, SHT_NOTE); + elf.AddSegment(note1_idx, note1_idx, PT_NOTE); + elf.AddSegment(note2_idx, note2_idx, PT_NOTE); + elf.AddSegment(note3_idx, note3_idx, PT_NOTE); + elf.Finish(); + this->GetElfContents(elf); + + id_vector identifier(this->make_vector()); + EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, + identifier)); + EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size()); + + string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier); + EXPECT_EQ(expected_identifier_string, identifier_string); +} + // Test to make sure two files with different text sections produce // different hashes when not using a build id. TYPED_TEST(FileIDTest, UniqueHashes) { From f88a1aa2af1d1fd795716365245761b89041139d Mon Sep 17 00:00:00 2001 From: Konstantin Mandrika Date: Wed, 24 Apr 2024 12:48:55 -0400 Subject: [PATCH 30/91] Use zlib's uncompress() to uncompress headers Change-Id: Ib785633b229d3f17534da9b0de93255e80fddd70 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5484086 Reviewed-by: Joshua Peraza --- src/common/linux/dump_symbols.cc | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index b693fc9e1..8e3b97420 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -315,31 +315,17 @@ uint32_t GetCompressionHeader( std::pair UncompressZlibSectionContents( const uint8_t* compressed_buffer, uint64_t compressed_size, uint64_t uncompressed_size) { - z_stream stream; - memset(&stream, 0, sizeof stream); - - stream.avail_in = compressed_size; - stream.avail_out = uncompressed_size; - stream.next_in = const_cast(compressed_buffer); - google_breakpad::scoped_array uncompressed_buffer( new uint8_t[uncompressed_size]); - int status = inflateInit(&stream); - while (stream.avail_in != 0 && status == Z_OK) { - stream.next_out = - uncompressed_buffer.get() + uncompressed_size - stream.avail_out; + uLongf size = static_cast(uncompressed_size); - if ((status = inflate(&stream, Z_FINISH)) != Z_STREAM_END) { - break; - } - - status = inflateReset(&stream); - } + int status = uncompress( + uncompressed_buffer.get(), &size, compressed_buffer, compressed_size); - return inflateEnd(&stream) != Z_OK || status != Z_OK || stream.avail_out != 0 - ? std::make_pair(nullptr, 0) - : std::make_pair(uncompressed_buffer.release(), uncompressed_size); + return status != Z_OK + ? std::make_pair(nullptr, 0) + : std::make_pair(uncompressed_buffer.release(), uncompressed_size); } #ifdef HAVE_LIBZSTD From 6fe410dcd5ddacec9554e8c217f3c37d0362da21 Mon Sep 17 00:00:00 2001 From: Sean Carpenter Date: Tue, 7 May 2024 16:01:37 -0700 Subject: [PATCH 31/91] Adds a Flag to Perserve Address Offset in dump_syms By default, the .code section start address is normalized to zero, and subsequently the address of all functions and lines are adjusted accordingly. This change adds a command line flag that perserves the original addresses. This is a requirement for those that may wish to use the crash resolver, but do not have a minidump file to work with (most commonly in firmware). TEST=make check BUG=b:328511413 Change-Id: Id7c477196ffed7fd319029b28ed2607192249c6c Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5519154 Reviewed-by: Rob Barnes Reviewed-by: Ivan Penkov Reviewed-by: Ivan Penkov --- src/common/linux/dump_symbols.cc | 2 +- src/common/linux/dump_symbols.h | 7 ++-- src/common/linux/dump_symbols_unittest.cc | 6 ++-- src/common/module.cc | 23 +++++++----- src/common/module.h | 5 +-- src/common/module_unittest.cc | 43 +++++++++++++++++++++++ src/tools/linux/dump_syms/dump_syms.cc | 7 +++- 7 files changed, 76 insertions(+), 17 deletions(-) diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index 8e3b97420..2877c9ca8 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -1280,7 +1280,7 @@ bool WriteSymbolFile(const string& load_path, &module)) return false; - bool result = module->Write(sym_stream, options.symbol_data); + bool result = module->Write(sym_stream, options.symbol_data, options.preserve_load_address); delete module; return result; } diff --git a/src/common/linux/dump_symbols.h b/src/common/linux/dump_symbols.h index f1802ecc3..d38ba6fe9 100644 --- a/src/common/linux/dump_symbols.h +++ b/src/common/linux/dump_symbols.h @@ -48,14 +48,17 @@ class Module; struct DumpOptions { DumpOptions(SymbolData symbol_data, bool handle_inter_cu_refs, - bool enable_multiple_field) + bool enable_multiple_field, + bool preserve_load_address) : symbol_data(symbol_data), handle_inter_cu_refs(handle_inter_cu_refs), - enable_multiple_field(enable_multiple_field) {} + enable_multiple_field(enable_multiple_field), + preserve_load_address(preserve_load_address) {} SymbolData symbol_data; bool handle_inter_cu_refs; bool enable_multiple_field; + bool preserve_load_address; }; // Find all the debugging information in OBJ_FILE, an ELF executable diff --git a/src/common/linux/dump_symbols_unittest.cc b/src/common/linux/dump_symbols_unittest.cc index 55dcdeed8..df3cca529 100644 --- a/src/common/linux/dump_symbols_unittest.cc +++ b/src/common/linux/dump_symbols_unittest.cc @@ -95,7 +95,7 @@ TYPED_TEST(DumpSymbols, Invalid) { Elf32_Ehdr header; memset(&header, 0, sizeof(header)); Module* module; - DumpOptions options(ALL_SYMBOL_DATA, true, false); + DumpOptions options(ALL_SYMBOL_DATA, true, false, false); EXPECT_FALSE(ReadSymbolDataInternal(reinterpret_cast(&header), "foo", "Linux", @@ -132,7 +132,7 @@ TYPED_TEST(DumpSymbols, SimplePublic) { this->GetElfContents(elf); Module* module; - DumpOptions options(ALL_SYMBOL_DATA, true, false); + DumpOptions options(ALL_SYMBOL_DATA, true, false, false); EXPECT_TRUE(ReadSymbolDataInternal(this->elfdata, "foo", "Linux", @@ -189,7 +189,7 @@ TYPED_TEST(DumpSymbols, SimpleBuildID) { this->GetElfContents(elf); Module* module; - DumpOptions options(ALL_SYMBOL_DATA, true, false); + DumpOptions options(ALL_SYMBOL_DATA, true, false, false); EXPECT_TRUE(ReadSymbolDataInternal(this->elfdata, "foo", "Linux", diff --git a/src/common/module.cc b/src/common/module.cc index b6f5da7e6..6f81b5119 100644 --- a/src/common/module.cc +++ b/src/common/module.cc @@ -380,7 +380,7 @@ bool Module::AddressIsInModule(Address address) const { return false; } -bool Module::Write(std::ostream& stream, SymbolData symbol_data) { +bool Module::Write(std::ostream& stream, SymbolData symbol_data, bool preserve_load_address) { stream << "MODULE " << os_ << " " << architecture_ << " " << id_ << " " << name_ << "\n"; if (!stream.good()) @@ -390,6 +390,13 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) { stream << "INFO CODE_ID " << code_id_ << "\n"; } + // load_address is subtracted from each line. If we use zero instead, we + // preserve the original addresses present in the ELF binary. + Address load_offset = load_address_; + if (preserve_load_address) { + load_offset = 0; + } + if (symbol_data & SYMBOLS_AND_FILES) { // Get all referenced inline origins. set inline_origins; @@ -406,13 +413,13 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) { return ReportError(); } } + // Write out inline origins. for (InlineOrigin* origin : inline_origins) { stream << "INLINE_ORIGIN " << origin->id << " " << origin->name << "\n"; if (!stream.good()) return ReportError(); } - // Write out functions and their inlines and lines. for (FunctionSet::const_iterator func_it = functions_.begin(); func_it != functions_.end(); ++func_it) { @@ -421,7 +428,7 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) { for (auto range_it = func->ranges.cbegin(); range_it != func->ranges.cend(); ++range_it) { stream << "FUNC " << (func->is_multiple ? "m " : "") << hex - << (range_it->address - load_address_) << " " << range_it->size + << (range_it->address - load_offset) << " " << range_it->size << " " << func->parameter_size << " " << func->name << dec << "\n"; @@ -434,7 +441,7 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) { stream << in->inline_nest_level << " " << in->call_site_line << " " << in->getCallSiteFileID() << " " << in->origin->id << hex; for (const Range& r : in->ranges) - stream << " " << (r.address - load_address_) << " " << r.size; + stream << " " << (r.address - load_offset) << " " << r.size; stream << dec << "\n"; }; Module::Inline::InlineDFS(func->inlines, write_inline); @@ -445,7 +452,7 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) { (line_it->address >= range_it->address) && (line_it->address < (range_it->address + range_it->size))) { stream << hex - << (line_it->address - load_address_) << " " + << (line_it->address - load_offset) << " " << line_it->size << " " << dec << line_it->number << " " @@ -464,7 +471,7 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) { extern_it != externs_.end(); ++extern_it) { Extern* ext = extern_it->get(); stream << "PUBLIC " << (ext->is_multiple ? "m " : "") << hex - << (ext->address - load_address_) << " 0 " << ext->name << dec + << (ext->address - load_offset) << " 0 " << ext->name << dec << "\n"; } } @@ -475,7 +482,7 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) { frame_it != stack_frame_entries_.end(); ++frame_it) { StackFrameEntry* entry = frame_it->get(); stream << "STACK CFI INIT " << hex - << (entry->address - load_address_) << " " + << (entry->address - load_offset) << " " << entry->size << " " << dec; if (!stream.good() || !WriteRuleMap(entry->initial_rules, stream)) @@ -487,7 +494,7 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) { for (RuleChangeMap::const_iterator delta_it = entry->rule_changes.begin(); delta_it != entry->rule_changes.end(); ++delta_it) { stream << "STACK CFI " << hex - << (delta_it->first - load_address_) << " " << dec; + << (delta_it->first - load_offset) << " " << dec; if (!stream.good() || !WriteRuleMap(delta_it->second, stream)) return ReportError(); diff --git a/src/common/module.h b/src/common/module.h index 28e8e9c50..69eec36de 100644 --- a/src/common/module.h +++ b/src/common/module.h @@ -421,8 +421,9 @@ class Module { // If symbol_data is CFI then: // - all CFI records. // Addresses in the output are all relative to the load address - // established by SetLoadAddress. - bool Write(std::ostream& stream, SymbolData symbol_data); + // established by SetLoadAddress, unless preserve_load_address + // is equal to true, in which case each address will remain unchanged. + bool Write(std::ostream& stream, SymbolData symbol_data, bool preserve_load_address = false); // Place the name in the global set of strings. Return a StringView points to // a string inside the pool. diff --git a/src/common/module_unittest.cc b/src/common/module_unittest.cc index c51162e52..6b2c49a41 100644 --- a/src/common/module_unittest.cc +++ b/src/common/module_unittest.cc @@ -175,6 +175,49 @@ TEST(Module, WriteRelativeLoadAddress) { contents.c_str()); } +TEST(Module, WritePreserveLoadAddress) { + stringstream s; + Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); + // Set the load address to something. Doesn't matter what. + // The goal of this test is to demonstrate that the load + // address does not impact any of the generated addresses + // when the preserve_load_address option is equal to true. + m.SetLoadAddress(0x1337ULL); + + Module::File* file = m.FindFile("filename-a.cc"); + Module::Function* function = new Module::Function( + "do_stuff", 0x110ULL); + Module::Range range(0x110ULL, 0x210ULL); + function->ranges.push_back(range); + function->parameter_size = 0x50ULL; + Module::Line line1 = { 0x110ULL, 0x1ULL, + file, 20ULL }; + function->lines.push_back(line1); + m.AddFunction(function); + + // Some stack information. + auto entry = std::make_unique(); + entry->address = 0x200ULL; + entry->size = 0x55ULL; + entry->initial_rules[".cfa"] = "some call frame info"; + entry->rule_changes[0x201ULL][".s0"] = + "some rules change call frame info"; + m.AddStackFrameEntry(std::move(entry)); + + bool preserve_load_address = true; + m.Write(s, ALL_SYMBOL_DATA, preserve_load_address); + string contents = s.str(); + EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" + "FILE 0 filename-a.cc\n" + "FUNC 110 210 50 do_stuff\n" + "110 1 20 0\n" + "STACK CFI INIT 200 55" + " .cfa: some call frame info\n" + "STACK CFI 201" + " .s0: some rules change call frame info\n", + contents.c_str()); +} + TEST(Module, WriteOmitUnusedFiles) { Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); diff --git a/src/tools/linux/dump_syms/dump_syms.cc b/src/tools/linux/dump_syms/dump_syms.cc index 2fce23c2a..99deb958f 100644 --- a/src/tools/linux/dump_syms/dump_syms.cc +++ b/src/tools/linux/dump_syms/dump_syms.cc @@ -52,6 +52,8 @@ int usage(const char* self) { google_breakpad::BaseName(self).c_str()); fprintf(stderr, "Options:\n"); fprintf(stderr, " -i: Output module header information only.\n"); + fprintf(stderr, " -a Preserve the load address - Do not normalize " + "the load address to zero.\n"); fprintf(stderr, " -c Do not generate CFI section\n"); fprintf(stderr, " -d Generate INLINE/INLINE_ORIGIN records\n"); fprintf(stderr, " -r Do not handle inter-compilation " @@ -69,6 +71,7 @@ int usage(const char* self) { int main(int argc, char** argv) { if (argc < 2) return usage(argv[0]); + bool preserve_load_address = false; bool header_only = false; bool cfi = true; bool handle_inlines = false; @@ -82,6 +85,8 @@ int main(int argc, char** argv) { argv[arg_index][0] == '-') { if (strcmp("-i", argv[arg_index]) == 0) { header_only = true; + } else if (strcmp("-a", argv[arg_index]) == 0) { + preserve_load_address = true; } else if (strcmp("-c", argv[arg_index]) == 0) { cfi = false; } else if (strcmp("-d", argv[arg_index]) == 0) { @@ -143,7 +148,7 @@ int main(int argc, char** argv) { SymbolData symbol_data = (handle_inlines ? INLINES : NO_DATA) | (cfi ? CFI : NO_DATA) | SYMBOLS_AND_FILES; google_breakpad::DumpOptions options(symbol_data, handle_inter_cu_refs, - enable_multiple_field); + enable_multiple_field, preserve_load_address); if (!WriteSymbolFile(binary, obj_name, obj_os, debug_dirs, options, std::cout)) { fprintf(saved_stderr, "Failed to write symbol file.\n"); From 54986d34d4611983243f8401563ff022b649afbf Mon Sep 17 00:00:00 2001 From: Sean Carpenter Date: Wed, 8 May 2024 16:25:28 -0700 Subject: [PATCH 32/91] Adds a custom Module ID flag to dump_syms TEST=make check BUG=b:328511413 Change-Id: I09d4c5e92213501b647311b804e65f272772bbaf Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5523975 Reviewed-by: Ivan Penkov Reviewed-by: Ivan Penkov --- src/common/linux/dump_symbols.cc | 34 +++++++++------ src/common/linux/dump_symbols.h | 3 ++ src/common/linux/dump_symbols_unittest.cc | 52 +++++++++++++++++++++++ src/tools/linux/dump_syms/dump_syms.cc | 13 +++++- 4 files changed, 88 insertions(+), 14 deletions(-) diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index 2877c9ca8..846757d4e 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -1148,6 +1148,7 @@ template bool InitModuleForElfClass(const typename ElfClass::Ehdr* elf_header, const string& obj_filename, const string& obj_os, + const string& module_id, scoped_ptr& module, bool enable_multiple_field) { PageAllocator allocator; @@ -1171,10 +1172,14 @@ bool InitModuleForElfClass(const typename ElfClass::Ehdr* elf_header, ? name_buf : google_breakpad::BaseName(obj_filename); - // Add an extra "0" at the end. PDB files on Windows have an 'age' - // number appended to the end of the file identifier; this isn't - // really used or necessary on other platforms, but be consistent. - string id = FileID::ConvertIdentifierToUUIDString(identifier) + "0"; + // Use the provided module_id + string id = module_id.empty() + // Add an extra "0" at the end. PDB files on Windows have an 'age' + // number appended to the end of the file identifier; this isn't + // really used or necessary on other platforms, but be consistent. + ? FileID::ConvertIdentifierToUUIDString(identifier) + "0" + : module_id; + // This is just the raw Build ID in hex. string code_id = FileID::ConvertIdentifierToString(identifier); @@ -1188,6 +1193,7 @@ template bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, const string& obj_filename, const string& obj_os, + const string& module_id, const std::vector& debug_dirs, const DumpOptions& options, Module** out_module) { @@ -1196,8 +1202,8 @@ bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, *out_module = NULL; scoped_ptr module; - if (!InitModuleForElfClass(elf_header, obj_filename, obj_os, module, - options.enable_multiple_field)) { + if (!InitModuleForElfClass(elf_header, obj_filename, obj_os, module_id, + module, options.enable_multiple_field)) { return false; } @@ -1246,6 +1252,7 @@ namespace google_breakpad { bool ReadSymbolDataInternal(const uint8_t* obj_file, const string& obj_filename, const string& obj_os, + const string& module_id, const std::vector& debug_dirs, const DumpOptions& options, Module** module) { @@ -1258,12 +1265,12 @@ bool ReadSymbolDataInternal(const uint8_t* obj_file, if (elfclass == ELFCLASS32) { return ReadSymbolDataElfClass( reinterpret_cast(obj_file), obj_filename, obj_os, - debug_dirs, options, module); + module_id, debug_dirs, options, module); } if (elfclass == ELFCLASS64) { return ReadSymbolDataElfClass( reinterpret_cast(obj_file), obj_filename, obj_os, - debug_dirs, options, module); + module_id, debug_dirs, options, module); } return false; @@ -1272,11 +1279,12 @@ bool ReadSymbolDataInternal(const uint8_t* obj_file, bool WriteSymbolFile(const string& load_path, const string& obj_file, const string& obj_os, + const string& module_id, const std::vector& debug_dirs, const DumpOptions& options, std::ostream& sym_stream) { Module* module; - if (!ReadSymbolData(load_path, obj_file, obj_os, debug_dirs, options, + if (!ReadSymbolData(load_path, obj_file, obj_os, module_id, debug_dirs, options, &module)) return false; @@ -1291,6 +1299,7 @@ bool WriteSymbolFile(const string& load_path, bool WriteSymbolFileHeader(const string& load_path, const string& obj_file, const string& obj_os, + const string& module_id, std::ostream& sym_stream) { MmapWrapper map_wrapper; void* elf_header = NULL; @@ -1309,14 +1318,14 @@ bool WriteSymbolFileHeader(const string& load_path, if (elfclass == ELFCLASS32) { if (!InitModuleForElfClass( reinterpret_cast(elf_header), obj_file, obj_os, - module, /*enable_multiple_field=*/false)) { + module_id, module, /*enable_multiple_field=*/false)) { fprintf(stderr, "Failed to load ELF module: %s\n", obj_file.c_str()); return false; } } else if (elfclass == ELFCLASS64) { if (!InitModuleForElfClass( reinterpret_cast(elf_header), obj_file, obj_os, - module, /*enable_multiple_field=*/false)) { + module_id, module, /*enable_multiple_field=*/false)) { fprintf(stderr, "Failed to load ELF module: %s\n", obj_file.c_str()); return false; } @@ -1331,6 +1340,7 @@ bool WriteSymbolFileHeader(const string& load_path, bool ReadSymbolData(const string& load_path, const string& obj_file, const string& obj_os, + const string& module_id, const std::vector& debug_dirs, const DumpOptions& options, Module** module) { @@ -1340,7 +1350,7 @@ bool ReadSymbolData(const string& load_path, return false; return ReadSymbolDataInternal(reinterpret_cast(elf_header), - obj_file, obj_os, debug_dirs, options, module); + obj_file, obj_os, module_id, debug_dirs, options, module); } } // namespace google_breakpad diff --git a/src/common/linux/dump_symbols.h b/src/common/linux/dump_symbols.h index d38ba6fe9..25ede3e0f 100644 --- a/src/common/linux/dump_symbols.h +++ b/src/common/linux/dump_symbols.h @@ -70,6 +70,7 @@ struct DumpOptions { bool WriteSymbolFile(const string& load_path, const string& obj_file, const string& obj_os, + const string& module_id, const std::vector& debug_dirs, const DumpOptions& options, std::ostream& sym_stream); @@ -81,6 +82,7 @@ bool WriteSymbolFile(const string& load_path, bool WriteSymbolFileHeader(const string& load_path, const string& obj_file, const string& obj_os, + const string& module_id, std::ostream& sym_stream); // As above, but simply return the debugging information in MODULE @@ -89,6 +91,7 @@ bool WriteSymbolFileHeader(const string& load_path, bool ReadSymbolData(const string& load_path, const string& obj_file, const string& obj_os, + const string& module_id, const std::vector& debug_dirs, const DumpOptions& options, Module** module); diff --git a/src/common/linux/dump_symbols_unittest.cc b/src/common/linux/dump_symbols_unittest.cc index df3cca529..f20ac0dfc 100644 --- a/src/common/linux/dump_symbols_unittest.cc +++ b/src/common/linux/dump_symbols_unittest.cc @@ -55,6 +55,7 @@ namespace google_breakpad { bool ReadSymbolDataInternal(const uint8_t* obj_file, const string& obj_filename, const string& obj_os, + const string& module_id, const std::vector& debug_dir, const DumpOptions& options, Module** module); @@ -99,6 +100,7 @@ TYPED_TEST(DumpSymbols, Invalid) { EXPECT_FALSE(ReadSymbolDataInternal(reinterpret_cast(&header), "foo", "Linux", + "", vector(), options, &module)); @@ -136,6 +138,7 @@ TYPED_TEST(DumpSymbols, SimplePublic) { EXPECT_TRUE(ReadSymbolDataInternal(this->elfdata, "foo", "Linux", + "", vector(), options, &module)); @@ -151,6 +154,54 @@ TYPED_TEST(DumpSymbols, SimplePublic) { delete module; } +TYPED_TEST(DumpSymbols, ModuleIdOverride) { + ELF elf(TypeParam::kMachine, TypeParam::kClass, kLittleEndian); + // Zero out text section for simplicity. + Section text(kLittleEndian); + text.Append(4096, 0); + elf.AddSection(".text", text, SHT_PROGBITS); + + // Add a public symbol. + StringTable table(kLittleEndian); + SymbolTable syms(kLittleEndian, TypeParam::kAddrSize, table); + syms.AddSymbol("superfunc", + (typename TypeParam::Addr)0x1000, + (typename TypeParam::Addr)0x10, + // ELF32_ST_INFO works for 32-or 64-bit. + ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), + SHN_UNDEF + 1); + int index = elf.AddSection(".dynstr", table, SHT_STRTAB); + elf.AddSection(".dynsym", syms, + SHT_DYNSYM, // type + SHF_ALLOC, // flags + 0, // addr + index, // link + sizeof(typename TypeParam::Sym)); // entsize + + elf.Finish(); + this->GetElfContents(elf); + + Module* module; + DumpOptions options(ALL_SYMBOL_DATA, true, false, false); + EXPECT_TRUE(ReadSymbolDataInternal(this->elfdata, + "foo", + "Linux", + "some_module_id", + vector(), + options, + &module)); + + stringstream s; + module->Write(s, ALL_SYMBOL_DATA); + const string expected = + string("MODULE Linux ") + TypeParam::kMachineName + + " some_module_id foo\n" + "INFO CODE_ID 00000000000000000000000000000000\n" + "PUBLIC 1000 0 superfunc\n"; + EXPECT_EQ(expected, s.str()); + delete module; +} + TYPED_TEST(DumpSymbols, SimpleBuildID) { ELF elf(TypeParam::kMachine, TypeParam::kClass, kLittleEndian); // Zero out text section for simplicity. @@ -193,6 +244,7 @@ TYPED_TEST(DumpSymbols, SimpleBuildID) { EXPECT_TRUE(ReadSymbolDataInternal(this->elfdata, "foo", "Linux", + "", vector(), options, &module)); diff --git a/src/tools/linux/dump_syms/dump_syms.cc b/src/tools/linux/dump_syms/dump_syms.cc index 99deb958f..007b46094 100644 --- a/src/tools/linux/dump_syms/dump_syms.cc +++ b/src/tools/linux/dump_syms/dump_syms.cc @@ -59,6 +59,7 @@ int usage(const char* self) { fprintf(stderr, " -r Do not handle inter-compilation " "unit references\n"); fprintf(stderr, " -v Print all warnings to stderr\n"); + fprintf(stderr, " -b Use specified id for the module id\n"); fprintf(stderr, " -n Use specified name for name of the object\n"); fprintf(stderr, " -o Use specified name for the " "operating system\n"); @@ -79,6 +80,7 @@ int main(int argc, char** argv) { bool log_to_stderr = false; bool enable_multiple_field = false; std::string obj_name; + std::string module_id; const char* obj_os = "Linux"; int arg_index = 1; while (arg_index < argc && strlen(argv[arg_index]) > 0 && @@ -95,6 +97,13 @@ int main(int argc, char** argv) { handle_inter_cu_refs = false; } else if (strcmp("-v", argv[arg_index]) == 0) { log_to_stderr = true; + } else if (strcmp("-b", argv[arg_index]) == 0) { + if (arg_index + 1 >= argc) { + fprintf(stderr, "Missing argument to -b\n"); + return usage(argv[0]); + } + module_id = argv[arg_index + 1]; + ++arg_index; } else if (strcmp("-n", argv[arg_index]) == 0) { if (arg_index + 1 >= argc) { fprintf(stderr, "Missing argument to -n\n"); @@ -140,7 +149,7 @@ int main(int argc, char** argv) { obj_name = binary; if (header_only) { - if (!WriteSymbolFileHeader(binary, obj_name, obj_os, std::cout)) { + if (!WriteSymbolFileHeader(binary, obj_name, obj_os, module_id, std::cout)) { fprintf(saved_stderr, "Failed to process file.\n"); return 1; } @@ -149,7 +158,7 @@ int main(int argc, char** argv) { (cfi ? CFI : NO_DATA) | SYMBOLS_AND_FILES; google_breakpad::DumpOptions options(symbol_data, handle_inter_cu_refs, enable_multiple_field, preserve_load_address); - if (!WriteSymbolFile(binary, obj_name, obj_os, debug_dirs, options, + if (!WriteSymbolFile(binary, obj_name, obj_os, module_id, debug_dirs, options, std::cout)) { fprintf(saved_stderr, "Failed to write symbol file.\n"); return 1; From 417f5dbd0af9f96ca3e5faa99f41c064b89b40fd Mon Sep 17 00:00:00 2001 From: Jacob Hinton Date: Thu, 2 May 2024 15:19:16 -0700 Subject: [PATCH 33/91] preserve NT_FILE note converting md to core breakpad produced Minidumps have all the information needed to preserve the NT_FILE note that linux coredumps normally have, but are not currently included when converting using minidump-2-core. This adds a step to coredump generation to add the note to the coredump. This change allows for two improvements when loading coredumps into gdb: 1. for PIE code (default compilation now for gcc) gdb is now able to properly validate the PIE displacement and apply it to the debugging session, providing better stack trace quality. 2. gdb can now pick up so symbol files automatically without relying on the scripting normally recommended by google for breakpad where add-symbol-file is used to manually load symbols. Bug: https://crbug.com/google-breakpad/766 Change-Id: I8cb25246dce0ae3492eedd6d3a4efcf1783d414d Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5463435 Reviewed-by: Mike Frysinger --- src/tools/linux/md2core/minidump-2-core.cc | 86 ++++++++++++++++++++-- 1 file changed, 79 insertions(+), 7 deletions(-) diff --git a/src/tools/linux/md2core/minidump-2-core.cc b/src/tools/linux/md2core/minidump-2-core.cc index 3e310bc7d..00384c405 100644 --- a/src/tools/linux/md2core/minidump-2-core.cc +++ b/src/tools/linux/md2core/minidump-2-core.cc @@ -349,6 +349,34 @@ struct CrashedProcess { std::vector link_map; }; +/* NT_FILE note as defined by linux kernel in fs/binfmt_elf.c + * is structured as: + * long count -- how many files are mapped + * long page_size -- units for file_ofs + * array of [COUNT] elements of + * long start + * long end + * long file_ofs + * followed by COUNT filenames in ASCII: "FILE1" NUL "FILE2" NUL... + * we can re-use the file mappings info + */ +struct NtFileNote { + NtFileNote() + // XXX: we really should source page size from the minidump itself but + // I cannot find anywhere in the minidump generation code where this + // would be stashed. + : page_sz((unsigned long)getpagesize()), + filename_count(0), + filenames_length(0) { + } + + unsigned long page_sz; + unsigned long filename_count; + std::vector file_mappings; + std::vector filenames; + size_t filenames_length; +}; + #if defined(__i386__) static uint32_t U32(const uint8_t* data) { @@ -1298,6 +1326,8 @@ AugmentMappings(const Options& options, CrashedProcess* crashinfo, } AddDataToMapping(crashinfo, crashinfo->dynamic_data, (uintptr_t)crashinfo->debug.dynamic); + } else { + fprintf(stderr, "dynamic data empty\n"); } } @@ -1417,19 +1447,40 @@ main(int argc, const char* argv[]) { if (!writea(options.out_fd, &ehdr, sizeof(Ehdr))) return 1; + struct NtFileNote nt_file; + for (auto iter = crashinfo.mappings.begin(); + iter != crashinfo.mappings.end(); iter++) { + if (iter->second.filename.empty()) + continue; + nt_file.file_mappings.push_back(iter->second.start_address); + nt_file.file_mappings.push_back(iter->second.end_address); + nt_file.file_mappings.push_back(iter->second.offset); + nt_file.filenames.push_back(iter->second.filename); + nt_file.filenames_length += iter->second.filename.length() + 1; + nt_file.filename_count += 1; + } + // implementation of NT_FILE note seems to pad alignment by 4 bytes but + // keep the header size the true size of the note. so we keep nt_file_align + // as separate field. + size_t nt_file_data_sz = (2 * sizeof(unsigned long)) + + (nt_file.file_mappings.size() * sizeof(unsigned long)) + + nt_file.filenames_length; + size_t nt_file_align = nt_file_data_sz % 4 == 0 ? 0 : 4 - + (nt_file_data_sz % 4); size_t offset = sizeof(Ehdr) + ehdr.e_phnum * sizeof(Phdr); size_t filesz = sizeof(Nhdr) + 8 + sizeof(prpsinfo) + - // sizeof(Nhdr) + 8 + sizeof(user) + - sizeof(Nhdr) + 8 + crashinfo.auxv_length + - crashinfo.threads.size() * ( - (sizeof(Nhdr) + 8 + sizeof(prstatus)) + // sizeof(Nhdr) + 8 + sizeof(user) + + sizeof(Nhdr) + 8 + crashinfo.auxv_length + + sizeof(Nhdr) + 8 + nt_file_data_sz + nt_file_align + + crashinfo.threads.size() * ( + (sizeof(Nhdr) + 8 + sizeof(prstatus)) #if defined(__i386__) || defined(__x86_64__) - + sizeof(Nhdr) + 8 + sizeof(user_fpregs_struct) + + sizeof(Nhdr) + 8 + sizeof(user_fpregs_struct) #endif #if defined(__i386__) - + sizeof(Nhdr) + 8 + sizeof(user_fpxregs_struct) + + sizeof(Nhdr) + 8 + sizeof(user_fpxregs_struct) #endif - ); + ); Phdr phdr; memset(&phdr, 0, sizeof(Phdr)); @@ -1492,6 +1543,27 @@ main(int argc, const char* argv[]) { return 1; } + nhdr.n_descsz = nt_file_data_sz; + nhdr.n_type = NT_FILE; + if (!writea(options.out_fd, &nhdr, sizeof(nhdr)) || + !writea(options.out_fd, "CORE\0\0\0\0", 8) || + !writea(options.out_fd, + &nt_file.filename_count, sizeof(nt_file.filename_count)) || + !writea(options.out_fd, &nt_file.page_sz, sizeof(nt_file.page_sz))) { + return 1; + } + for (auto iter = nt_file.file_mappings.begin(); + iter != nt_file.file_mappings.end(); iter++) { + if (!writea(options.out_fd, &*iter, sizeof(*iter))) + return 1; + } + for (auto iter = nt_file.filenames.begin(); + iter != nt_file.filenames.end(); iter++) { + if (!writea(options.out_fd, iter->c_str(), iter->length() + 1)) + return 1; + } + writea(options.out_fd, "\0\0\0\0", nt_file_align); + for (const auto& current_thread : crashinfo.threads) { if (current_thread.tid == crashinfo.exception.tid) { // Use the exception record's context for the crashed thread instead of From 9dd7d3497e7f6d58e9459e0e6be28b1d4b41d35f Mon Sep 17 00:00:00 2001 From: Tyrel Russell Date: Thu, 23 May 2024 12:05:02 -0400 Subject: [PATCH 34/91] Add error handling for common failure case seen processing debug symbols Propagates error from ProcessDIEs to the top level where it can be handled. Change-Id: Ib6ba171ff642a898c75233a3f70995837c6c0552 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5564423 Reviewed-by: Joshua Peraza --- src/common/dwarf/dwarf2reader.cc | 20 +++++++++++++++++--- src/common/dwarf/dwarf2reader.h | 2 +- src/common/linux/dump_symbols.cc | 21 +++++++++++++++------ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc index 51228f745..8bd1d860b 100644 --- a/src/common/dwarf/dwarf2reader.cc +++ b/src/common/dwarf/dwarf2reader.cc @@ -463,7 +463,11 @@ uint64_t CompilationUnit::Start() { } // Now that we have our abbreviations, start processing DIE's. - ProcessDIEs(); + if (!ProcessDIEs()) { + // If ProcessDIEs fails return 0, ourlength must be non-zero + // as it is equal to header_.length + (12 or 4) + return 0; + } // If this is a skeleton compilation unit generated with split DWARF, // and the client needs the full debug info, we need to find the full @@ -922,7 +926,7 @@ const uint8_t* CompilationUnit::ProcessDIE(uint64_t dieoffset, return start; } -void CompilationUnit::ProcessDIEs() { +bool CompilationUnit::ProcessDIEs() { const uint8_t* dieptr = after_header_; size_t len; @@ -953,13 +957,22 @@ void CompilationUnit::ProcessDIEs() { if (abbrev_num == 0) { if (die_stack.size() == 0) // If it is padding, then we are done with the compilation unit's DIEs. - return; + return true; const uint64_t offset = die_stack.top(); die_stack.pop(); handler_->EndDIE(offset); continue; } + // Abbrev > abbrev_.size() indicates a corruption in the dwarf file + // We attempt to recover + if (abbrev_num > abbrevs_->size()) { + fprintf(stderr, "An invalid abbrev was referenced %d / %d. Stopped " + "procesing following DIEs in this CU.", abbrev_num, + abbrevs_->size()); + return false; + } + const Abbrev& abbrev = abbrevs_->at(static_cast(abbrev_num)); const enum DwarfTag tag = abbrev.tag; if (!handler_->StartDIE(absolute_offset, tag)) { @@ -989,6 +1002,7 @@ void CompilationUnit::ProcessDIEs() { handler_->EndDIE(absolute_offset); } } + return true; } // Check for a valid ELF file and return the Address size. diff --git a/src/common/dwarf/dwarf2reader.h b/src/common/dwarf/dwarf2reader.h index c023211e7..bd2e4d2e9 100644 --- a/src/common/dwarf/dwarf2reader.h +++ b/src/common/dwarf/dwarf2reader.h @@ -664,7 +664,7 @@ class CompilationUnit { } // Processes all DIEs for this compilation unit - void ProcessDIEs(); + bool ProcessDIEs(); // Skips the die with attributes specified in ABBREV starting at // START, and return the new place to position the stream to. diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index 846757d4e..5bb434319 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -498,7 +498,11 @@ bool LoadDwarf(const string& dwarf_filename, &byte_reader, &die_dispatcher); // Process the entire compilation unit; get the offset of the next. - offset += reader.Start(); + uint64_t result = reader.Start(); + if (result == 0) { + return false; + } + offset += result; // Start to process split dwarf file. if (reader.ShouldProcessSplitDwarf()) { StartProcessSplitDwarf(&reader, module, endianness, handle_inter_cu_refs, @@ -878,6 +882,7 @@ bool LoadSymbols(const string& obj_file, const char* names_end = names + section_names->sh_size; bool found_debug_info_section = false; bool found_usable_info = false; + bool usable_info_parsed = false; if ((options.symbol_data & SYMBOLS_AND_FILES) || (options.symbol_data & INLINES)) { @@ -893,8 +898,10 @@ bool LoadSymbols(const string& obj_file, found_debug_info_section = true; found_usable_info = true; info->LoadedSection(".stab"); - if (!LoadStabs(elf_header, stab_section, stabstr_section, - big_endian, module)) { + bool result = LoadStabs(elf_header, stab_section, stabstr_section, + big_endian, module); + usable_info_parsed = usable_info_parsed || result; + if (!result) { fprintf(stderr, "%s: \".stab\" section found, but failed to load" " STABS debugging information\n", obj_file.c_str()); } @@ -981,9 +988,11 @@ bool LoadSymbols(const string& obj_file, found_debug_info_section = true; found_usable_info = true; info->LoadedSection(".debug_info"); - if (!LoadDwarf(obj_file, elf_header, big_endian, + bool result = LoadDwarf(obj_file, elf_header, big_endian, options.handle_inter_cu_refs, - options.symbol_data & INLINES, module)) { + options.symbol_data & INLINES, module); + usable_info_parsed = usable_info_parsed || result; + if (!result){ fprintf(stderr, "%s: \".debug_info\" section found, but failed to load " "DWARF debugging information\n", obj_file.c_str()); } @@ -1088,7 +1097,7 @@ bool LoadSymbols(const string& obj_file, return false; } - return true; + return usable_info_parsed; } // Return the breakpad symbol file identifier for the architecture of From 69f9a4ef3ce4f5b40e3b202302a076cc2e96ec0b Mon Sep 17 00:00:00 2001 From: Tyrel Russell Date: Thu, 23 May 2024 14:08:59 -0400 Subject: [PATCH 35/91] Fix format string for uint64_t and size_t data. Change-Id: I9086396561ea7870cfd55ab62c416d2944f0d46b Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5564823 Reviewed-by: Mike Frysinger --- src/common/dwarf/dwarf2reader.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc index 8bd1d860b..3cae1a8e8 100644 --- a/src/common/dwarf/dwarf2reader.cc +++ b/src/common/dwarf/dwarf2reader.cc @@ -964,11 +964,10 @@ bool CompilationUnit::ProcessDIEs() { continue; } - // Abbrev > abbrev_.size() indicates a corruption in the dwarf file - // We attempt to recover + // Abbrev > abbrev_.size() indicates a corruption in the dwarf file. if (abbrev_num > abbrevs_->size()) { - fprintf(stderr, "An invalid abbrev was referenced %d / %d. Stopped " - "procesing following DIEs in this CU.", abbrev_num, + fprintf(stderr, "An invalid abbrev was referenced %" PRIu64 " / %zu. " + "Stopped procesing following DIEs in this CU.", abbrev_num, abbrevs_->size()); return false; } From 527331a471207d28d015e210c12fb8bb8b6732fd Mon Sep 17 00:00:00 2001 From: Martin Kurbanov Date: Fri, 31 May 2024 13:36:23 +0300 Subject: [PATCH 36/91] Wait for SIGSTOP during attach, reinjecting unrelated signals PTRACE_ATTACH sends SIGSTOP to this thread. However, on waitpid() we may receive some other pending signal sooner than this SIGSTOP. Therefore, we need to call waitpid() until we receive SIGSTOP. Signals other than SIGSTOP that are received need to be reinjected with PTRACE_CONT, or they will otherwise get lost. If we do not wait for the SIGSTOP signal in waitpid(), this signal will be delivered after PTRACE_DETACH, and the thread will enter the "T (stopped)" state. See ptrace(2) manpage, under the section "Attaching and detaching". Change-Id: Ifcc89cc34086988d496cd31f5dc63e9fceebcaf6 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5582149 Reviewed-by: Mike Frysinger --- .../minidump_writer/linux_ptrace_dumper.cc | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc index e5850063c..fb5b7e762 100644 --- a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc +++ b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc @@ -59,6 +59,7 @@ #include "client/linux/minidump_writer/directory_reader.h" #include "client/linux/minidump_writer/line_reader.h" +#include "common/linux/eintr_wrapper.h" #include "common/linux/linux_libc_support.h" #include "third_party/lss/linux_syscall_support.h" @@ -84,11 +85,29 @@ static bool SuspendThread(pid_t pid) { errno != 0) { return false; } - while (sys_waitpid(pid, NULL, __WALL) < 0) { - if (errno != EINTR) { + while (true) { + int status; + int r = HANDLE_EINTR(sys_waitpid(pid, &status, __WALL)); + if (r < 0) { sys_ptrace(PTRACE_DETACH, pid, NULL, NULL); return false; } + + if (!WIFSTOPPED(status)) + return false; + + // Any signal will stop the thread, make sure it is SIGSTOP. Otherwise, this + // signal will be delivered after PTRACE_DETACH, and the thread will enter + // the "T (stopped)" state. + if (WSTOPSIG(status) == SIGSTOP) + break; + + // Signals other than SIGSTOP that are received need to be reinjected, + // or they will otherwise get lost. + r = sys_ptrace(PTRACE_CONT, pid, NULL, + reinterpret_cast(WSTOPSIG(status))); + if (r < 0) + return false; } #if defined(__i386) || defined(__x86_64) // On x86, the stack pointer is NULL or -1, when executing trusted code in From c8318f06d3a48b0af37862b29fbeeeae8258dbed Mon Sep 17 00:00:00 2001 From: Joshua Peraza Date: Mon, 17 Jun 2024 16:54:19 -0700 Subject: [PATCH 37/91] ARM: use r11 as frame pointer during stack unwind Bug: b/340226382 Change-Id: Idb3d6e502a5a1e25179c3d5f2a19ac4cd79cd103 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5636127 Reviewed-by: Ivan Penkov --- src/processor/stackwalker.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/processor/stackwalker.cc b/src/processor/stackwalker.cc index 1ff6cf7cb..e7ef42d62 100644 --- a/src/processor/stackwalker.cc +++ b/src/processor/stackwalker.cc @@ -263,6 +263,8 @@ Stackwalker* Stackwalker::StackwalkerForCPU( int fp_register = -1; if (system_info->os_short == "ios") fp_register = MD_CONTEXT_ARM_REG_IOS_FP; + else + fp_register = MD_CONTEXT_ARM_REG_FP; cpu_stackwalker = new StackwalkerARM(system_info, context->GetContextARM(), fp_register, memory, modules, From e0a3a76758874bdc04e7a32e254403332f515a2d Mon Sep 17 00:00:00 2001 From: Ivan Penkov Date: Tue, 18 Jun 2024 16:35:26 -0700 Subject: [PATCH 38/91] Allows setting maximum number of threads to process. By default, there is no limit and all threads will be processed. If set to a positive integer (via set_max_thread_count), the minidump processor will stop once that limit is reached. The limit will be ignored if the crashing/requesting thread is above the specified limit. The original thread count is stored in the ProcessState and can be acessed via the original_thread_count() method. Change-Id: I6f0f173e5ad163aa7b2be76780b4a86e4932fc17 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5641257 Reviewed-by: Joshua Peraza --- .../processor/minidump_processor.h | 9 +++++ src/google_breakpad/processor/process_state.h | 6 +++ src/processor/minidump_processor.cc | 38 +++++++++++++------ src/processor/process_state.cc | 1 + 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/google_breakpad/processor/minidump_processor.h b/src/google_breakpad/processor/minidump_processor.h index 8475407e7..2a5b07499 100644 --- a/src/google_breakpad/processor/minidump_processor.h +++ b/src/google_breakpad/processor/minidump_processor.h @@ -138,6 +138,11 @@ class MinidumpProcessor { enable_objdump_for_exploitability_ = enabled; } + // Sets the maximum number of threads to process. + void set_max_thread_count(int max_thread_count) { + max_thread_count_ = max_thread_count; + } + private: StackFrameSymbolizer* frame_symbolizer_; // Indicate whether resolver_helper_ is owned by this instance. @@ -157,6 +162,10 @@ class MinidumpProcessor { // purposes of disassembly. This results in significantly more overhead than // the enable_objdump_ flag. bool enable_objdump_for_exploitability_; + + // The maximum number of threads to process. This can be exceeded if the + // requesting thread comes after the limit. Setting this to -1 means no limit. + int max_thread_count_; }; } // namespace google_breakpad diff --git a/src/google_breakpad/processor/process_state.h b/src/google_breakpad/processor/process_state.h index 3fe6a5c27..cc0e83a5d 100644 --- a/src/google_breakpad/processor/process_state.h +++ b/src/google_breakpad/processor/process_state.h @@ -105,6 +105,7 @@ class ProcessState { uint64_t crash_address() const { return crash_address_; } string assertion() const { return assertion_; } int requesting_thread() const { return requesting_thread_; } + int original_thread_count() const { return original_thread_count_; } const ExceptionRecord* exception_record() const { return &exception_record_; } const vector* threads() const { return &threads_; } const vector* thread_memory_regions() const { @@ -168,6 +169,11 @@ class ProcessState { // indicating that the dump thread is not available. int requesting_thread_; + // Original thread count. The Processor has limit on how many threads to + // process, so not all threads are processed. This tells you how many threads + // were originally in the minudump. + int original_thread_count_; + // Exception record details: code, flags, address, parameters. ExceptionRecord exception_record_; diff --git a/src/processor/minidump_processor.cc b/src/processor/minidump_processor.cc index c8d4d4c9a..44e69c890 100644 --- a/src/processor/minidump_processor.cc +++ b/src/processor/minidump_processor.cc @@ -35,6 +35,8 @@ #include #include +#include +#include #include #include #include @@ -64,7 +66,8 @@ MinidumpProcessor::MinidumpProcessor(SymbolSupplier* supplier, own_frame_symbolizer_(true), enable_exploitability_(false), enable_objdump_(false), - enable_objdump_for_exploitability_(false) { + enable_objdump_for_exploitability_(false), + max_thread_count_(-1) { } MinidumpProcessor::MinidumpProcessor(SymbolSupplier* supplier, @@ -74,7 +77,8 @@ MinidumpProcessor::MinidumpProcessor(SymbolSupplier* supplier, own_frame_symbolizer_(true), enable_exploitability_(enable_exploitability), enable_objdump_(false), - enable_objdump_for_exploitability_(false) { + enable_objdump_for_exploitability_(false), + max_thread_count_(-1) { } MinidumpProcessor::MinidumpProcessor(StackFrameSymbolizer* frame_symbolizer, @@ -83,7 +87,8 @@ MinidumpProcessor::MinidumpProcessor(StackFrameSymbolizer* frame_symbolizer, own_frame_symbolizer_(false), enable_exploitability_(enable_exploitability), enable_objdump_(false), - enable_objdump_for_exploitability_(false) { + enable_objdump_for_exploitability_(false), + max_thread_count_(-1) { assert(frame_symbolizer_); } @@ -208,29 +213,32 @@ ProcessResult MinidumpProcessor::Process( bool interrupted = false; bool found_requesting_thread = false; unsigned int thread_count = threads->thread_count(); + process_state->original_thread_count_ = thread_count; // Reset frame_symbolizer_ at the beginning of stackwalk for each minidump. frame_symbolizer_->Reset(); - MinidumpThreadNameList* thread_names = dump->GetThreadNameList(); std::map thread_id_to_name; if (thread_names) { const unsigned int thread_name_count = thread_names->thread_name_count(); for (unsigned int thread_name_index = 0; - thread_name_index < thread_name_count; - ++thread_name_index) { - MinidumpThreadName* thread_name = thread_names->GetThreadNameAtIndex(thread_name_index); + thread_name_index < thread_name_count; ++thread_name_index) { + MinidumpThreadName* thread_name = + thread_names->GetThreadNameAtIndex(thread_name_index); if (!thread_name) { - BPLOG(ERROR) << "Could not get thread name for thread at index " << thread_name_index; + BPLOG(ERROR) << "Could not get thread name for thread at index " + << thread_name_index; return PROCESS_ERROR_GETTING_THREAD_NAME; } uint32_t thread_id; if (!thread_name->GetThreadID(&thread_id)) { - BPLOG(ERROR) << "Could not get thread ID for thread at index " << thread_name_index; + BPLOG(ERROR) << "Could not get thread ID for thread at index " + << thread_name_index; return PROCESS_ERROR_GETTING_THREAD_NAME; } - thread_id_to_name.insert(std::make_pair(thread_id, thread_name->GetThreadName())); + thread_id_to_name.insert( + std::make_pair(thread_id, thread_name->GetThreadName())); } } @@ -270,6 +278,7 @@ ProcessResult MinidumpProcessor::Process( // dump of itself (when both its context and its stack are in flux), // processing that stack wouldn't provide much useful data. if (has_dump_thread && thread_id == dump_thread_id) { + process_state->original_thread_count_--; continue; } @@ -290,6 +299,13 @@ ProcessResult MinidumpProcessor::Process( // be the index of the current thread when it's pushed into the // vector. process_state->requesting_thread_ = process_state->threads_.size(); + if (max_thread_count_ >= 0) { + thread_count = + std::min(thread_count, + std::max(static_cast( + process_state->requesting_thread_ + 1), + static_cast(max_thread_count_))); + } found_requesting_thread = true; @@ -1341,7 +1357,7 @@ string MinidumpProcessor::GetCrashReason(Minidump* dump, uint64_t* address, // an attempt to read data, 1 if it was an attempt to write data, // and 8 if this was a data execution violation. // exception_information[2] contains the underlying NTSTATUS code, - // which is the explanation for why this error occured. + // which is the explanation for why this error occurred. // This information is useful in addition to the code address, which // will be present in the crash thread's instruction field anyway. if (raw_exception->exception_record.number_parameters >= 1) { diff --git a/src/processor/process_state.cc b/src/processor/process_state.cc index c5c38b6cc..54459c653 100644 --- a/src/processor/process_state.cc +++ b/src/processor/process_state.cc @@ -54,6 +54,7 @@ void ProcessState::Clear() { crash_address_ = 0; assertion_.clear(); requesting_thread_ = -1; + original_thread_count_ = 0; for (vector::const_iterator iterator = threads_.begin(); iterator != threads_.end(); ++iterator) { From 63c61b6f5a1d823ff944e1c58e1b341d27e9f0fe Mon Sep 17 00:00:00 2001 From: Jacob Hinton Date: Tue, 14 May 2024 12:37:21 -0700 Subject: [PATCH 39/91] handle write failure in minidump-2-core Change-Id: I0636f315d300a1738a9f12f28d693292a836dc56 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5539174 Reviewed-by: Mike Frysinger --- src/tools/linux/md2core/minidump-2-core.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/linux/md2core/minidump-2-core.cc b/src/tools/linux/md2core/minidump-2-core.cc index 00384c405..29560ed18 100644 --- a/src/tools/linux/md2core/minidump-2-core.cc +++ b/src/tools/linux/md2core/minidump-2-core.cc @@ -1562,7 +1562,8 @@ main(int argc, const char* argv[]) { if (!writea(options.out_fd, iter->c_str(), iter->length() + 1)) return 1; } - writea(options.out_fd, "\0\0\0\0", nt_file_align); + if (!writea(options.out_fd, "\0\0\0\0", nt_file_align)) + return 1; for (const auto& current_thread : crashinfo.threads) { if (current_thread.tid == crashinfo.exception.tid) { From 8470d392a2fdb73b8f838196ba3c09cf8c95d3ac Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Wed, 3 Jul 2024 19:37:19 +0200 Subject: [PATCH 40/91] Support large files in the Windows variant of HTTPUpload The STL uses fseek and ftell, which don't work for files with lengths greater than that which a long can accommodate. Avoid std::fstream, and instead use Win32 APIs directly to read files in the HTTP uploader. Additionally: - Halve the heap impact of reading files by reading directly into the request. - Hint to the Windows cache manager that the file will be read sequentially, thereby reducing the impact of the read on the system. Bug: chromium:349736158 Change-Id: I260836946069f6867c20a9ba8ea6043dd041c69c Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5675886 Reviewed-by: Ivan Penkov --- src/common/windows/http_upload.cc | 87 ++++++++++++++++--------------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/src/common/windows/http_upload.cc b/src/common/windows/http_upload.cc index bd48a2339..ff34f074f 100644 --- a/src/common/windows/http_upload.cc +++ b/src/common/windows/http_upload.cc @@ -31,11 +31,12 @@ #endif #include +#include +#include // Disable exception handler warnings. #pragma warning(disable:4530) -#include #include #include "common/windows/string_utils-inl.h" @@ -47,8 +48,8 @@ namespace { using std::wstring; using std::map; using std::vector; - using std::ifstream; using std::ios; + using std::unique_ptr; const wchar_t kUserAgent[] = L"Breakpad/1.0 (Windows)"; @@ -110,38 +111,51 @@ namespace { return result; } - bool GetFileContents(const wstring& filename, vector* contents) { - bool rv = false; - // The "open" method on pre-MSVC8 ifstream implementations doesn't accept a - // wchar_t* filename, so use _wfopen directly in that case. For VC8 and - // later, _wfopen has been deprecated in favor of _wfopen_s, which does - // not exist in earlier versions, so let the ifstream open the file itself. - // GCC doesn't support wide file name and opening on FILE* requires ugly - // hacks, so fallback to multi byte file. -#ifdef _MSC_VER - ifstream file; - file.open(filename.c_str(), ios::binary); -#else // GCC - ifstream file(WideToMBCP(filename, CP_ACP).c_str(), ios::binary); -#endif // _MSC_VER >= 1400 - if (file.is_open()) { - file.seekg(0, ios::end); - std::streamoff length = file.tellg(); - // Check for loss of data when converting lenght from std::streamoff into - // std::vector::size_type - std::vector::size_type vector_size = - static_cast::size_type>(length); - if (static_cast(vector_size) == length) { - contents->resize(vector_size); - if (length != 0) { - file.seekg(0, ios::beg); - file.read(&((*contents)[0]), length); + // Invokes the Win32 CloseHandle function on `handle` if it is valid. + // Intended for use as a deleter for a std::unique_ptr. + void CloseWindowsHandle(void* handle) { + if (handle != INVALID_HANDLE_VALUE && handle != nullptr) { + ::CloseHandle(handle); + } + } + + // Appends the contents of the file at `filename` to `contents`. + bool AppendFileContents(const wstring& filename, string* contents) { + // Use Win32 APIs rather than the STL so that files larger than 2^31-1 bytes + // can be read. This also allows for use of a hint to the cache manager that + // the file will be read sequentially, which can improve performance. + using ScopedWindowsHandle = + unique_ptr; + ScopedWindowsHandle file( + ::CreateFileW(filename.c_str(), GENERIC_READ, + FILE_SHARE_DELETE | FILE_SHARE_READ, + /*lpSecurityAttributes=*/nullptr, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, + /*hTemplateFile=*/nullptr), &CloseWindowsHandle); + BY_HANDLE_FILE_INFORMATION info = {}; + if (file.get() != nullptr && file.get() != INVALID_HANDLE_VALUE && + ::GetFileInformationByHandle(file.get(), &info)) { + uint64_t file_size = info.nFileSizeHigh; + file_size <<= 32; + file_size |= info.nFileSizeLow; + string::size_type position = contents->size(); + contents->resize(position + file_size); + constexpr DWORD kChunkSize = 1024*1024; + while (file_size) { + const DWORD bytes_to_read = + (file_size >= kChunkSize + ? kChunkSize + : static_cast(file_size)); + DWORD bytes_read = 0; + if (!::ReadFile(file.get(), &((*contents)[position]), bytes_to_read, + &bytes_read, /*lpOverlapped=*/nullptr)) { + return false; } - rv = true; + position += bytes_read; + file_size -= bytes_read; } - file.close(); } - return rv; + return true; } bool CheckParameters(const map& parameters) { @@ -386,16 +400,7 @@ namespace { request_body->append("\r\n"); } - vector contents; - if (!GetFileContents(filename, &contents)) { - return false; - } - - if (!contents.empty()) { - request_body->append(&(contents[0]), contents.size()); - } - - return true; + return AppendFileContents(filename, request_body); } bool GenerateRequestBody(const map& parameters, From 9ad37adcc5218698e3d24710491833a5e89d1284 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Fri, 5 Jul 2024 12:42:30 +0200 Subject: [PATCH 41/91] [Windows] Improve diagnostic logging in HTTPUpload Log the operation and Windows and/or WinInet error in case of failure. Also remove use of an intermediate buffer in ReadResponse. Bug: chromium:349736158 Change-Id: I51de506e1636e28a24a5c6dd579ebbfcd07c0345 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5679269 Reviewed-by: Primiano Tucci --- src/common/windows/http_upload.cc | 99 +++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 31 deletions(-) diff --git a/src/common/windows/http_upload.cc b/src/common/windows/http_upload.cc index ff34f074f..7dd935577 100644 --- a/src/common/windows/http_upload.cc +++ b/src/common/windows/http_upload.cc @@ -32,13 +32,12 @@ #include #include +#include #include // Disable exception handler warnings. #pragma warning(disable:4530) -#include - #include "common/windows/string_utils-inl.h" #include "common/windows/http_upload.h" @@ -47,7 +46,6 @@ namespace { using std::string; using std::wstring; using std::map; - using std::vector; using std::ios; using std::unique_ptr; @@ -111,6 +109,30 @@ namespace { return result; } + // Returns a string representation of a given Windows error code, or null + // on failure. + using ScopedLocalString = unique_ptr; + ScopedLocalString FormatError(DWORD error) { + wchar_t* message_buffer = nullptr; + DWORD message_length = + ::FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, + /*lpSource=*/::GetModuleHandle(L"wininet.dll"), error, + /*dwLanguageId=*/0, reinterpret_cast(&message_buffer), + /*nSize=*/0, /*Arguments=*/nullptr); + return ScopedLocalString(message_length ? message_buffer : nullptr, + &LocalFree); + } + + // Emits a log message to stderr for the named operation and Windows error + // code. + void LogError(const char* operation, DWORD error) { + ScopedLocalString message = FormatError(error); + fwprintf(stderr, L"%S failed with error %u: %s\n", operation, error, + message ? message.get() : L""); + } + // Invokes the Win32 CloseHandle function on `handle` if it is valid. // Intended for use as a deleter for a std::unique_ptr. void CloseWindowsHandle(void* handle) { @@ -193,37 +215,46 @@ namespace { has_content_length_header = true; claimed_size = wcstol(content_length, NULL, 10); response_body.reserve(claimed_size); + } else { + DWORD error = ::GetLastError(); + if (error != ERROR_HTTP_HEADER_NOT_FOUND) { + LogError("HttpQueryInfo", error); + } } - DWORD bytes_available; DWORD total_read = 0; - BOOL return_code; - - while (((return_code = InternetQueryDataAvailable(request, &bytes_available, - 0, 0)) != 0) && bytes_available > 0) { - vector response_buffer(bytes_available); + while (true) { + DWORD bytes_available; + if (!InternetQueryDataAvailable(request, &bytes_available, 0, 0)) { + LogError("InternetQueryDataAvailable", ::GetLastError()); + return false; + } + if (bytes_available == 0) { + break; + } + // Grow the output to hold the available bytes. + response_body.resize(total_read + bytes_available); DWORD size_read; - - return_code = InternetReadFile(request, - &response_buffer[0], - bytes_available, &size_read); - - if (return_code && size_read > 0) { - total_read += size_read; - response_body.append(&response_buffer[0], size_read); + if (!InternetReadFile(request, &response_body[total_read], + bytes_available, &size_read)) { + LogError("InternetReadFile", ::GetLastError()); + return false; } - else { + if (size_read == 0) { break; } + total_read += size_read; } + // The body may have been over-sized above; shrink to the actual bytes read. + response_body.resize(total_read); - bool succeeded = return_code && (!has_content_length_header || - (total_read == claimed_size)); - if (succeeded && response) { + if (has_content_length_header && (total_read != claimed_size)) { + return false; // The response doesn't match the Content-Length header. + } + if (response) { *response = UTF8ToWide(response_body); } - - return succeeded; + return true; } bool SendRequestInner( @@ -251,8 +282,7 @@ namespace { components.dwUrlPathLength = sizeof(path) / sizeof(path[0]); if (!InternetCrackUrl(url.c_str(), static_cast(url.size()), 0, &components)) { - DWORD err = GetLastError(); - wprintf(L"%d\n", err); + LogError("InternetCrackUrl", ::GetLastError()); return false; } bool secure = false; @@ -269,6 +299,7 @@ namespace { NULL, // proxy bypass 0)); // flags if (!internet.get()) { + LogError("InternetOpen", ::GetLastError()); return false; } @@ -281,6 +312,7 @@ namespace { 0, // flags 0)); // context if (!connection.get()) { + LogError("InternetConnect", ::GetLastError()); return false; } @@ -295,14 +327,17 @@ namespace { http_open_flags, 0)); // context if (!request.get()) { + LogError("HttpOpenRequest", ::GetLastError()); return false; } if (!content_type_header.empty()) { - HttpAddRequestHeaders(request.get(), - content_type_header.c_str(), - static_cast(-1), - HTTP_ADDREQ_FLAG_ADD); + if (!HttpAddRequestHeaders(request.get(), + content_type_header.c_str(), + static_cast(-1), + HTTP_ADDREQ_FLAG_ADD)) { + LogError("HttpAddRequestHeaders", ::GetLastError()); + } } if (timeout_ms) { @@ -310,20 +345,21 @@ namespace { INTERNET_OPTION_SEND_TIMEOUT, timeout_ms, sizeof(*timeout_ms))) { - fwprintf(stderr, L"Could not unset send timeout, continuing...\n"); + LogError("InternetSetOption-send timeout", ::GetLastError()); } if (!InternetSetOption(request.get(), INTERNET_OPTION_RECEIVE_TIMEOUT, timeout_ms, sizeof(*timeout_ms))) { - fwprintf(stderr, L"Could not unset receive timeout, continuing...\n"); + LogError("InternetSetOption-receive timeout", ::GetLastError()); } } if (!HttpSendRequest(request.get(), NULL, 0, const_cast(request_body.data()), static_cast(request_body.size()))) { + LogError("HttpSendRequest", ::GetLastError()); return false; } @@ -333,6 +369,7 @@ namespace { if (!HttpQueryInfo(request.get(), HTTP_QUERY_STATUS_CODE, static_cast(&http_status), &http_status_size, 0)) { + LogError("HttpQueryInfo", ::GetLastError()); return false; } From 5b748cb3a691d0954d9c00b5a02ed866cbc97106 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Mon, 8 Jul 2024 15:31:17 +0200 Subject: [PATCH 42/91] [symupload] Fix malformed Content-Type header SendSimplePostRequest expects a complete message header for Content-Type, not only the value. Change-Id: Ib0b039d1a717c10f74b7e07caa8e4b544dff6cd1 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5682928 Reviewed-by: Ivan Penkov --- src/common/windows/symbol_collector_client.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/windows/symbol_collector_client.cc b/src/common/windows/symbol_collector_client.cc index d91b702b0..9695100a0 100644 --- a/src/common/windows/symbol_collector_client.cc +++ b/src/common/windows/symbol_collector_client.cc @@ -106,7 +106,7 @@ namespace google_breakpad { if (!HTTPUpload::SendSimplePostRequest( url, body, - L"application/json", + L"Content-Type: application/json", timeout_ms, &response, &response_code)) { @@ -176,4 +176,4 @@ namespace google_breakpad { SymbolStatus::Missing; } -} // namespace google_breakpad \ No newline at end of file +} // namespace google_breakpad From 2c5ac8a88e58b294443df92f5be08915da951067 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Mon, 8 Jul 2024 13:19:56 +0200 Subject: [PATCH 43/91] [symupload] Log details to stderr on failure On success, symupload emits details such as the debug identifier. Emit a very similar message to stderr on failure, as this information may also be useful when diagnosing upload failures. Bug: chromium:349736158 Change-Id: Ic3b5316283e4603dca815bd85a2fd51516fbcca8 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5682842 Reviewed-by: Ivan Penkov --- src/tools/windows/symupload/symupload.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/windows/symupload/symupload.cc b/src/tools/windows/symupload/symupload.cc index 46ace95ad..20f48a277 100644 --- a/src/tools/windows/symupload/symupload.cc +++ b/src/tools/windows/symupload/symupload.cc @@ -305,12 +305,12 @@ int wmain(int argc, wchar_t* argv[]) { _wunlink(symbol_file.c_str()); - if (success) { - wprintf(L"Uploaded breakpad symbols for windows-%s/%s/%s (%s %s)\n", - pdb_info.cpu.c_str(), pdb_info.debug_file.c_str(), - pdb_info.debug_identifier.c_str(), code_file.c_str(), - file_version.c_str()); - } + fwprintf(success ? stdout : stderr, + L"%S breakpad symbols for windows-%s/%s/%s (%s %s)\n", + success ? "Uploaded" : "Failed to upload", + pdb_info.cpu.c_str(), pdb_info.debug_file.c_str(), + pdb_info.debug_identifier.c_str(), code_file.c_str(), + file_version.c_str()); return success ? 0 : 1; } From 466cc92bc247862a2c9ad3b0051eab4dd081c355 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Fri, 12 Jul 2024 11:52:20 +0200 Subject: [PATCH 44/91] [symupload] Upload compressed symbol files on Windows When supported at build-time (by defining HAVE_ZLIB and ensuring that zlib.h is in the include path), use zlib to deflate symbol files before uploading. In case of failure (or when not supported), fall-back to uploading the raw data as before. Bug: chromium:349736158 Change-Id: I9345b87e42a03c87a43247e418b5cc05cd19b2b5 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5701147 Reviewed-by: Ivan Penkov --- src/common/windows/http_upload.cc | 69 ++++++++++++++++++++++++++++++- src/common/windows/http_upload.h | 3 +- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/common/windows/http_upload.cc b/src/common/windows/http_upload.cc index 7dd935577..cade22ec8 100644 --- a/src/common/windows/http_upload.cc +++ b/src/common/windows/http_upload.cc @@ -30,11 +30,18 @@ #include // Must come first #endif +#include + #include #include #include +#include #include +#if defined(HAVE_ZLIB) +#include +#endif + // Disable exception handler warnings. #pragma warning(disable:4530) @@ -49,6 +56,56 @@ namespace { using std::ios; using std::unique_ptr; +// Compresses the contents of `data` into `deflated` using the deflate +// algorithm, if supported. Returns true on success, or false if not supported +// or in case of any error. The contents of `deflated` are undefined in the +// latter case. +bool Deflate(const string& data, string& deflated) { +#if defined(HAVE_ZLIB) + z_stream stream{}; + + // Start with an output buffer sufficient for 75% compression to avoid + // reallocations. + deflated.resize(data.size() / 4); + stream.next_in = reinterpret_cast(const_cast(data.data())); + stream.avail_in = data.size(); + stream.next_out = reinterpret_cast(&deflated[0]); + stream.avail_out = deflated.size(); + stream.data_type = Z_TEXT; + + // Z_BEST_SPEED is chosen because, in practice, it offers excellent speed with + // comparable compression for the symbol data typically being uploaded. + // Z_BEST_COMPRESSION: 2151202094 bytes compressed 84.27% in 74.440s. + // Z_DEFAULT_COMPRESSION: 2151202094 bytes compressed 84.08% in 36.016s. + // Z_BEST_SPEED: 2151202094 bytes compressed 80.39% in 13.73s. + int result = deflateInit(&stream, Z_BEST_SPEED); + if (result != Z_OK) { + return false; + } + + while (true) { + result = deflate(&stream, /*flush=*/Z_FINISH); + if (result == Z_STREAM_END) { // All data processed. + deflated.resize(stream.total_out); + break; + } + if (result != Z_OK && result != Z_BUF_ERROR) { + fwprintf(stderr, L"Compression failed with zlib error %d\n", result); + break; // Error condition. + } + // Grow `deflated` by at least 1k to accept the rest of the data. + deflated.resize(deflated.size() + std::max(stream.avail_in, 1024U)); + stream.next_out = reinterpret_cast(&deflated[stream.total_out]); + stream.avail_out = deflated.size() - stream.total_out; + } + deflateEnd(&stream); + + return result == Z_STREAM_END; +#else + return false; +#endif // defined(HAVE_ZLIB) +} + const wchar_t kUserAgent[] = L"Breakpad/1.0 (Windows)"; // Helper class which closes an internet handle when it goes away @@ -490,10 +547,20 @@ namespace google_breakpad { return false; } + static const wchar_t kNoEncoding[] = L""; + static const wchar_t kDeflateEncoding[] = L"Content-Encoding: deflate\r\n"; + const wchar_t* encoding_header = &kNoEncoding[0]; + string compressed_body; + if (Deflate(request_body, compressed_body)) { + request_body.swap(compressed_body); + encoding_header = &kDeflateEncoding[0]; + } // else deflate unsupported or failed; send the raw data. + string().swap(compressed_body); // Free memory. + return SendRequestInner( url, L"PUT", - L"", + encoding_header, request_body, timeout_ms, response_body, diff --git a/src/common/windows/http_upload.h b/src/common/windows/http_upload.h index e117840e9..0fc55e411 100644 --- a/src/common/windows/http_upload.h +++ b/src/common/windows/http_upload.h @@ -51,7 +51,8 @@ using std::map; class HTTPUpload { public: // Sends a PUT request containing the data in |path| to the given - // URL. + // URL. The data is encoded via the deflate algorithm, if support for such + // is available at build-time. // Only HTTP(S) URLs are currently supported. Returns true on success. // If the request is successful and response_body is non-NULL, // the response body will be returned in response_body. From 7f3ccb77337bc9d35b252fcddc4f6a983f80dd6b Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Mon, 8 Jul 2024 11:04:39 +0200 Subject: [PATCH 45/91] [Windows] PDBSourceLineWriter improvements COM calls that return a BSTR via an out param pass ownership of the string's underlying memory to the caller. It is the caller's responsibility to free the memory via SysFreeString. Be sure to use CComBSTR in all such cases, so that this happens upon destruction of the CComBSTR. This CL fixes three BSTR memory leaks. The inline_origins_ member maps an inline origin's name to a unique numerical identifier. Simplify the container by mapping a name only to an id rather than a name to a struct holding the name and id. These origins are printed ordered by id. Rather than using a std::set to create a container sorted by id, leverage the fact that ids are ints that are assigned sequentially to create the reverse mapping in a std::vector. This greatly reduces heap usage, and reduces complexity to O(N). Combined, these changes reduce commit charge by 26% and runtime by 10% when processing chrome.dll for a 32-bit win-dcheck build. Change-Id: Ib8d6540c74622500989f1dc06f705d6846be303f Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5682242 Reviewed-by: Ivan Penkov --- src/common/windows/pdb_source_line_writer.cc | 59 +++++++++++--------- src/common/windows/pdb_source_line_writer.h | 17 ++---- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/src/common/windows/pdb_source_line_writer.cc b/src/common/windows/pdb_source_line_writer.cc index dd80a6d25..86f01a798 100644 --- a/src/common/windows/pdb_source_line_writer.cc +++ b/src/common/windows/pdb_source_line_writer.cc @@ -105,7 +105,7 @@ void MaybeRecordSymbol(DWORD rva, // Take the 'least' symbol by lexicographical order of the decorated name. We // use the decorated rather than undecorated name because computing the latter // is expensive. - BSTR current_name, new_name; + CComBSTR current_name, new_name; loc->second.symbol->get_name(¤t_name); symbol->get_name(&new_name); if (wcscmp(new_name, current_name) < 0) { @@ -479,6 +479,28 @@ bool PDBSourceLineWriter::Open(const wstring& file, FileFormat format) { return true; } +int PDBSourceLineWriter::GetCallsiteInlineOriginId( + CComPtr& callsite) { + wstring name; + { + CComBSTR name_bstr; + callsite->get_name(&name_bstr); + if (name.assign(name_bstr, name_bstr.Length()).empty()) { + name = L""; + } + } + + const int next_id = inline_origins_.size(); + auto iter_inserted = inline_origins_.emplace(std::move(name), next_id); + if (!iter_inserted.second) { + // `name` is already present. Return its previously-assigned unique id. + return iter_inserted.first->second; + } + // `name` was just inserted. Assign it the next id and return this value. + iter_inserted.first->second = next_id; + return next_id; +} + bool PDBSourceLineWriter::GetLine(IDiaLineNumber* dia_line, Line* line) const { if (FAILED(dia_line->get_relativeVirtualAddress(&line->rva))) { fprintf(stderr, "failed to get line rva\n"); @@ -783,17 +805,16 @@ bool PDBSourceLineWriter::PrintFunctions() { } void PDBSourceLineWriter::PrintInlineOrigins() const { - struct OriginCompare { - bool operator()(const InlineOrigin lhs, const InlineOrigin rhs) const { - return lhs.id < rhs.id; - } - }; - set origins; - // Sort by origin id. - for (auto const& origin : inline_origins_) - origins.insert(origin.second); - for (auto o : origins) { - fprintf(output_, "INLINE_ORIGIN %d %ls\n", o.id, o.name.c_str()); + // Inline origins' unique identifiers are assigned sequentially starting from + // zero. Make a reverse-mapping from ids to names, then print the names in + // order of id. + vector names_by_id(inline_origins_.size()); + for (const auto& origin : inline_origins_) { + names_by_id[origin.second] = &origin.first; + } + int id = 0; + for (const wstring* name : names_by_id) { + fprintf(output_, "INLINE_ORIGIN %d %ls\n", id++, name->c_str()); } } @@ -838,19 +859,7 @@ bool PDBSourceLineWriter::GetInlines(IDiaSymbol* block, } dia_line.Release(); } - BSTR name; - callsite->get_name(&name); - if (SysStringLen(name) == 0) { - name = SysAllocString(L""); - } - auto iter = inline_origins_.find(name); - if (iter == inline_origins_.end()) { - InlineOrigin origin; - origin.id = inline_origins_.size(); - origin.name = name; - inline_origins_[name] = origin; - } - new_inline->SetOriginId(inline_origins_[name].id); + new_inline->SetOriginId(GetCallsiteInlineOriginId(callsite)); new_inline->SetCallSiteLine(call_site_line); new_inline->SetCallSiteFileId(file_id); // Go to next level. diff --git a/src/common/windows/pdb_source_line_writer.h b/src/common/windows/pdb_source_line_writer.h index 8c74e2ca3..c4d7c0613 100644 --- a/src/common/windows/pdb_source_line_writer.h +++ b/src/common/windows/pdb_source_line_writer.h @@ -103,15 +103,6 @@ class PDBSourceLineWriter { bool UsesGUID(bool *uses_guid); private: - // InlineOrigin represents INLINE_ORIGIN record in a symbol file. It's an - // inlined function. - struct InlineOrigin { - // The unique id for an InlineOrigin. - int id; - // The name of the inlined function. - wstring name; - }; - // Line represents LINE record in a symbol file. It represents a source code // line. struct Line { @@ -196,6 +187,10 @@ class PDBSourceLineWriter { map line_map_; }; + // Returns the unique id for the inline origin with the same name as the given + // callsite, creating a new id if needed. + int GetCallsiteInlineOriginId(CComPtr& callsite); + // Construct Line from IDiaLineNumber. The output Line is stored at line. // Return true on success. bool GetLine(IDiaLineNumber* dia_line, Line* line) const; @@ -337,8 +332,8 @@ class PDBSourceLineWriter { // This maps unique filenames to file IDs. unordered_map unique_files_; - // The INLINE_ORIGINS records. The key is the function name. - std::map inline_origins_; + // The INLINE_ORIGINS records; inline origin name -> unique id. + std::map inline_origins_; // This is used for calculating post-transform symbol addresses and lengths. ImageMap image_map_; From 0c9811dd5d6d9f544c7a18fdac79b35a5faabcd1 Mon Sep 17 00:00:00 2001 From: Sean Carpenter Date: Wed, 17 Jul 2024 10:44:43 -0700 Subject: [PATCH 46/91] Adds NDS32 Architecture Support to dump_syms NDS32 is a relatively uncommon architecture that is used on a significant chunk of our ChromeOS EC Microprocessors. NDS32 symbol table generation was already supported, but would fail due to "Unrecognized ELF machine architecture". This change fixes that. TEST=dump_syms -a some.nds32.elf BUG=b:328511413 Change-Id: I3e9ae900be483c957a824166d24e2d5db240b64a Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5718928 Reviewed-by: Forest Mittelberg Reviewed-by: Ivan Penkov --- src/common/linux/dump_symbols.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index 5bb434319..55fa98469 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -1118,6 +1118,7 @@ const char* ElfArchitecture(const typename ElfClass::Ehdr* elf_header) { case EM_SPARCV9: return "sparcv9"; case EM_X86_64: return "x86_64"; case EM_RISCV: return "riscv"; + case EM_NDS32: return "nds32"; default: return NULL; } } From 81819541a78c49e9109d2267462775e801f89ce6 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Thu, 18 Jul 2024 09:23:54 +0200 Subject: [PATCH 47/91] [windows] Include-what-you-use fixes in http_upload.{cc,h} Bug: b/353869880 Change-Id: I7dd2d432032099c77410ce67a0fce6c7a71b473f Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5720428 Reviewed-by: Ivan Penkov --- src/common/windows/http_upload.cc | 4 +++- src/common/windows/http_upload.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/common/windows/http_upload.cc b/src/common/windows/http_upload.cc index cade22ec8..22250f502 100644 --- a/src/common/windows/http_upload.cc +++ b/src/common/windows/http_upload.cc @@ -31,6 +31,9 @@ #endif #include +#include +#include +#include #include #include @@ -53,7 +56,6 @@ namespace { using std::string; using std::wstring; using std::map; - using std::ios; using std::unique_ptr; // Compresses the contents of `data` into `deflated` using the deflate diff --git a/src/common/windows/http_upload.h b/src/common/windows/http_upload.h index 0fc55e411..4a2e9bf2f 100644 --- a/src/common/windows/http_upload.h +++ b/src/common/windows/http_upload.h @@ -41,6 +41,7 @@ #include #include +#include namespace google_breakpad { From ee94d7f24bf1ac756c8db20b6d9e052acaa17e0c Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Wed, 24 Jul 2024 13:00:51 +0200 Subject: [PATCH 48/91] [windows] Silence MSVC warning C4100 when building without zlib support Bug: b/354710760 Change-Id: I0a5771795ca456cd07ad26038f005553875df641 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5735099 Reviewed-by: Ivan Penkov Reviewed-by: Ivan Penkov --- src/common/windows/http_upload.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/windows/http_upload.cc b/src/common/windows/http_upload.cc index 22250f502..a2dd87f22 100644 --- a/src/common/windows/http_upload.cc +++ b/src/common/windows/http_upload.cc @@ -104,6 +104,9 @@ bool Deflate(const string& data, string& deflated) { return result == Z_STREAM_END; #else + // Silence MSVC warning C4100 when building without zlib support. + data; + deflated; return false; #endif // defined(HAVE_ZLIB) } From 680014b34edd1b6b631b79e84b4424185a693dde Mon Sep 17 00:00:00 2001 From: Tom Burgin Date: Thu, 25 Jul 2024 16:32:30 -0400 Subject: [PATCH 49/91] upload_system_symbols: break into go packages This will make reusing this code easier. Since there are multiple packages now, the build needs updating. A separate CL in Chromium will follow this change. Change-Id: I8d95d13ea61d32684d0ef845c3d1da2cd6d4cd7f Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5742415 Reviewed-by: Mark Mentovai Reviewed-by: Leonard Grey --- .../{ => arch}/arch_constants.h | 0 .../{ => arch}/arch_reader.go | 6 +++--- .../{ => archive}/extract.go | 2 +- .../upload_system_symbols.go | 19 ++++++++++++------- 4 files changed, 16 insertions(+), 11 deletions(-) rename src/tools/mac/upload_system_symbols/{ => arch}/arch_constants.h (100%) rename src/tools/mac/upload_system_symbols/{ => arch}/arch_reader.go (94%) rename src/tools/mac/upload_system_symbols/{ => archive}/extract.go (99%) diff --git a/src/tools/mac/upload_system_symbols/arch_constants.h b/src/tools/mac/upload_system_symbols/arch/arch_constants.h similarity index 100% rename from src/tools/mac/upload_system_symbols/arch_constants.h rename to src/tools/mac/upload_system_symbols/arch/arch_constants.h diff --git a/src/tools/mac/upload_system_symbols/arch_reader.go b/src/tools/mac/upload_system_symbols/arch/arch_reader.go similarity index 94% rename from src/tools/mac/upload_system_symbols/arch_reader.go rename to src/tools/mac/upload_system_symbols/arch/arch_reader.go index 03a764215..6553c8ba1 100644 --- a/src/tools/mac/upload_system_symbols/arch_reader.go +++ b/src/tools/mac/upload_system_symbols/arch/arch_reader.go @@ -27,7 +27,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package main +package arch import ( "debug/macho" @@ -38,10 +38,10 @@ import ( */ import "C" -// getArchStringFromHeader takes a MachO FileHeader and returns a string that +// GetArchStringFromHeader takes a MachO FileHeader and returns a string that // represents the CPU type and subtype. // This function is a Go version of src/common/mac/arch_utilities.cc:BreakpadGetArchInfoFromCpuType(). -func getArchStringFromHeader(header macho.FileHeader) string { +func GetArchStringFromHeader(header macho.FileHeader) string { // TODO(rsesek): As of 10.9.4, OS X doesn't list these in /usr/include/mach/machine.h. if header.Cpu == C.kCPU_TYPE_ARM64 && header.SubCpu == C.kCPU_SUBTYPE_ARM64_ALL { return "arm64" diff --git a/src/tools/mac/upload_system_symbols/extract.go b/src/tools/mac/upload_system_symbols/archive/extract.go similarity index 99% rename from src/tools/mac/upload_system_symbols/extract.go rename to src/tools/mac/upload_system_symbols/archive/extract.go index f991e3aa8..f5df10492 100644 --- a/src/tools/mac/upload_system_symbols/extract.go +++ b/src/tools/mac/upload_system_symbols/archive/extract.go @@ -1,4 +1,4 @@ -package main +package archive // #cgo LDFLAGS: -lParallelCompression // #include diff --git a/src/tools/mac/upload_system_symbols/upload_system_symbols.go b/src/tools/mac/upload_system_symbols/upload_system_symbols.go index b7b3cb556..8b0cb46f9 100644 --- a/src/tools/mac/upload_system_symbols/upload_system_symbols.go +++ b/src/tools/mac/upload_system_symbols/upload_system_symbols.go @@ -55,6 +55,9 @@ import ( "strings" "sync" "time" + + "upload_system_symbols/arch" + "upload_system_symbols/archive" ) var ( @@ -179,7 +182,7 @@ func getSystemRoots(tempDir string) []string { if hasIPSW || hasRoot { log.Fatalf("--installer, --ipsw, and --system-root are mutually exclusive") } - if rs, err := extractSystems(Installer, *installer, tempDir); err != nil { + if rs, err := extractSystems(archive.Installer, *installer, tempDir); err != nil { log.Fatalf("Couldn't extract installer at %s: %v", *installer, err) } else { return rs @@ -188,7 +191,7 @@ func getSystemRoots(tempDir string) []string { if hasRoot { log.Fatalf("--installer, --ipsw, and --system-root are mutually exclusive") } - if rs, err := extractSystems(IPSW, *ipsw, tempDir); err != nil { + if rs, err := extractSystems(archive.IPSW, *ipsw, tempDir); err != nil { log.Fatalf("Couldn't extract IPSW at %s: %v", *ipsw, err) } else { return rs @@ -506,11 +509,13 @@ func (fq *findQueue) worker() { } func (fq *findQueue) dumpMachOFile(fp string, image *macho.File) { - if image.Type != MachODylib && image.Type != MachOBundle && image.Type != MachODylinker { + if image.Type != arch.MachODylib && + image.Type != arch.MachOBundle && + image.Type != arch.MachODylinker { return } - arch := getArchStringFromHeader(image.FileHeader) + arch := arch.GetArchStringFromHeader(image.FileHeader) if arch == "" { // Don't know about this architecture type. return @@ -521,14 +526,14 @@ func (fq *findQueue) dumpMachOFile(fp string, image *macho.File) { } } -// extractSystems extracts any dyld shared caches from `archive`, then extracts the caches +// extractSystems extracts any dyld shared caches from `archivePath`, then extracts the caches // into macOS system libraries, returning the locations on disk of any systems extracted. -func extractSystems(format ArchiveFormat, archive string, extractPath string) ([]string, error) { +func extractSystems(format archive.ArchiveFormat, archivePath string, extractPath string) ([]string, error) { cachesPath := path.Join(extractPath, "caches") if err := os.MkdirAll(cachesPath, 0755); err != nil { return nil, err } - if err := ExtractCaches(format, archive, cachesPath, true); err != nil { + if err := archive.ExtractCaches(format, archivePath, cachesPath, true); err != nil { return nil, err } files, err := os.ReadDir(cachesPath) From 1420017c7f9fb910a9ae878d7bf5a6423fba3c59 Mon Sep 17 00:00:00 2001 From: Tom Burgin Date: Fri, 26 Jul 2024 16:25:34 +0000 Subject: [PATCH 50/91] Revert "[windows] Silence MSVC warning C4100 when building without zlib support" This reverts commit ee94d7f24bf1ac756c8db20b6d9e052acaa17e0c. Reason for revert: Breaks Windows builds of Chromium. https://ci.chromium.org/ui/p/chromium/builders/try/win-rel/695756/overview Original change's description: > [windows] Silence MSVC warning C4100 when building without zlib support > > Bug: b/354710760 > Change-Id: I0a5771795ca456cd07ad26038f005553875df641 > Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5735099 > Reviewed-by: Ivan Penkov > Reviewed-by: Ivan Penkov Bug: b/354710760 Change-Id: Ib49e06944934d467beaefb91411235eed020381a No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5742385 Reviewed-by: Ivan Penkov --- src/common/windows/http_upload.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/common/windows/http_upload.cc b/src/common/windows/http_upload.cc index a2dd87f22..22250f502 100644 --- a/src/common/windows/http_upload.cc +++ b/src/common/windows/http_upload.cc @@ -104,9 +104,6 @@ bool Deflate(const string& data, string& deflated) { return result == Z_STREAM_END; #else - // Silence MSVC warning C4100 when building without zlib support. - data; - deflated; return false; #endif // defined(HAVE_ZLIB) } From eb6b3f89fd6261353797f52f2cd43346b1d724cf Mon Sep 17 00:00:00 2001 From: Sean Carpenter Date: Sun, 28 Jul 2024 21:11:20 -0700 Subject: [PATCH 51/91] Adds Support for EC Zephyr Binaries The text section header for EC Zephyr binaries is `text` instead of the standard `.text`. As a result the file_id hash function was failing when attempting to generate a file id by hashing the contents of a Zephyr binaries `text` section. This change adds support for Zephyr binaries by having said hash function also check the `text` section in addition to `.text`. Test output: https://paste.googleplex.com/4708788542373888#l=20 Three tests are listed as failing in the test output. This is a known unrelated issue caused by this commit: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5636127 TEST=make check && dump_syms -a ~/some.zephyr.elf BUG=b:328511413 Change-Id: I88882305a4c9ca18082ba2690ba1b22da03bd19d Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5732693 Reviewed-by: Forest Mittelberg Reviewed-by: Joshua Peraza --- src/common/linux/file_id.cc | 6 ++++-- src/common/linux/file_id_unittest.cc | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/common/linux/file_id.cc b/src/common/linux/file_id.cc index 296531608..83e72c40f 100644 --- a/src/common/linux/file_id.cc +++ b/src/common/linux/file_id.cc @@ -128,8 +128,10 @@ static bool HashElfTextSection(const void* elf_mapped_base, void* text_section; size_t text_size; - if (!FindElfSection(elf_mapped_base, ".text", SHT_PROGBITS, - (const void**)&text_section, &text_size) || + if ((!FindElfSection(elf_mapped_base, ".text", SHT_PROGBITS, + (const void**)&text_section, &text_size) && + !FindElfSection(elf_mapped_base, "text", SHT_PROGBITS, + (const void**)&text_section, &text_size)) || text_size == 0) { return false; } diff --git a/src/common/linux/file_id_unittest.cc b/src/common/linux/file_id_unittest.cc index 7be239f60..9de57c123 100644 --- a/src/common/linux/file_id_unittest.cc +++ b/src/common/linux/file_id_unittest.cc @@ -176,6 +176,31 @@ TYPED_TEST(FileIDTest, ElfClass) { EXPECT_EQ(expected_identifier_string, identifier_string); } +TYPED_TEST(FileIDTest, ZephyrTextSection) { + const char expected_identifier_string[] = + "80808080808000000000008080808080"; + const size_t kTextSectionSize = 128; + + ELF elf(EM_386, TypeParam::kClass, kLittleEndian); + Section text(kLittleEndian); + for (size_t i = 0; i < kTextSectionSize; ++i) { + text.D8(i * 3); + } + // Some binaries, namely Zephyr firmware binaries (https://www.zephyrproject.org/), + // refer to the `.text` section as `text`. They are logically identical however + // and should be handled the same. + elf.AddSection("text", text, SHT_PROGBITS); + elf.Finish(); + this->GetElfContents(elf); + + id_vector identifier(this->make_vector()); + EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, + identifier)); + + string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier); + EXPECT_EQ(expected_identifier_string, identifier_string); +} + TYPED_TEST(FileIDTest, BuildID) { const uint8_t kExpectedIdentifierBytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, From 6b0c5b7ee1988a14a4af94564e8ae8bba8a94374 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Thu, 8 Aug 2024 15:15:00 +0200 Subject: [PATCH 52/91] [windows] Silence MSVC warning C4100 when building without zlib support Also correct the indentation of the Deflate function to match the surrounding code. Bug: b/354710760 Change-Id: I17e64b2f6390f673169a783e63505eb9df233a79 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5771532 Reviewed-by: Joshua Peraza --- src/common/windows/http_upload.cc | 93 +++++++++++++++++-------------- 1 file changed, 50 insertions(+), 43 deletions(-) diff --git a/src/common/windows/http_upload.cc b/src/common/windows/http_upload.cc index 22250f502..c6d00bd0b 100644 --- a/src/common/windows/http_upload.cc +++ b/src/common/windows/http_upload.cc @@ -58,55 +58,62 @@ namespace { using std::map; using std::unique_ptr; -// Compresses the contents of `data` into `deflated` using the deflate -// algorithm, if supported. Returns true on success, or false if not supported -// or in case of any error. The contents of `deflated` are undefined in the -// latter case. -bool Deflate(const string& data, string& deflated) { +// Silence warning C4100, which may strike when building without zlib support. +#pragma warning(push) +#pragma warning(disable:4100) + + // Compresses the contents of `data` into `deflated` using the deflate + // algorithm, if supported. Returns true on success, or false if not supported + // or in case of any error. The contents of `deflated` are undefined in the + // latter case. + bool Deflate(const string& data, string& deflated) { #if defined(HAVE_ZLIB) - z_stream stream{}; - - // Start with an output buffer sufficient for 75% compression to avoid - // reallocations. - deflated.resize(data.size() / 4); - stream.next_in = reinterpret_cast(const_cast(data.data())); - stream.avail_in = data.size(); - stream.next_out = reinterpret_cast(&deflated[0]); - stream.avail_out = deflated.size(); - stream.data_type = Z_TEXT; - - // Z_BEST_SPEED is chosen because, in practice, it offers excellent speed with - // comparable compression for the symbol data typically being uploaded. - // Z_BEST_COMPRESSION: 2151202094 bytes compressed 84.27% in 74.440s. - // Z_DEFAULT_COMPRESSION: 2151202094 bytes compressed 84.08% in 36.016s. - // Z_BEST_SPEED: 2151202094 bytes compressed 80.39% in 13.73s. - int result = deflateInit(&stream, Z_BEST_SPEED); - if (result != Z_OK) { - return false; - } - - while (true) { - result = deflate(&stream, /*flush=*/Z_FINISH); - if (result == Z_STREAM_END) { // All data processed. - deflated.resize(stream.total_out); - break; + z_stream stream{}; + + // Start with an output buffer sufficient for 75% compression to avoid + // reallocations. + deflated.resize(data.size() / 4); + stream.next_in = reinterpret_cast(const_cast(data.data())); + stream.avail_in = data.size(); + stream.next_out = reinterpret_cast(&deflated[0]); + stream.avail_out = deflated.size(); + stream.data_type = Z_TEXT; + + // Z_BEST_SPEED is chosen because, in practice, it offers excellent speed + // with comparable compression for the symbol data typically being uploaded. + // Z_BEST_COMPRESSION: 2151202094 bytes compressed 84.27% in 74.440s. + // Z_DEFAULT_COMPRESSION: 2151202094 bytes compressed 84.08% in 36.016s. + // Z_BEST_SPEED: 2151202094 bytes compressed 80.39% in 13.73s. + int result = deflateInit(&stream, Z_BEST_SPEED); + if (result != Z_OK) { + return false; } - if (result != Z_OK && result != Z_BUF_ERROR) { - fwprintf(stderr, L"Compression failed with zlib error %d\n", result); - break; // Error condition. + + while (true) { + result = deflate(&stream, /*flush=*/Z_FINISH); + if (result == Z_STREAM_END) { // All data processed. + deflated.resize(stream.total_out); + break; + } + if (result != Z_OK && result != Z_BUF_ERROR) { + fwprintf(stderr, L"Compression failed with zlib error %d\n", result); + break; // Error condition. + } + // Grow `deflated` by at least 1k to accept the rest of the data. + deflated.resize(deflated.size() + std::max(stream.avail_in, 1024U)); + stream.next_out = reinterpret_cast(&deflated[stream.total_out]); + stream.avail_out = deflated.size() - stream.total_out; } - // Grow `deflated` by at least 1k to accept the rest of the data. - deflated.resize(deflated.size() + std::max(stream.avail_in, 1024U)); - stream.next_out = reinterpret_cast(&deflated[stream.total_out]); - stream.avail_out = deflated.size() - stream.total_out; - } - deflateEnd(&stream); + deflateEnd(&stream); - return result == Z_STREAM_END; + return result == Z_STREAM_END; #else - return false; + return false; #endif // defined(HAVE_ZLIB) -} + } + +// Restore C4100 to its previous state. +#pragma warning(pop) const wchar_t kUserAgent[] = L"Breakpad/1.0 (Windows)"; From 8668fcea0edb5fe5cf7d8562cee02e87486eb3c9 Mon Sep 17 00:00:00 2001 From: abrook Date: Wed, 4 Sep 2024 14:41:24 -0400 Subject: [PATCH 53/91] Fix bugs with alternative section naming on mac, and unpropagated section information. Change-Id: I6f4e112a83aeee1e4cd525c1d1d0b9213ef2d09b Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5838157 Reviewed-by: Joshua Peraza --- src/common/dwarf/dwarf2reader.cc | 5 +++++ src/common/mac/dump_syms.cc | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc index 3cae1a8e8..3d85840cc 100644 --- a/src/common/dwarf/dwarf2reader.cc +++ b/src/common/dwarf/dwarf2reader.cc @@ -67,6 +67,11 @@ const SectionMap::const_iterator GetSectionByName(const SectionMap& std::string macho_name("__"); macho_name += name + 1; iter = sections.find(macho_name); + + // .debug_str_offsets is alternatively named .debug_str_offs, so try both + if (iter == sections.end() && std::string(name) == ".debug_str_offsets") { + return GetSectionByName(sections, ".debug_str_offs"); + } return iter; } diff --git a/src/common/mac/dump_syms.cc b/src/common/mac/dump_syms.cc index 3d3413a2b..19c1bce1e 100644 --- a/src/common/mac/dump_syms.cc +++ b/src/common/mac/dump_syms.cc @@ -354,8 +354,9 @@ class DumpSymbols::DumperLineToModule: vector* lines, std::map* files) { DwarfLineToModule handler(module, compilation_dir_, lines, files); - LineInfo parser(program, length, byte_reader_, nullptr, 0, - nullptr, 0, &handler); + LineInfo parser(program, length, byte_reader_, string_section, + string_section_length, line_string_section, + line_string_section_length, &handler); parser.Start(); } private: From e92bea30759edbae08205bccd14dc25bf1806f93 Mon Sep 17 00:00:00 2001 From: Liryna Date: Wed, 4 Sep 2024 15:42:44 -0400 Subject: [PATCH 54/91] [windows] dump_syms - Support ARM64 PDB Change-Id: I6a9cb5c5253abcd34cb72a035d280b7fd8a50372 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5836085 Reviewed-by: Nelson Billing --- src/common/windows/pdb_source_line_writer.cc | 2 +- src/common/windows/pe_util.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/common/windows/pdb_source_line_writer.cc b/src/common/windows/pdb_source_line_writer.cc index 86f01a798..584b0a5a7 100644 --- a/src/common/windows/pdb_source_line_writer.cc +++ b/src/common/windows/pdb_source_line_writer.cc @@ -1050,7 +1050,7 @@ bool PDBSourceLineWriter::PrintFrameDataUsingEXE() { bool PDBSourceLineWriter::PrintFrameData() { PDBModuleInfo info; - if (GetModuleInfo(&info) && info.cpu == L"x86_64") { + if (GetModuleInfo(&info) && (info.cpu == L"x86_64" || info.cpu == L"arm64")) { return PrintFrameDataUsingEXE(); } return PrintFrameDataUsingPDB(); diff --git a/src/common/windows/pe_util.h b/src/common/windows/pe_util.h index 6c6b364f9..d8ffb0fba 100644 --- a/src/common/windows/pe_util.h +++ b/src/common/windows/pe_util.h @@ -68,6 +68,9 @@ constexpr const wchar_t* FileHeaderMachineToCpuString(WORD machine) { case IMAGE_FILE_MACHINE_AMD64: { return L"x86_64"; } + case IMAGE_FILE_MACHINE_ARM64: { + return L"arm64"; + } default: { return L"unknown"; } } } From 1cbd9ebb22099250dae86ca31ba0f7e91e19ad09 Mon Sep 17 00:00:00 2001 From: Takuto Ikuta Date: Mon, 28 Oct 2024 16:25:09 +0900 Subject: [PATCH 55/91] dwarf: fix missing include for exit() Bug: 375980422 Change-Id: I7f55c5ed74781becfaec0d79998676e9a984ffc5 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5970061 Reviewed-by: Lei Zhang --- src/common/dwarf/dwarf2reader.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc index 3d85840cc..7efb7d8b5 100644 --- a/src/common/dwarf/dwarf2reader.cc +++ b/src/common/dwarf/dwarf2reader.cc @@ -40,6 +40,7 @@ #include #include #include +#include #include #include From a70e77ea35a768a84078462c008c3f70e64d867e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rulong=20Chen=EF=BC=88=E9=99=88=E6=B1=9D=E9=BE=99=EF=BC=89?= Date: Tue, 29 Oct 2024 17:33:58 +0800 Subject: [PATCH 56/91] Print additional argument that describes the crash Bug: none Change-Id: I94b1585d78387dc93efdaba2fa52eb71725a644e Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5974621 Reviewed-by: Ivan Penkov Reviewed-by: Ivan Penkov --- src/processor/stackwalk_common.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/processor/stackwalk_common.cc b/src/processor/stackwalk_common.cc index 688b27823..a46bd04bc 100644 --- a/src/processor/stackwalk_common.cc +++ b/src/processor/stackwalk_common.cc @@ -1156,6 +1156,15 @@ void PrintProcessState(const ProcessState& process_state, if (process_state.crashed()) { printf("Crash reason: %s\n", process_state.crash_reason().c_str()); printf("Crash address: 0x%" PRIx64 "\n", process_state.crash_address()); + const std::vector* exception_param_vec = + process_state.exception_record()->parameters(); + if (exception_param_vec->size() > 0) { + printf("Crash parameters:\n"); + for (const auto& param : *exception_param_vec) { + printf(" value: %" PRIu64 "\tdescription: %s\n", param.value(), + param.description()); + } + } } else { printf("No crash\n"); } From f8d05a9d0709ab0ec78582d220a939f8ceb41891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rulong=20Chen=EF=BC=88=E9=99=88=E6=B1=9D=E9=BE=99=EF=BC=89?= Date: Wed, 30 Oct 2024 09:24:46 +0800 Subject: [PATCH 57/91] Fix the compilation error Bug: none Change-Id: I823fe99720eb0bc22f08457e78766500b7bc82ad Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5975023 Reviewed-by: Ivan Penkov --- src/processor/stackwalk_common.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/processor/stackwalk_common.cc b/src/processor/stackwalk_common.cc index a46bd04bc..72fceecdc 100644 --- a/src/processor/stackwalk_common.cc +++ b/src/processor/stackwalk_common.cc @@ -1162,7 +1162,7 @@ void PrintProcessState(const ProcessState& process_state, printf("Crash parameters:\n"); for (const auto& param : *exception_param_vec) { printf(" value: %" PRIu64 "\tdescription: %s\n", param.value(), - param.description()); + param.description().c_str()); } } } else { From 47f7823bdf4b1f39e462b2a497a674860e922e38 Mon Sep 17 00:00:00 2001 From: Nelson Billing Date: Wed, 30 Oct 2024 20:50:12 +0000 Subject: [PATCH 58/91] Revert "[windows] dump_syms - Support ARM64 PDB" This reverts commit e92bea30759edbae08205bccd14dc25bf1806f93. Reason for revert: Causing crashes in symupload.exe for arm64 binaries. Original change's description: > [windows] dump_syms - Support ARM64 PDB > > Change-Id: I6a9cb5c5253abcd34cb72a035d280b7fd8a50372 > Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5836085 > Reviewed-by: Nelson Billing Change-Id: I32c96088213c1196f506580dbcb0b79dae945398 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5980968 Reviewed-by: Will Harris --- src/common/windows/pdb_source_line_writer.cc | 2 +- src/common/windows/pe_util.h | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/common/windows/pdb_source_line_writer.cc b/src/common/windows/pdb_source_line_writer.cc index 584b0a5a7..86f01a798 100644 --- a/src/common/windows/pdb_source_line_writer.cc +++ b/src/common/windows/pdb_source_line_writer.cc @@ -1050,7 +1050,7 @@ bool PDBSourceLineWriter::PrintFrameDataUsingEXE() { bool PDBSourceLineWriter::PrintFrameData() { PDBModuleInfo info; - if (GetModuleInfo(&info) && (info.cpu == L"x86_64" || info.cpu == L"arm64")) { + if (GetModuleInfo(&info) && info.cpu == L"x86_64") { return PrintFrameDataUsingEXE(); } return PrintFrameDataUsingPDB(); diff --git a/src/common/windows/pe_util.h b/src/common/windows/pe_util.h index d8ffb0fba..6c6b364f9 100644 --- a/src/common/windows/pe_util.h +++ b/src/common/windows/pe_util.h @@ -68,9 +68,6 @@ constexpr const wchar_t* FileHeaderMachineToCpuString(WORD machine) { case IMAGE_FILE_MACHINE_AMD64: { return L"x86_64"; } - case IMAGE_FILE_MACHINE_ARM64: { - return L"arm64"; - } default: { return L"unknown"; } } } From c6ec7108ee82ce21f0c0b1d733d4817583b91743 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Wed, 13 Nov 2024 11:14:11 -0500 Subject: [PATCH 59/91] win: include stdlib.h for mbstowcs_s, wcstombs_s This used to come in transitively via , but upstream libc++ cleaned up its a bit and this is no longer true with new libc++ versions. No behavior change. Bug: chromium:376278210 Change-Id: I658f500cfd0e3a33c260d34302557b3ceb2799ca Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5994352 Reviewed-by: Mark Mentovai --- src/common/windows/string_utils.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/windows/string_utils.cc b/src/common/windows/string_utils.cc index 1e570b525..956ee9906 100644 --- a/src/common/windows/string_utils.cc +++ b/src/common/windows/string_utils.cc @@ -30,6 +30,8 @@ #include // Must come first #endif +#include + #include #include From 1db382f0dabe2d17f49956066286e4bf15482b5a Mon Sep 17 00:00:00 2001 From: Mark Mentovai Date: Thu, 14 Nov 2024 10:40:24 -0500 Subject: [PATCH 60/91] Fix #includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. #include in preference to 2. In affected files, sort #includes according to modern practice 3. Where #include order changes resulted in compile errors in other code, adhere to the principle of “include what you use” Step 1 was achieved by the following snippet, plus manual inspection and modification to move headers to the proper sections. ``` for f in $(git grep -l '^#(include|import) '); do sed -E -i '' \ -e 's/^#(include|import) /#include <\2.h>/' \ "$f" done ``` Step 2 is achieved by the manual inspection and modification, followed by `git cl format`. Step 3 is manual, based on the results of a test build. Change-Id: I7e43a7a534fab54b6c1d47e442a3573f28996151 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6023410 Reviewed-by: Joshua Peraza --- .../linux/handler/minidump_descriptor.h | 2 +- src/client/linux/minidump_writer/pe_structs.h | 4 ++-- src/client/mac/crash_generation/Inspector.mm | 16 +++++-------- src/client/mac/handler/minidump_generator.cc | 20 +++++++--------- .../solaris/handler/exception_handler.cc | 10 ++++---- .../solaris/handler/exception_handler_test.cc | 12 +++++----- .../solaris/handler/minidump_generator.cc | 24 +++++++++---------- src/client/solaris/handler/solaris_lwp.cc | 13 +++++----- .../crash_generation_client.cc | 5 +++- .../crash_generation_server.cc | 7 ++++-- .../windows/handler/exception_handler.cc | 10 ++++---- src/common/solaris/file_id.cc | 11 ++++----- src/common/solaris/guid_creator.cc | 7 +++--- src/common/string_view.h | 8 +++++-- src/common/windows/omap.cc | 2 +- src/common/windows/string_utils.cc | 6 ++--- src/common/windows/sym_upload_v2_protocol.cc | 2 +- src/google_breakpad/processor/call_stack.h | 3 ++- src/processor/exploitability.cc | 2 +- src/processor/fast_source_line_resolver.cc | 7 +++--- .../fast_source_line_resolver_types.h | 3 ++- src/processor/map_serializers_unittest.cc | 9 +++---- src/processor/minidump.cc | 5 ++-- src/processor/minidump_processor.cc | 4 ++-- src/processor/module_serializer.cc | 5 ++-- src/processor/module_serializer.h | 3 ++- src/processor/simple_serializer-inl.h | 3 ++- src/processor/stackwalker_arm64.cc | 6 +++-- src/processor/stackwalker_arm64.h | 1 + src/processor/static_address_map_unittest.cc | 10 ++++---- .../static_contained_range_map_unittest.cc | 6 +++-- src/processor/static_map_unittest.cc | 9 +++---- src/tools/linux/dump_syms/dump_syms.cc | 2 +- src/tools/solaris/dump_syms/dump_syms.cc | 7 +++--- .../converter/ms_symbol_server_converter.cc | 9 +++---- src/tools/windows/converter_exe/converter.cc | 7 +++--- src/tools/windows/symupload/symupload.cc | 6 ++--- 37 files changed, 143 insertions(+), 123 deletions(-) diff --git a/src/client/linux/handler/minidump_descriptor.h b/src/client/linux/handler/minidump_descriptor.h index d822c9d92..1fbcaccfd 100644 --- a/src/client/linux/handler/minidump_descriptor.h +++ b/src/client/linux/handler/minidump_descriptor.h @@ -30,9 +30,9 @@ #define CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_ #include +#include #include -#include #include #include "client/linux/handler/microdump_extra_info.h" diff --git a/src/client/linux/minidump_writer/pe_structs.h b/src/client/linux/minidump_writer/pe_structs.h index 122cc2956..017ac0619 100644 --- a/src/client/linux/minidump_writer/pe_structs.h +++ b/src/client/linux/minidump_writer/pe_structs.h @@ -29,7 +29,7 @@ #ifndef CLIENT_LINUX_MINIDUMP_WRITER_PE_STRUCTS_H_ #define CLIENT_LINUX_MINIDUMP_WRITER_PE_STRUCTS_H_ -#include +#include namespace google_breakpad { @@ -222,4 +222,4 @@ typedef struct _RSDS_DEBUG_FORMAT { } // namespace google_breakpad -#endif // CLIENT_LINUX_MINIDUMP_WRITER_PE_STRUCTS_H_ \ No newline at end of file +#endif // CLIENT_LINUX_MINIDUMP_WRITER_PE_STRUCTS_H_ diff --git a/src/client/mac/crash_generation/Inspector.mm b/src/client/mac/crash_generation/Inspector.mm index 8d4e3e98b..4c0a78062 100644 --- a/src/client/mac/crash_generation/Inspector.mm +++ b/src/client/mac/crash_generation/Inspector.mm @@ -28,26 +28,23 @@ // // Utility that can inspect another process and write a crash dump -#include -#include +#import "client/mac/crash_generation/Inspector.h" + +#import #include #include #include -#include -#import "client/mac/crash_generation/Inspector.h" +#include +#include +#import "GTMDefines.h" #import "client/mac/Framework/Breakpad.h" #import "client/mac/handler/minidump_generator.h" - #import "common/mac/MachIPC.h" #include "common/mac/bootstrap_compat.h" #include "common/mac/launch_reporter.h" -#import "GTMDefines.h" - -#import - namespace google_breakpad { //============================================================================= @@ -358,4 +355,3 @@ } } // namespace google_breakpad - diff --git a/src/client/mac/handler/minidump_generator.cc b/src/client/mac/handler/minidump_generator.cc index fd863aea9..f30742160 100644 --- a/src/client/mac/handler/minidump_generator.cc +++ b/src/client/mac/handler/minidump_generator.cc @@ -30,20 +30,19 @@ #include // Must come first #endif -#include -#include +#include "client/mac/handler/minidump_generator.h" +#include +#include +#include #include #include #include -#include -#include -#include +#include #include +#include -#include - -#include "client/mac/handler/minidump_generator.h" +#include #if defined(HAS_ARM_SUPPORT) || defined(HAS_ARM64_SUPPORT) #include @@ -1071,9 +1070,8 @@ bool MinidumpGenerator::WriteMemoryListStream( ip_memory_d.start_of_memory_range = std::max(uintptr_t(addr), uintptr_t(ip - (kIPMemorySize / 2))); - uintptr_t end_of_range = - std::min(uintptr_t(ip + (kIPMemorySize / 2)), - uintptr_t(addr + size)); + uintptr_t end_of_range = std::min(uintptr_t(ip + (kIPMemorySize / 2)), + uintptr_t(addr + size)); uintptr_t range_diff = end_of_range - static_cast(ip_memory_d.start_of_memory_range); ip_memory_d.memory.data_size = static_cast(range_diff); diff --git a/src/client/solaris/handler/exception_handler.cc b/src/client/solaris/handler/exception_handler.cc index 0e5f44976..e3688581a 100644 --- a/src/client/solaris/handler/exception_handler.cc +++ b/src/client/solaris/handler/exception_handler.cc @@ -32,16 +32,16 @@ #include // Must come first #endif +#include "client/solaris/handler/exception_handler.h" + +#include #include +#include #include #include +#include #include -#include -#include -#include - -#include "client/solaris/handler/exception_handler.h" #include "common/solaris/guid_creator.h" #include "common/solaris/message_output.h" #include "google_breakpad/common/minidump_format.h" diff --git a/src/client/solaris/handler/exception_handler_test.cc b/src/client/solaris/handler/exception_handler_test.cc index 3d656820d..56ef94dd0 100644 --- a/src/client/solaris/handler/exception_handler_test.cc +++ b/src/client/solaris/handler/exception_handler_test.cc @@ -32,15 +32,15 @@ #include // Must come first #endif +#include "client/solaris/handler/exception_handler.h" + +#include #include +#include +#include +#include #include -#include -#include -#include -#include - -#include "client/solaris/handler/exception_handler.h" #include "client/solaris/handler/solaris_lwp.h" using namespace google_breakpad; diff --git a/src/client/solaris/handler/minidump_generator.cc b/src/client/solaris/handler/minidump_generator.cc index 5d24d0ae8..f9e1adfc6 100644 --- a/src/client/solaris/handler/minidump_generator.cc +++ b/src/client/solaris/handler/minidump_generator.cc @@ -32,18 +32,18 @@ #include // Must come first #endif +#include "client/solaris/handler/minidump_generator.h" + #include +#include #include #include #include #include #include +#include #include -#include -#include - -#include "client/solaris/handler/minidump_generator.h" #include "client/minidump_file_writer-inl.h" #include "common/solaris/file_id.h" @@ -337,7 +337,7 @@ bool WriteCPUInformation(MDRawSystemInfo* sys_info) { build = strchr(uts.version, '_'); ++build; sys_info->build_number = atoi(build); - + return true; } @@ -596,8 +596,8 @@ bool WriteExceptionStream(MinidumpFileWriter* minidump_writer, #if TARGET_CPU_SPARC if (writer_args->sig_ctx != NULL) { - exception.get()->exception_record.exception_address = - writer_args->sig_ctx->uc_mcontext.gregs[REG_PC]; + exception.get()->exception_record.exception_address = + writer_args->sig_ctx->uc_mcontext.gregs[REG_PC]; } else { return true; } @@ -700,14 +700,14 @@ void* Write(void* argument) { if (writer_args->sighandler_ebp != 0 && writer_args->lwp_lister->FindSigContext(writer_args->sighandler_ebp, &writer_args->sig_ctx)) { - writer_args->crashed_stack_bottom = - writer_args->lwp_lister->GetLwpStackBottom( + writer_args->crashed_stack_bottom = + writer_args->lwp_lister->GetLwpStackBottom( #if TARGET_CPU_SPARC - writer_args->sig_ctx->uc_mcontext.gregs[REG_O6] + writer_args->sig_ctx->uc_mcontext.gregs[REG_O6] #elif TARGET_CPU_X86 - writer_args->sig_ctx->uc_mcontext.gregs[UESP] + writer_args->sig_ctx->uc_mcontext.gregs[UESP] #endif - ); + ); int crashed_lwpid = FindCrashingLwp(writer_args->crashed_stack_bottom, writer_args->requester_pid, diff --git a/src/client/solaris/handler/solaris_lwp.cc b/src/client/solaris/handler/solaris_lwp.cc index 02f1c37e8..fec9e3f3e 100644 --- a/src/client/solaris/handler/solaris_lwp.cc +++ b/src/client/solaris/handler/solaris_lwp.cc @@ -32,11 +32,16 @@ #include // Must come first #endif +#include "client/solaris/handler/solaris_lwp.h" + +#include #include #include #include #include #include +#include +#include #include #include #include @@ -44,12 +49,8 @@ #include #include -#include -#include -#include #include -#include "client/solaris/handler/solaris_lwp.h" #include "common/solaris/message_output.h" using namespace google_breakpad; @@ -320,7 +321,7 @@ int SolarisLwp::ListModules( return -1; /* - * Determine number of mappings, this value must be + * Determine number of mappings, this value must be * larger than the actual module count */ size = status.st_size; @@ -337,7 +338,7 @@ int SolarisLwp::ListModules( prmap_t* _maps; int _num; int module_count = 0; - + /* * Scan each mapping - note it is assummed that the mappings are * presented in order. We fill holes between mappings. On intel diff --git a/src/client/windows/crash_generation/crash_generation_client.cc b/src/client/windows/crash_generation/crash_generation_client.cc index c3d6a2bc8..653fafdc2 100644 --- a/src/client/windows/crash_generation/crash_generation_client.cc +++ b/src/client/windows/crash_generation/crash_generation_client.cc @@ -31,8 +31,11 @@ #endif #include "client/windows/crash_generation/crash_generation_client.h" -#include + +#include + #include + #include "client/windows/common/ipc_protocol.h" namespace google_breakpad { diff --git a/src/client/windows/crash_generation/crash_generation_server.cc b/src/client/windows/crash_generation/crash_generation_server.cc index 61b0cbc0b..1e7a6ca70 100644 --- a/src/client/windows/crash_generation/crash_generation_server.cc +++ b/src/client/windows/crash_generation/crash_generation_server.cc @@ -31,12 +31,15 @@ #endif #include "client/windows/crash_generation/crash_generation_server.h" + #include -#include + +#include + #include + #include "client/windows/common/auto_critical_section.h" #include "common/scoped_ptr.h" - #include "client/windows/crash_generation/client_info.h" namespace google_breakpad { diff --git a/src/client/windows/handler/exception_handler.cc b/src/client/windows/handler/exception_handler.cc index 64b297999..bc56bd80b 100644 --- a/src/client/windows/handler/exception_handler.cc +++ b/src/client/windows/handler/exception_handler.cc @@ -30,17 +30,17 @@ #include // Must come first #endif +#include "client/windows/handler/exception_handler.h" + +#include #include +#include #include -#include -#include - -#include "common/windows/string_utils-inl.h" #include "client/windows/common/ipc_protocol.h" -#include "client/windows/handler/exception_handler.h" #include "common/windows/guid_string.h" +#include "common/windows/string_utils-inl.h" namespace google_breakpad { diff --git a/src/common/solaris/file_id.cc b/src/common/solaris/file_id.cc index 5a9982bb4..73b6acc22 100644 --- a/src/common/solaris/file_id.cc +++ b/src/common/solaris/file_id.cc @@ -36,20 +36,19 @@ #include // Must come first #endif +#include "common/solaris/file_id.h" + +#include #include #include #include -#include -#include #include #include +#include +#include #include -#include -#include - #include "common/md5.h" -#include "common/solaris/file_id.h" #include "common/solaris/message_output.h" #include "google_breakpad/common/minidump_format.h" diff --git a/src/common/solaris/guid_creator.cc b/src/common/solaris/guid_creator.cc index 998d24991..2cfe1b7b3 100644 --- a/src/common/solaris/guid_creator.cc +++ b/src/common/solaris/guid_creator.cc @@ -32,15 +32,14 @@ #include // Must come first #endif -#include -#include +#include "common/solaris/guid_creator.h" +#include #include #include +#include #include -#include "common/solaris/guid_creator.h" - // // GUIDGenerator // diff --git a/src/common/string_view.h b/src/common/string_view.h index a8e15922d..8b9b19e6e 100644 --- a/src/common/string_view.h +++ b/src/common/string_view.h @@ -29,9 +29,13 @@ #ifndef COMMON_STRING_VIEW_H__ #define COMMON_STRING_VIEW_H__ -#include -#include +#include +#include +#include + +#include #include + #include "common/using_std_string.h" namespace google_breakpad { diff --git a/src/common/windows/omap.cc b/src/common/windows/omap.cc index 1ffcec765..e707e1268 100644 --- a/src/common/windows/omap.cc +++ b/src/common/windows/omap.cc @@ -106,10 +106,10 @@ #include "common/windows/omap.h" +#include #include #include -#include #include #include "common/windows/dia_util.h" diff --git a/src/common/windows/string_utils.cc b/src/common/windows/string_utils.cc index 956ee9906..46d530ecf 100644 --- a/src/common/windows/string_utils.cc +++ b/src/common/windows/string_utils.cc @@ -30,13 +30,13 @@ #include // Must come first #endif +#include "common/windows/string_utils-inl.h" + +#include #include -#include #include -#include "common/windows/string_utils-inl.h" - namespace google_breakpad { // static diff --git a/src/common/windows/sym_upload_v2_protocol.cc b/src/common/windows/sym_upload_v2_protocol.cc index 450f3626b..ee3b1919e 100644 --- a/src/common/windows/sym_upload_v2_protocol.cc +++ b/src/common/windows/sym_upload_v2_protocol.cc @@ -32,7 +32,7 @@ #include "common/windows/sym_upload_v2_protocol.h" -#include +#include #include "common/windows/http_upload.h" #include "common/windows/symbol_collector_client.h" diff --git a/src/google_breakpad/processor/call_stack.h b/src/google_breakpad/processor/call_stack.h index 9bf062f83..a18f8f74b 100644 --- a/src/google_breakpad/processor/call_stack.h +++ b/src/google_breakpad/processor/call_stack.h @@ -44,7 +44,8 @@ #ifndef GOOGLE_BREAKPAD_PROCESSOR_CALL_STACK_H__ #define GOOGLE_BREAKPAD_PROCESSOR_CALL_STACK_H__ -#include +#include + #include namespace google_breakpad { diff --git a/src/processor/exploitability.cc b/src/processor/exploitability.cc index 89064c9b1..e8b817449 100644 --- a/src/processor/exploitability.cc +++ b/src/processor/exploitability.cc @@ -37,7 +37,7 @@ #include // Must come first #endif -#include +#include #include "common/scoped_ptr.h" #include "google_breakpad/processor/exploitability.h" diff --git a/src/processor/fast_source_line_resolver.cc b/src/processor/fast_source_line_resolver.cc index 1c329772d..044eea356 100644 --- a/src/processor/fast_source_line_resolver.cc +++ b/src/processor/fast_source_line_resolver.cc @@ -41,16 +41,17 @@ #endif #include "google_breakpad/processor/fast_source_line_resolver.h" -#include "processor/fast_source_line_resolver_types.h" -#include -#include +#include +#include + #include #include #include #include "common/scoped_ptr.h" #include "common/using_std_string.h" +#include "processor/fast_source_line_resolver_types.h" #include "processor/logging.h" #include "processor/module_factory.h" #include "processor/simple_serializer-inl.h" diff --git a/src/processor/fast_source_line_resolver_types.h b/src/processor/fast_source_line_resolver_types.h index 14913518b..ae58d7525 100644 --- a/src/processor/fast_source_line_resolver_types.h +++ b/src/processor/fast_source_line_resolver_types.h @@ -36,7 +36,8 @@ #ifndef PROCESSOR_FAST_SOURCE_LINE_RESOLVER_TYPES_H__ #define PROCESSOR_FAST_SOURCE_LINE_RESOLVER_TYPES_H__ -#include +#include + #include #include diff --git a/src/processor/map_serializers_unittest.cc b/src/processor/map_serializers_unittest.cc index 855c4dae1..c5228d647 100644 --- a/src/processor/map_serializers_unittest.cc +++ b/src/processor/map_serializers_unittest.cc @@ -31,12 +31,15 @@ // // Author: Siyang Xie (lambxsy@google.com) -#include #ifdef HAVE_CONFIG_H #include // Must come first #endif -#include +#include "map_serializers-inl.h" + +#include +#include + #include #include #include @@ -44,8 +47,6 @@ #include #include "breakpad_googletest_includes.h" -#include "map_serializers-inl.h" - #include "processor/address_map-inl.h" #include "processor/range_map-inl.h" #include "processor/contained_range_map-inl.h" diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 22dce7626..d33522631 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -44,10 +44,10 @@ #include "google_breakpad/processor/minidump.h" #include -#include #include #include #include +#include #include #include @@ -62,8 +62,6 @@ #include #include -#include "processor/range_map-inl.h" - #include "common/macros.h" #include "common/scoped_ptr.h" #include "common/stdio_wrapper.h" @@ -72,6 +70,7 @@ #include "processor/basic_code_modules.h" #include "processor/convert_old_arm64_context.h" #include "processor/logging.h" +#include "processor/range_map-inl.h" namespace google_breakpad { diff --git a/src/processor/minidump_processor.cc b/src/processor/minidump_processor.cc index 44e69c890..b2166e652 100644 --- a/src/processor/minidump_processor.cc +++ b/src/processor/minidump_processor.cc @@ -33,10 +33,10 @@ #include "google_breakpad/processor/minidump_processor.h" #include +#include +#include #include -#include -#include #include #include #include diff --git a/src/processor/module_serializer.cc b/src/processor/module_serializer.cc index 33130353a..5a744a56c 100644 --- a/src/processor/module_serializer.cc +++ b/src/processor/module_serializer.cc @@ -38,8 +38,9 @@ #include "processor/module_serializer.h" -#include -#include +#include +#include + #include #include diff --git a/src/processor/module_serializer.h b/src/processor/module_serializer.h index 675d78488..eefe2857d 100644 --- a/src/processor/module_serializer.h +++ b/src/processor/module_serializer.h @@ -36,7 +36,8 @@ #ifndef PROCESSOR_MODULE_SERIALIZER_H__ #define PROCESSOR_MODULE_SERIALIZER_H__ -#include +#include + #include #include diff --git a/src/processor/simple_serializer-inl.h b/src/processor/simple_serializer-inl.h index bc2c8def2..30d0533bd 100644 --- a/src/processor/simple_serializer-inl.h +++ b/src/processor/simple_serializer-inl.h @@ -39,7 +39,8 @@ #include "processor/simple_serializer.h" -#include +#include + #include #include "google_breakpad/processor/basic_source_line_resolver.h" diff --git a/src/processor/stackwalker_arm64.cc b/src/processor/stackwalker_arm64.cc index 6c3168ecc..0fdc11018 100644 --- a/src/processor/stackwalker_arm64.cc +++ b/src/processor/stackwalker_arm64.cc @@ -36,7 +36,10 @@ #include // Must come first #endif -#include +#include "processor/stackwalker_arm64.h" + +#include + #include #include "common/scoped_ptr.h" @@ -46,7 +49,6 @@ #include "google_breakpad/processor/stack_frame_cpu.h" #include "processor/cfi_frame_info.h" #include "processor/logging.h" -#include "processor/stackwalker_arm64.h" namespace google_breakpad { diff --git a/src/processor/stackwalker_arm64.h b/src/processor/stackwalker_arm64.h index 193ab302a..933b557ff 100644 --- a/src/processor/stackwalker_arm64.h +++ b/src/processor/stackwalker_arm64.h @@ -41,6 +41,7 @@ #include "google_breakpad/common/breakpad_types.h" #include "google_breakpad/common/minidump_format.h" +#include "google_breakpad/processor/stack_frame_cpu.h" #include "google_breakpad/processor/stackwalker.h" namespace google_breakpad { diff --git a/src/processor/static_address_map_unittest.cc b/src/processor/static_address_map_unittest.cc index 2e8461675..d99833ce8 100644 --- a/src/processor/static_address_map_unittest.cc +++ b/src/processor/static_address_map_unittest.cc @@ -34,9 +34,12 @@ #include // Must come first #endif -#include -#include -#include +#include "processor/static_address_map-inl.h" + +#include +#include +#include + #include #include #include @@ -44,7 +47,6 @@ #include "breakpad_googletest_includes.h" #include "common/using_std_string.h" #include "processor/address_map-inl.h" -#include "processor/static_address_map-inl.h" #include "processor/simple_serializer-inl.h" #include "map_serializers-inl.h" diff --git a/src/processor/static_contained_range_map_unittest.cc b/src/processor/static_contained_range_map_unittest.cc index c6d78400d..b9ed72489 100644 --- a/src/processor/static_contained_range_map_unittest.cc +++ b/src/processor/static_contained_range_map_unittest.cc @@ -31,15 +31,17 @@ // // Author: Siyang Xie (lambxsy@google.com) -#include #ifdef HAVE_CONFIG_H #include // Must come first #endif +#include "processor/static_contained_range_map-inl.h" + +#include + #include "breakpad_googletest_includes.h" #include "common/scoped_ptr.h" #include "processor/contained_range_map-inl.h" -#include "processor/static_contained_range_map-inl.h" #include "processor/simple_serializer-inl.h" #include "processor/map_serializers-inl.h" #include "processor/logging.h" diff --git a/src/processor/static_map_unittest.cc b/src/processor/static_map_unittest.cc index 1fbb9a498..9308b04bd 100644 --- a/src/processor/static_map_unittest.cc +++ b/src/processor/static_map_unittest.cc @@ -30,17 +30,18 @@ // // Author: Siyang Xie (lambxsy@google.com) -#include #ifdef HAVE_CONFIG_H #include // Must come first #endif -#include +#include "processor/static_map-inl.h" + +#include +#include + #include #include "breakpad_googletest_includes.h" -#include "processor/static_map-inl.h" - typedef int ValueType; typedef int KeyType; diff --git a/src/tools/linux/dump_syms/dump_syms.cc b/src/tools/linux/dump_syms/dump_syms.cc index 007b46094..f5f89f410 100644 --- a/src/tools/linux/dump_syms/dump_syms.cc +++ b/src/tools/linux/dump_syms/dump_syms.cc @@ -32,9 +32,9 @@ #include #include +#include #include -#include #include #include #include diff --git a/src/tools/solaris/dump_syms/dump_syms.cc b/src/tools/solaris/dump_syms/dump_syms.cc index ead160011..8f5924ae2 100644 --- a/src/tools/solaris/dump_syms/dump_syms.cc +++ b/src/tools/solaris/dump_syms/dump_syms.cc @@ -32,11 +32,12 @@ #include // Must come first #endif -#include -#include - #include "common/solaris/dump_symbols.h" +#include + +#include + using namespace google_breakpad; int main(int argc, char** argv) { diff --git a/src/tools/windows/converter/ms_symbol_server_converter.cc b/src/tools/windows/converter/ms_symbol_server_converter.cc index f7d9d9431..d1a6b40d5 100644 --- a/src/tools/windows/converter/ms_symbol_server_converter.cc +++ b/src/tools/windows/converter/ms_symbol_server_converter.cc @@ -37,14 +37,15 @@ #include // Must come first #endif +#include "tools/windows/converter/ms_symbol_server_converter.h" + #include + +#include #include #include +#include -#include -#include - -#include "tools/windows/converter/ms_symbol_server_converter.h" #include "common/windows/pdb_source_line_writer.h" #include "common/windows/pe_source_line_writer.h" #include "common/windows/string_utils-inl.h" diff --git a/src/tools/windows/converter_exe/converter.cc b/src/tools/windows/converter_exe/converter.cc index 92c41774a..6d7664774 100644 --- a/src/tools/windows/converter_exe/converter.cc +++ b/src/tools/windows/converter_exe/converter.cc @@ -35,9 +35,10 @@ #include // Must come first #endif -#include -#include -#include +#include +#include +#include + #include #include #include diff --git a/src/tools/windows/symupload/symupload.cc b/src/tools/windows/symupload/symupload.cc index 20f48a277..52a915c30 100644 --- a/src/tools/windows/symupload/symupload.cc +++ b/src/tools/windows/symupload/symupload.cc @@ -47,18 +47,18 @@ #endif #include + #include +#include #include -#include #include #include #include -#include "common/windows/string_utils-inl.h" - #include "common/windows/http_upload.h" #include "common/windows/pdb_source_line_writer.h" +#include "common/windows/string_utils-inl.h" #include "common/windows/sym_upload_v2_protocol.h" #include "common/windows/symbol_collector_client.h" From 02dd5c3ffbfed2bcbc93b553ed0e90a1ac951cb4 Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Mon, 2 Dec 2024 12:44:04 -0500 Subject: [PATCH 61/91] Upload system symbols: ensure dumped breakpad filenames are unique At some point, we started hitting limits on symbol file names, so we began collapsing each path components except the filename down to the first letter. This breaks down with the following setup: Some.framework/Versions/30/libSomething.dylib Some.framework/Versions/31/libSomething.dylib Which collapse to the same file name. Since upload_system_symbols dumps in parallel, this can lead to one of the files overwriting part of the other, creating a corrupted end product. This change creates files with O_EXCL. If creating fails due to the file already existing, we tack on a counter (so f.sym becomes f_1.sym, for example). Bug: chromium:40250422 Change-Id: I66ea50b84d68d3c5103eb7e31568b8444ec3be27 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6064141 Reviewed-by: Mark Mentovai --- .../upload_system_symbols.go | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/tools/mac/upload_system_symbols/upload_system_symbols.go b/src/tools/mac/upload_system_symbols/upload_system_symbols.go index 8b0cb46f9..2f6d1c19c 100644 --- a/src/tools/mac/upload_system_symbols/upload_system_symbols.go +++ b/src/tools/mac/upload_system_symbols/upload_system_symbols.go @@ -113,6 +113,7 @@ var ( regexp.MustCompile(`\.a$`), regexp.MustCompile(`\.dat$`), } + maxFileCreateTries = 10 ) func main() { @@ -226,6 +227,34 @@ func manglePath(path string) string { return builder.String() } +// createSymbolFile creates a writable file in `base` with a name derived from +// `original_path`. It ensures that multiple threads can't simultaneously create +// the same file for two `original_paths` that map to the same mangled name. +// Returns the filename, the file, and an error if creating the file failed. +func createSymbolFile(base string, original_path string, arch string) (filename string, f *os.File, err error) { + mangled := manglePath(original_path) + counter := 0 + filebase := path.Join(base, mangled) + for { + var symfile string + if counter == 0 { + symfile = fmt.Sprintf("%s_%s.sym", filebase, arch) + } else { + symfile = fmt.Sprintf("%s_%s_%d.sym", filebase, arch, counter) + } + f, err := os.OpenFile(symfile, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644) + if err == nil { + return symfile, f, nil + } + if os.IsExist(err) && counter < maxFileCreateTries { + counter++ + continue + } + return "", nil, err + } + +} + type WorkerPool struct { wg sync.WaitGroup } @@ -359,9 +388,7 @@ func (dq *DumpQueue) worker() { dumpSyms := path.Join(*breakpadTools, "dump_syms") for req := range dq.queue { - filebase := path.Join(dq.dumpPath, manglePath(req.path)) - symfile := fmt.Sprintf("%s_%s.sym", filebase, req.arch) - f, err := os.Create(symfile) + symfile, f, err := createSymbolFile(dq.dumpPath, req.path, req.arch) if err != nil { log.Fatalf("Error creating symbol file: %v", err) } From 0dfd77492fdb0dcd06027c5842095e2e908adc90 Mon Sep 17 00:00:00 2001 From: Takuto Ikuta Date: Mon, 16 Dec 2024 18:54:44 +0900 Subject: [PATCH 62/91] add missing includes for the build with use_libcxx_modules This is to fix build error when we set use_libcxx_modules=true in chromium build. Bug: 40263312 Change-Id: Ibcdd9da07ae3af2c981216e683b200b4c3a25d84 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6096620 Reviewed-by: Primiano Tucci Reviewed-by: Primiano Tucci --- src/processor/tokenize.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/processor/tokenize.cc b/src/processor/tokenize.cc index a46c9644c..47fc3fec0 100644 --- a/src/processor/tokenize.cc +++ b/src/processor/tokenize.cc @@ -32,6 +32,7 @@ #include +#include #include #include From 69621cb9c6d40252c1dc5cd357db1372893add4a Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 14 Jan 2025 23:43:55 -0500 Subject: [PATCH 63/91] convert random NULL usage to nullptr Since NULL requires headers to be included to define it, and some of our files are missing those includes depending on optimization settings, switch over to the language nullptr builtin to avoid. This doesn't cover all the files in the tree, just some random Linux and common ones that I ran into build failures with. Change-Id: I0a68538fa138148c2a0c1ec5d6dd558ffd4629b2 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6173184 Reviewed-by: Lei Zhang --- src/client/linux/handler/exception_handler.h | 2 +- .../linux/handler/microdump_extra_info.h | 8 +++--- .../linux/handler/minidump_descriptor.h | 4 +-- src/client/linux/minidump_writer/cpu_set.h | 2 +- .../minidump_writer/proc_cpuinfo_reader.h | 2 +- src/common/memory_range.h | 6 ++-- src/common/scoped_ptr.h | 28 +++++++++---------- src/processor/static_map_iterator.h | 2 +- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/client/linux/handler/exception_handler.h b/src/client/linux/handler/exception_handler.h index f8bc1ead7..f12979322 100644 --- a/src/client/linux/handler/exception_handler.h +++ b/src/client/linux/handler/exception_handler.h @@ -207,7 +207,7 @@ class ExceptionHandler { // Returns whether out-of-process dump generation is used or not. bool IsOutOfProcess() const { - return crash_generation_client_.get() != NULL; + return crash_generation_client_.get() != nullptr; } // Add information about a memory mapping. This can be used if diff --git a/src/client/linux/handler/microdump_extra_info.h b/src/client/linux/handler/microdump_extra_info.h index 1da69d090..6418c1304 100644 --- a/src/client/linux/handler/microdump_extra_info.h +++ b/src/client/linux/handler/microdump_extra_info.h @@ -40,10 +40,10 @@ struct MicrodumpExtraInfo { const char* process_type; MicrodumpExtraInfo() - : build_fingerprint(NULL), - product_info(NULL), - gpu_fingerprint(NULL), - process_type(NULL) {} + : build_fingerprint(nullptr), + product_info(nullptr), + gpu_fingerprint(nullptr), + process_type(nullptr) {} }; } diff --git a/src/client/linux/handler/minidump_descriptor.h b/src/client/linux/handler/minidump_descriptor.h index 1fbcaccfd..72d119d9e 100644 --- a/src/client/linux/handler/minidump_descriptor.h +++ b/src/client/linux/handler/minidump_descriptor.h @@ -61,7 +61,7 @@ class MinidumpDescriptor { : mode_(kWriteMinidumpToFile), fd_(-1), directory_(directory), - c_path_(NULL), + c_path_(nullptr), size_limit_(-1), address_within_principal_mapping_(0), skip_dump_if_principal_mapping_not_referenced_(false), @@ -72,7 +72,7 @@ class MinidumpDescriptor { explicit MinidumpDescriptor(int fd) : mode_(kWriteMinidumpToFd), fd_(fd), - c_path_(NULL), + c_path_(nullptr), size_limit_(-1), address_within_principal_mapping_(0), skip_dump_if_principal_mapping_not_referenced_(false), diff --git a/src/client/linux/minidump_writer/cpu_set.h b/src/client/linux/minidump_writer/cpu_set.h index 70c1c7582..9023d3a5b 100644 --- a/src/client/linux/minidump_writer/cpu_set.h +++ b/src/client/linux/minidump_writer/cpu_set.h @@ -79,7 +79,7 @@ class CpuSet { size_t item_len = static_cast(p_end - p); const char* item_next = static_cast(my_memchr(p, ',', item_len)); - if (item_next != NULL) { + if (item_next != nullptr) { p = item_next + 1; item_len = static_cast(item_next - item); } else { diff --git a/src/client/linux/minidump_writer/proc_cpuinfo_reader.h b/src/client/linux/minidump_writer/proc_cpuinfo_reader.h index 5ae16dfbc..5ba1bafa6 100644 --- a/src/client/linux/minidump_writer/proc_cpuinfo_reader.h +++ b/src/client/linux/minidump_writer/proc_cpuinfo_reader.h @@ -74,7 +74,7 @@ class ProcCpuInfoReader { // - can contain spaces. // - some fields have an empty char* sep = static_cast(my_memchr(line, ':', line_len)); - if (sep == NULL) + if (sep == nullptr) continue; // Record the value. Skip leading space after the column to get diff --git a/src/common/memory_range.h b/src/common/memory_range.h index e2ab61d5a..3dda169e7 100644 --- a/src/common/memory_range.h +++ b/src/common/memory_range.h @@ -46,7 +46,7 @@ namespace google_breakpad { // in a crashed environment. class MemoryRange { public: - MemoryRange() : data_(NULL), length_(0) {} + MemoryRange() : data_(nullptr), length_(0) {} MemoryRange(const void* data, size_t length) { Set(data, length); @@ -60,7 +60,7 @@ class MemoryRange { // Resets to an empty range. void Reset() { - data_ = NULL; + data_ = nullptr; length_ = 0; } @@ -87,7 +87,7 @@ class MemoryRange { // |sub_offset| bytes of this memory range, or NULL if the subrange // is out of bounds. const void* GetData(size_t sub_offset, size_t sub_length) const { - return Covers(sub_offset, sub_length) ? (data_ + sub_offset) : NULL; + return Covers(sub_offset, sub_length) ? (data_ + sub_offset) : nullptr; } // Same as the two-argument version of GetData() but uses sizeof(DataType) diff --git a/src/common/scoped_ptr.h b/src/common/scoped_ptr.h index d11101782..237ee7129 100644 --- a/src/common/scoped_ptr.h +++ b/src/common/scoped_ptr.h @@ -89,7 +89,7 @@ class scoped_ptr { // Constructor. Defaults to initializing with NULL. // There is no way to create an uninitialized scoped_ptr. // The input parameter must be allocated with new. - explicit scoped_ptr(C* p = NULL) : ptr_(p) { } + explicit scoped_ptr(C* p = nullptr) : ptr_(p) { } // Destructor. If there is a C object, delete it. // We don't need to test ptr_ == NULL because C++ does that for us. @@ -101,7 +101,7 @@ class scoped_ptr { // Reset. Deletes the current owned object, if any. // Then takes ownership of a new object, if given. // this->reset(this->get()) works. - void reset(C* p = NULL) { + void reset(C* p = nullptr) { if (p != ptr_) { enum { type_must_be_complete = sizeof(C) }; delete ptr_; @@ -112,11 +112,11 @@ class scoped_ptr { // Accessors to get the owned object. // operator* and operator-> will assert() if there is no current object. C& operator*() const { - assert(ptr_ != NULL); + assert(ptr_ != nullptr); return *ptr_; } C* operator->() const { - assert(ptr_ != NULL); + assert(ptr_ != nullptr); return ptr_; } C* get() const { return ptr_; } @@ -141,7 +141,7 @@ class scoped_ptr { // and will not own the object any more. C* release() { C* retVal = ptr_; - ptr_ = NULL; + ptr_ = nullptr; return retVal; } @@ -194,7 +194,7 @@ class scoped_array { // Constructor. Defaults to intializing with NULL. // There is no way to create an uninitialized scoped_array. // The input parameter must be allocated with new []. - explicit scoped_array(C* p = NULL) : array_(p) { } + explicit scoped_array(C* p = nullptr) : array_(p) { } // Destructor. If there is a C object, delete it. // We don't need to test ptr_ == NULL because C++ does that for us. @@ -206,7 +206,7 @@ class scoped_array { // Reset. Deletes the current owned object, if any. // Then takes ownership of a new object, if given. // this->reset(this->get()) works. - void reset(C* p = NULL) { + void reset(C* p = nullptr) { if (p != array_) { enum { type_must_be_complete = sizeof(C) }; delete[] array_; @@ -218,7 +218,7 @@ class scoped_array { // Will assert() if there is no current object, or index i is negative. C& operator[](ptrdiff_t i) const { assert(i >= 0); - assert(array_ != NULL); + assert(array_ != nullptr); return array_[i]; } @@ -248,7 +248,7 @@ class scoped_array { // and will not own the object any more. C* release() { C* retVal = array_; - array_ = NULL; + array_ = nullptr; return retVal; } @@ -304,7 +304,7 @@ class scoped_ptr_malloc { // The input parameter must be allocated with an allocator that matches the // Free functor. For the default Free functor, this is malloc, calloc, or // realloc. - explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {} + explicit scoped_ptr_malloc(C* p = nullptr): ptr_(p) {} // Destructor. If there is a C object, call the Free functor. ~scoped_ptr_malloc() { @@ -314,7 +314,7 @@ class scoped_ptr_malloc { // Reset. Calls the Free functor on the current owned object, if any. // Then takes ownership of a new object, if given. // this->reset(this->get()) works. - void reset(C* p = NULL) { + void reset(C* p = nullptr) { if (ptr_ != p) { FreeProc free_proc; free_proc(ptr_); @@ -326,12 +326,12 @@ class scoped_ptr_malloc { // operator* and operator-> will cause an assert() failure if there is // no current object. C& operator*() const { - assert(ptr_ != NULL); + assert(ptr_ != nullptr); return *ptr_; } C* operator->() const { - assert(ptr_ != NULL); + assert(ptr_ != nullptr); return ptr_; } @@ -366,7 +366,7 @@ class scoped_ptr_malloc { // and will not own the object any more. C* release() { C* tmp = ptr_; - ptr_ = NULL; + ptr_ = nullptr; return tmp; } diff --git a/src/processor/static_map_iterator.h b/src/processor/static_map_iterator.h index 8cfe9e080..53d7c5d77 100644 --- a/src/processor/static_map_iterator.h +++ b/src/processor/static_map_iterator.h @@ -52,7 +52,7 @@ template class StaticMapIterator { public: // Constructors. - StaticMapIterator(): index_(-1), base_(NULL) { } + StaticMapIterator(): index_(-1), base_(nullptr) { } // Increment & Decrement operators: StaticMapIterator& operator++(); From feea0f7672e5e7ac33ebbf6acb13e580f8b6b136 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 14 Jan 2025 23:39:39 -0500 Subject: [PATCH 64/91] use const string& in more places to avoid unnecessary copy constructors Coverity has started checking for wasteful copies where move's would work which has pointed out a bunch of places where we use "string" in a function prototype even though it's always read-only. Convert all those over to "const string&" for simple performance improvements. Change-Id: I264b19c1de8d2d0aa69032bff44cea95cc057a70 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6173849 Reviewed-by: Nelson Billing --- .../handler/exception_handler_unittest.cc | 2 +- src/client/mac/handler/dynamic_images.h | 2 +- src/common/linux/dump_symbols.cc | 2 +- .../basic_source_line_resolver_unittest.cc | 2 +- src/processor/disassembler_objdump.cc | 20 ++++++++++++------- .../fast_source_line_resolver_unittest.cc | 2 +- src/processor/windows_frame_info.h | 4 ++-- src/tools/windows/converter_exe/converter.cc | 2 +- 8 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/client/linux/handler/exception_handler_unittest.cc b/src/client/linux/handler/exception_handler_unittest.cc index b2d8d4681..d512bd8d7 100644 --- a/src/client/linux/handler/exception_handler_unittest.cc +++ b/src/client/linux/handler/exception_handler_unittest.cc @@ -378,7 +378,7 @@ static bool InstallRaiseSIGKILL() { static void CrashWithCallbacks(ExceptionHandler::FilterCallback filter, ExceptionHandler::MinidumpCallback done, - string path) { + const string& path) { ExceptionHandler handler( MinidumpDescriptor(path), filter, done, NULL, true, -1); // Crash with the exception handler in scope. diff --git a/src/client/mac/handler/dynamic_images.h b/src/client/mac/handler/dynamic_images.h index b5af75848..4799fedfc 100644 --- a/src/client/mac/handler/dynamic_images.h +++ b/src/client/mac/handler/dynamic_images.h @@ -110,7 +110,7 @@ class DynamicImage { DynamicImage(uint8_t* header, // data is copied size_t header_size, // includes load commands uint64_t load_address, - string file_path, + const string& file_path, uintptr_t image_mod_date, mach_port_t task, cpu_type_t cpu_type) diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index 55fa98469..316d58a30 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -826,7 +826,7 @@ class LoadSymbolsInfo { string debuglink_file() const { return debuglink_file_; } - void set_debuglink_file(string file) { + void set_debuglink_file(const string& file) { debuglink_file_ = file; } diff --git a/src/processor/basic_source_line_resolver_unittest.cc b/src/processor/basic_source_line_resolver_unittest.cc index a73ded8b7..c496cbb97 100644 --- a/src/processor/basic_source_line_resolver_unittest.cc +++ b/src/processor/basic_source_line_resolver_unittest.cc @@ -60,7 +60,7 @@ using google_breakpad::SymbolParseHelper; class TestCodeModule : public CodeModule { public: - TestCodeModule(string code_file) : code_file_(code_file) {} + TestCodeModule(const string& code_file) : code_file_(code_file) {} virtual ~TestCodeModule() {} virtual uint64_t base_address() const { return 0; } diff --git a/src/processor/disassembler_objdump.cc b/src/processor/disassembler_objdump.cc index 9f9569a5e..3e0b6d196 100644 --- a/src/processor/disassembler_objdump.cc +++ b/src/processor/disassembler_objdump.cc @@ -73,7 +73,8 @@ bool IsOperandSize(const string& token) { return false; } -bool GetSegmentAddressX86(const DumpContext& context, string segment_name, +bool GetSegmentAddressX86(const DumpContext& context, + const string& segment_name, uint64_t& address) { if (segment_name == "ds") { address = context.GetContextX86()->ds; @@ -91,7 +92,8 @@ bool GetSegmentAddressX86(const DumpContext& context, string segment_name, return true; } -bool GetSegmentAddressAMD64(const DumpContext& context, string segment_name, +bool GetSegmentAddressAMD64(const DumpContext& context, + const string& segment_name, uint64_t& address) { if (segment_name == "ds") { address = 0; @@ -105,7 +107,8 @@ bool GetSegmentAddressAMD64(const DumpContext& context, string segment_name, return true; } -bool GetSegmentAddress(const DumpContext& context, string segment_name, +bool GetSegmentAddress(const DumpContext& context, + const string& segment_name, uint64_t& address) { if (context.GetContextCPU() == MD_CONTEXT_X86) { return GetSegmentAddressX86(context, segment_name, address); @@ -117,7 +120,8 @@ bool GetSegmentAddress(const DumpContext& context, string segment_name, } } -bool GetRegisterValueX86(const DumpContext& context, string register_name, +bool GetRegisterValueX86(const DumpContext& context, + const string& register_name, uint64_t& value) { if (register_name == "eax") { value = context.GetContextX86()->eax; @@ -145,7 +149,8 @@ bool GetRegisterValueX86(const DumpContext& context, string register_name, return true; } -bool GetRegisterValueAMD64(const DumpContext& context, string register_name, +bool GetRegisterValueAMD64(const DumpContext& context, + const string& register_name, uint64_t& value) { if (register_name == "rax") { value = context.GetContextAMD64()->rax; @@ -193,7 +198,8 @@ bool GetRegisterValueAMD64(const DumpContext& context, string register_name, // success. // Support for non-full-size registers not implemented, since we're only using // this to evaluate address expressions. -bool GetRegisterValue(const DumpContext& context, string register_name, +bool GetRegisterValue(const DumpContext& context, + const string& register_name, uint64_t& value) { if (context.GetContextCPU() == MD_CONTEXT_X86) { return GetRegisterValueX86(context, register_name, value); @@ -484,4 +490,4 @@ bool DisassemblerObjdump::CalculateDestAddress(const DumpContext& context, return CalculateAddress(context, dest_, address); } -} // namespace google_breakpad \ No newline at end of file +} // namespace google_breakpad diff --git a/src/processor/fast_source_line_resolver_unittest.cc b/src/processor/fast_source_line_resolver_unittest.cc index 08340c15a..5a24d2870 100644 --- a/src/processor/fast_source_line_resolver_unittest.cc +++ b/src/processor/fast_source_line_resolver_unittest.cc @@ -71,7 +71,7 @@ using google_breakpad::scoped_ptr; class TestCodeModule : public CodeModule { public: - explicit TestCodeModule(string code_file) : code_file_(code_file) {} + explicit TestCodeModule(const string& code_file) : code_file_(code_file) {} virtual ~TestCodeModule() {} virtual uint64_t base_address() const { return 0; } diff --git a/src/processor/windows_frame_info.h b/src/processor/windows_frame_info.h index 4014a1a99..346bc4d4b 100644 --- a/src/processor/windows_frame_info.h +++ b/src/processor/windows_frame_info.h @@ -95,7 +95,7 @@ struct WindowsFrameInfo { uint32_t set_local_size, uint32_t set_max_stack_size, int set_allocates_base_pointer, - const string set_program_string) + const string& set_program_string) : type_(type), valid(VALID_ALL), prolog_size(set_prolog_size), @@ -111,7 +111,7 @@ struct WindowsFrameInfo { // a string. Returns NULL if parsing fails, or a new object // otherwise. type, rva and code_size are present in the STACK line, // but not the StackFrameInfo structure, so return them as outparams. - static WindowsFrameInfo *ParseFromString(const string string, + static WindowsFrameInfo *ParseFromString(const string& string, int& type, uint64_t& rva, uint64_t& code_size) { diff --git a/src/tools/windows/converter_exe/converter.cc b/src/tools/windows/converter_exe/converter.cc index 6d7664774..e7b21862e 100644 --- a/src/tools/windows/converter_exe/converter.cc +++ b/src/tools/windows/converter_exe/converter.cc @@ -643,7 +643,7 @@ static void ConvertMissingSymbolFile(const MissingSymbolInfo& missing_info, // Reads the contents of file |file_name| and populates |contents|. // Returns true on success. -static bool ReadFile(string file_name, string* contents) { +static bool ReadFile(const string& file_name, string* contents) { char buffer[1024 * 8]; FILE* fp = fopen(file_name.c_str(), "rt"); if (!fp) { From 41b6533e5f3dd7f0320ef58608ee32e8e4f132fb Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 14 Jan 2025 23:41:57 -0500 Subject: [PATCH 65/91] use std::move with vector insertions Coverity has started detecting places where variables are inserted into a vector via a copy operation, and then not used anymore. Switch them over to explicit std::move for quick performance improvements. For example: 6405 MinidumpCrashpadInfo::AnnotationObject object = {annotation.type, name, 6406 value_data}; >>> CID 465406: Performance inefficiencies (COPY_INSTEAD_OF_MOVE) >>> "object" is copied and then passed-by-reference as parameter to STL insertion function "std::vector >::push_back( std::vector >::value_type const &)", when it could be moved instead. 6407 annotations_list->push_back(object); Change-Id: I2d3b3a35296dad84853f4dc6690d64c81c92d582 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6173183 Reviewed-by: Primiano Tucci Reviewed-by: Lei Zhang --- src/common/dwarf/dwarf2reader.cc | 2 +- src/processor/minidump.cc | 17 ++++++++++------- src/processor/minidump_processor.cc | 2 +- src/processor/proc_maps_linux.cc | 4 +++- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc index 7efb7d8b5..1c920fdc5 100644 --- a/src/common/dwarf/dwarf2reader.cc +++ b/src/common/dwarf/dwarf2reader.cc @@ -179,7 +179,7 @@ void CompilationUnit::ReadAbbrevs() { value); abbrev.attributes.push_back(abbrev_attr); } - abbrevs_->push_back(abbrev); + abbrevs_->push_back(std::move(abbrev)); } // Account of cases where entries are out of order. diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index d33522631..2a19836b3 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -5468,9 +5468,12 @@ bool MinidumpCrashpadInfo::Read(uint32_t expected_size) { module_crashpad_info_links_.push_back( module_crashpad_info_links[index].minidump_module_list_index); module_crashpad_info_.push_back(module_crashpad_info); - module_crashpad_info_list_annotations_.push_back(list_annotations); - module_crashpad_info_simple_annotations_.push_back(simple_annotations); - module_crashpad_info_annotation_objects_.push_back(annotation_objects); + module_crashpad_info_list_annotations_.push_back(std::move( + list_annotations)); + module_crashpad_info_simple_annotations_.push_back(std::move( + simple_annotations)); + module_crashpad_info_annotation_objects_.push_back(std::move( + annotation_objects)); } } @@ -6272,7 +6275,7 @@ bool Minidump::ReadStringList( return false; } - string_list->push_back(entry); + string_list->push_back(std::move(entry)); } return true; @@ -6402,9 +6405,9 @@ bool Minidump::ReadCrashpadAnnotationsList( return false; } - MinidumpCrashpadInfo::AnnotationObject object = {annotation.type, name, - value_data}; - annotations_list->push_back(object); + MinidumpCrashpadInfo::AnnotationObject object{annotation.type, name, + value_data}; + annotations_list->push_back(std::move(object)); } return true; diff --git a/src/processor/minidump_processor.cc b/src/processor/minidump_processor.cc index b2166e652..f4084005e 100644 --- a/src/processor/minidump_processor.cc +++ b/src/processor/minidump_processor.cc @@ -370,7 +370,7 @@ ProcessResult MinidumpProcessor::Process( stack->set_tid(thread_id); process_state->threads_.push_back(stack.release()); process_state->thread_memory_regions_.push_back(thread_memory); - process_state->thread_names_.push_back(thread_name); + process_state->thread_names_.push_back(std::move(thread_name)); } if (interrupted) { diff --git a/src/processor/proc_maps_linux.cc b/src/processor/proc_maps_linux.cc index 5234633e6..2ab6da225 100644 --- a/src/processor/proc_maps_linux.cc +++ b/src/processor/proc_maps_linux.cc @@ -17,6 +17,8 @@ #include #include +#include + #include "common/using_std_string.h" #include "processor/logging.h" @@ -99,7 +101,7 @@ bool ParseProcMaps(const string& input, return false; // Pushing then assigning saves us a string copy. - regions.push_back(region); + regions.push_back(std::move(region)); regions.back().path.assign(line + path_index); regions.back().line.assign(line); } From 4fe678ef96050b2ed97afe3b27bb9f8b660755de Mon Sep 17 00:00:00 2001 From: Sim Sun Date: Wed, 29 Jan 2025 17:33:09 -0800 Subject: [PATCH 66/91] linux: fix crash process not being dumpable on SIGABRT in Android Since aosp/743655, Android uses sigqueue for SIGABRT, preventing the current breakpad exception handler from setting the crash process as dumpable. This CL adds SI_QUEUE into the trusted si_code list to migrate the issue. Change-Id: I7015940c557e9c5252b299cda609f01ef375f003 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6217280 Reviewed-by: Mark Mentovai Reviewed-by: Joshua Peraza Reviewed-by: Nelson Billing --- src/client/linux/handler/exception_handler.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc index 9e23c1194..6267111fe 100644 --- a/src/client/linux/handler/exception_handler.cc +++ b/src/client/linux/handler/exception_handler.cc @@ -447,7 +447,8 @@ bool ExceptionHandler::HandleSignal(int /*sig*/, siginfo_t* info, void* uc) { // Allow ourselves to be dumped if the signal is trusted. bool signal_trusted = info->si_code > 0; bool signal_pid_trusted = info->si_code == SI_USER || - info->si_code == SI_TKILL; + info->si_code == SI_TKILL || + info->si_code == SI_QUEUE; if (signal_trusted || (signal_pid_trusted && info->si_pid == getpid())) { sys_prctl(PR_SET_DUMPABLE, 1, 0, 0, 0); } From c36c4e621f9c628019874c3d01ef5c3ea8c26459 Mon Sep 17 00:00:00 2001 From: Michael Spang Date: Thu, 6 Mar 2025 11:56:06 -0800 Subject: [PATCH 67/91] Revert "ARM: use r11 as frame pointer during stack unwind" This reverts commit c8318f06d3a48b0af37862b29fbeeeae8258dbed. Reason for revert: ARMv7 does not have a standard frame pointer gcc and clang have inconsistent frame pointer semantics on ARM. Frame pointers should not be used on this architecture for unwinding. Original change's description: > ARM: use r11 as frame pointer during stack unwind > > Bug: b/340226382 > Change-Id: Idb3d6e502a5a1e25179c3d5f2a19ac4cd79cd103 > Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/5636127 > Reviewed-by: Ivan Penkov Bug: b/340226382 Bug: b/349146521 Change-Id: I1f04aba79ad0ab14ad66146c47b545a8fa7bca53 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6329730 Reviewed-by: Joshua Peraza --- src/processor/stackwalker.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/processor/stackwalker.cc b/src/processor/stackwalker.cc index e7ef42d62..1ff6cf7cb 100644 --- a/src/processor/stackwalker.cc +++ b/src/processor/stackwalker.cc @@ -263,8 +263,6 @@ Stackwalker* Stackwalker::StackwalkerForCPU( int fp_register = -1; if (system_info->os_short == "ios") fp_register = MD_CONTEXT_ARM_REG_IOS_FP; - else - fp_register = MD_CONTEXT_ARM_REG_FP; cpu_stackwalker = new StackwalkerARM(system_info, context->GetContextARM(), fp_register, memory, modules, From 8c3a096081287d78112d7fe1da6f56c7ceea0e4c Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 12 Mar 2025 16:29:49 -0400 Subject: [PATCH 68/91] scoped_ptr.h: delete unused scoped_ptr_malloc API Nothing uses this, and it wasn't adopted into the C++ standard, so delete it to clean up. Change-Id: Icc9d0256bb29270cd08f4684acff55bf2a9a7dea Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6346968 Reviewed-by: Lei Zhang --- src/common/scoped_ptr.h | 121 +--------------------------------------- 1 file changed, 1 insertion(+), 120 deletions(-) diff --git a/src/common/scoped_ptr.h b/src/common/scoped_ptr.h index 237ee7129..e4d3cd290 100644 --- a/src/common/scoped_ptr.h +++ b/src/common/scoped_ptr.h @@ -62,7 +62,7 @@ // This is an implementation designed to match the anticipated future TR2 // implementation of the scoped_ptr class, and its closely-related brethren, -// scoped_array, scoped_ptr_malloc. +// scoped_array. #include #include @@ -280,125 +280,6 @@ bool operator!=(C* p1, const scoped_array& p2) { return p1 != p2.get(); } -// This class wraps the c library function free() in a class that can be -// passed as a template argument to scoped_ptr_malloc below. -class ScopedPtrMallocFree { - public: - inline void operator()(void* x) const { - free(x); - } -}; - -// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a -// second template argument, the functor used to free the object. - -template -class scoped_ptr_malloc { - public: - - // The element type - typedef C element_type; - - // Constructor. Defaults to initializing with NULL. - // There is no way to create an uninitialized scoped_ptr. - // The input parameter must be allocated with an allocator that matches the - // Free functor. For the default Free functor, this is malloc, calloc, or - // realloc. - explicit scoped_ptr_malloc(C* p = nullptr): ptr_(p) {} - - // Destructor. If there is a C object, call the Free functor. - ~scoped_ptr_malloc() { - reset(); - } - - // Reset. Calls the Free functor on the current owned object, if any. - // Then takes ownership of a new object, if given. - // this->reset(this->get()) works. - void reset(C* p = nullptr) { - if (ptr_ != p) { - FreeProc free_proc; - free_proc(ptr_); - ptr_ = p; - } - } - - // Get the current object. - // operator* and operator-> will cause an assert() failure if there is - // no current object. - C& operator*() const { - assert(ptr_ != nullptr); - return *ptr_; - } - - C* operator->() const { - assert(ptr_ != nullptr); - return ptr_; - } - - C* get() const { - return ptr_; - } - - // Comparison operators. - // These return whether a scoped_ptr_malloc and a plain pointer refer - // to the same object, not just to two different but equal objects. - // For compatibility with the boost-derived implementation, these - // take non-const arguments. - bool operator==(C* p) const { - return ptr_ == p; - } - - bool operator!=(C* p) const { - return ptr_ != p; - } - - // Swap two scoped pointers. - void swap(scoped_ptr_malloc & b) { - C* tmp = b.ptr_; - b.ptr_ = ptr_; - ptr_ = tmp; - } - - // Release a pointer. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - C* release() { - C* tmp = ptr_; - ptr_ = nullptr; - return tmp; - } - - private: - C* ptr_; - - // no reason to use these: each scoped_ptr_malloc should have its own object - template - bool operator==(scoped_ptr_malloc const& p) const; - template - bool operator!=(scoped_ptr_malloc const& p) const; - - // Disallow evil constructors - scoped_ptr_malloc(const scoped_ptr_malloc&); - void operator=(const scoped_ptr_malloc&); -}; - -template inline -void swap(scoped_ptr_malloc& a, scoped_ptr_malloc& b) { - a.swap(b); -} - -template inline -bool operator==(C* p, const scoped_ptr_malloc& b) { - return p == b.get(); -} - -template inline -bool operator!=(C* p, const scoped_ptr_malloc& b) { - return p != b.get(); -} - } // namespace google_breakpad #endif // COMMON_SCOPED_PTR_H_ From f48360c17e18f02677a34975cae6e4324e07ff88 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 12 Mar 2025 17:44:30 -0400 Subject: [PATCH 69/91] minidump: force string copy with unique_ptr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compiling with GCC 14.2 and C++20 triggers an error: $ g++ -std=gnu++20 -DHAVE_CONFIG_H -I. -I../src -I./src -I../src/src \ -Wmissing-braces -Wnon-virtual-dtor -Woverloaded-virtual -Wreorder -Wsign-compare -Wunused-local-typedefs -Wunused-variable -Wvla -Werror \ -fPIC -O2 -g -c ../src/src/processor/minidump.cc In file included from /usr/include/c++/14/memory:78, from ../src/src/processor/minidump.cc:63: In member function ‘void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = std::__cxx11::basic_string]’, inlined from ‘void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = std::__cxx11::basic_string]’ at /usr/include/c++/14/bits/unique_ptr.h:87:7, inlined from ‘std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = std::__cxx11::basic_string; _Dp = std::default_delete >]’ at /usr/include/c++/14/bits/unique_ptr.h:398:17, inlined from ‘virtual std::string google_breakpad::MinidumpModule::debug_file() const’ at ../src/src/processor/minidump.cc:2576:9: /usr/include/c++/14/bits/unique_ptr.h:93:9: error: ‘void operator delete(void*, std::size_t)’ called on unallocated object ‘file’ [-Werror=free-nonheap-object] 93 | delete __ptr; | ^~~~~~~~~~~~ ../src/src/processor/minidump.cc: In member function ‘virtual std::string google_breakpad::MinidumpModule::debug_file() const’: ../src/src/processor/minidump.cc:2509:10: note: declared here 2509 | string file; | ^~~~ Workaround this by forcing a new string to be constructed from the memory, and then moved into the stack file object. Change-Id: I1e2e6c2e30723daefca2046a3e5f5a580975301b Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6346970 Reviewed-by: Lei Zhang --- src/processor/minidump.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 2a19836b3..2099a2a61 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -2570,7 +2570,7 @@ string MinidumpModule::debug_file() const { // UTF-16, so pass false as the swap argument. scoped_ptr new_file(UTF16ToUTF8(string_utf16, false)); if (new_file.get() != nullptr) { - file = *new_file; + file = string(*new_file); } } } From d38dce0bc48a63d5785e7910ea269a186559ad96 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 12 Mar 2025 16:30:52 -0400 Subject: [PATCH 70/91] scoped_ptr.h: replace scoped_ptr with an alias to std::unique_ptr We've required C++17 for a while now, and that offers unique_ptr which is functionally the same as our scoped_ptr. Replace our custom code with an alias to the standard API. If this sticks, we can update the entire tree to use unique_ptr directly. Change-Id: I3ce01f710dc5c62d05df36d4c28059dddd3f71a9 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6346969 Reviewed-by: Lei Zhang --- src/common/scoped_ptr.h | 143 ++++------------------------------------ 1 file changed, 11 insertions(+), 132 deletions(-) diff --git a/src/common/scoped_ptr.h b/src/common/scoped_ptr.h index e4d3cd290..e7d2445ff 100644 --- a/src/common/scoped_ptr.h +++ b/src/common/scoped_ptr.h @@ -26,36 +26,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Scopers help you manage ownership of a pointer, helping you easily manage the -// a pointer within a scope, and automatically destroying the pointer at the -// end of a scope. There are two main classes you will use, which correspond -// to the operators new/delete and new[]/delete[]. -// -// Example usage (scoped_ptr): -// { -// scoped_ptr foo(new Foo("wee")); -// } // foo goes out of scope, releasing the pointer with it. -// -// { -// scoped_ptr foo; // No pointer managed. -// foo.reset(new Foo("wee")); // Now a pointer is managed. -// foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. -// foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. -// foo->Method(); // Foo::Method() called. -// foo.get()->Method(); // Foo::Method() called. -// SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer -// // manages a pointer. -// foo.reset(new Foo("wee4")); // foo manages a pointer again. -// foo.reset(); // Foo("wee4") destroyed, foo no longer -// // manages a pointer. -// } // foo wasn't managing a pointer, so nothing was destroyed. -// -// Example usage (scoped_array): -// { -// scoped_array foo(new Foo[100]); -// foo.get()->Method(); // Foo::Method on the 0th element. -// foo[10].Method(); // Foo::Method on the 10th element. -// } +// scoped_ptr is just a type alias for std::unique_ptr. Mass conversion TBD. #ifndef COMMON_SCOPED_PTR_H_ #define COMMON_SCOPED_PTR_H_ @@ -68,111 +39,19 @@ #include #include -namespace google_breakpad { - -// A scoped_ptr is like a T*, except that the destructor of scoped_ptr -// automatically deletes the pointer it holds (if any). -// That is, scoped_ptr owns the T object that it points to. -// Like a T*, a scoped_ptr may hold either NULL or a pointer to a T object. -// Also like T*, scoped_ptr is thread-compatible, and once you -// dereference it, you get the threadsafety guarantees of T. -// -// The size of a scoped_ptr is small: -// sizeof(scoped_ptr) == sizeof(C*) -template -class scoped_ptr { - public: +#include - // The element type - typedef C element_type; - - // Constructor. Defaults to initializing with NULL. - // There is no way to create an uninitialized scoped_ptr. - // The input parameter must be allocated with new. - explicit scoped_ptr(C* p = nullptr) : ptr_(p) { } - - // Destructor. If there is a C object, delete it. - // We don't need to test ptr_ == NULL because C++ does that for us. - ~scoped_ptr() { - enum { type_must_be_complete = sizeof(C) }; - delete ptr_; - } - - // Reset. Deletes the current owned object, if any. - // Then takes ownership of a new object, if given. - // this->reset(this->get()) works. - void reset(C* p = nullptr) { - if (p != ptr_) { - enum { type_must_be_complete = sizeof(C) }; - delete ptr_; - ptr_ = p; - } - } - - // Accessors to get the owned object. - // operator* and operator-> will assert() if there is no current object. - C& operator*() const { - assert(ptr_ != nullptr); - return *ptr_; - } - C* operator->() const { - assert(ptr_ != nullptr); - return ptr_; - } - C* get() const { return ptr_; } - - // Comparison operators. - // These return whether two scoped_ptr refer to the same object, not just to - // two different but equal objects. - bool operator==(C* p) const { return ptr_ == p; } - bool operator!=(C* p) const { return ptr_ != p; } - - // Swap two scoped pointers. - void swap(scoped_ptr& p2) { - C* tmp = ptr_; - ptr_ = p2.ptr_; - p2.ptr_ = tmp; - } - - // Release a pointer. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - C* release() { - C* retVal = ptr_; - ptr_ = nullptr; - return retVal; - } - - private: - C* ptr_; - - // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't - // make sense, and if C2 == C, it still doesn't make sense because you should - // never have the same object owned by two different scoped_ptrs. - template bool operator==(scoped_ptr const& p2) const; - template bool operator!=(scoped_ptr const& p2) const; - - // Disallow evil constructors - scoped_ptr(const scoped_ptr&); - void operator=(const scoped_ptr&); -}; - -// Free functions -template -void swap(scoped_ptr& p1, scoped_ptr& p2) { - p1.swap(p2); -} +namespace google_breakpad { -template -bool operator==(C* p1, const scoped_ptr& p2) { - return p1 == p2.get(); -} +template > +using scoped_ptr = std::unique_ptr; -template -bool operator!=(C* p1, const scoped_ptr& p2) { - return p1 != p2.get(); +// A function to convert T* into scoped_ptr +// Doing e.g. make_scoped_ptr(new FooBarBaz(arg)) is a shorter notation +// for scoped_ptr >(new FooBarBaz(arg)) +template +scoped_ptr make_scoped_ptr(T* ptr) { + return scoped_ptr(ptr); } // scoped_array is like scoped_ptr, except that the caller must allocate From 2c736308b5a4c7a8371fa3a3e434f551eddd17c9 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 25 Feb 2025 11:17:35 -0800 Subject: [PATCH 71/91] lss: update to latest version Change-Id: Ib07dcda1ca94fc2eda225a76d6fcb52c9ebd1700 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6297837 Reviewed-by: Troy Wang --- DEPS | 2 +- default.xml | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/DEPS b/DEPS index 3fcd524dc..cbcc5769f 100644 --- a/DEPS +++ b/DEPS @@ -46,7 +46,7 @@ deps = { # Linux syscall support. "src/src/third_party/lss": "https://chromium.googlesource.com/linux-syscall-support/" + - "@9719c1e1e676814c456b55f5f070eabad6709d31", + "@ed31caa60f20a4f6569883b2d752ef7522de51e0", } hooks = [ diff --git a/default.xml b/default.xml index 916b41fe7..08a0fee2d 100644 --- a/default.xml +++ b/default.xml @@ -7,14 +7,14 @@ sync-c='true' sync-j='8' /> - - + + - - + + From 87b8e4526a50a683672e51b3af413515ff2e4abd Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 12 Mar 2025 16:15:42 -0400 Subject: [PATCH 72/91] increase C++ standard to 20 Chromium switched to C++20 2 years ago, and we want to start using features from it, so update to it too. Change-Id: I97067f5015be6369506de5389913c60f336130a0 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6347230 Reviewed-by: Mark Mentovai --- configure | 124 +++++++++++++++++++++++++++++++++++++++++---------- configure.ac | 2 +- 2 files changed, 102 insertions(+), 24 deletions(-) diff --git a/configure b/configure index 3442e7969..37f3ac3ef 100755 --- a/configure +++ b/configure @@ -675,7 +675,7 @@ ANDROID_HOST_TRUE LINUX_HOST_FALSE LINUX_HOST_TRUE WARN_CXXFLAGS -HAVE_CXX17 +HAVE_CXX20 HAVE_MEMFD_CREATE_FALSE HAVE_MEMFD_CREATE_TRUE HAVE_GETCONTEXT_FALSE @@ -7594,7 +7594,7 @@ fi - ax_cxx_compile_alternatives="17 1z" ax_cxx_compile_cxx17_required=true + ax_cxx_compile_alternatives="20" ax_cxx_compile_cxx20_required=true ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -7602,9 +7602,9 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_success=no - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++17 features by default" >&5 -printf %s "checking whether $CXX supports C++17 features by default... " >&6; } -if test ${ax_cv_cxx_compile_cxx17+y} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++20 features by default" >&5 +printf %s "checking whether $CXX supports C++20 features by default... " >&6; } +if test ${ax_cv_cxx_compile_cxx20+y} then : printf %s "(cached) " >&6 else $as_nop @@ -8400,27 +8400,53 @@ namespace cxx17 + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 202002L && !defined _MSC_VER + +#error "This is not a C++20 compiler" + +#else + +#include + +namespace cxx20 +{ + +// As C++20 supports feature test macros in the standard, there is no +// immediate need to actually test for feature availability on the +// Autoconf side. + +} // namespace cxx20 + +#endif // __cplusplus < 202002L && !defined _MSC_VER + + + _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : - ax_cv_cxx_compile_cxx17=yes + ax_cv_cxx_compile_cxx20=yes else $as_nop - ax_cv_cxx_compile_cxx17=no + ax_cv_cxx_compile_cxx20=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx17" >&5 -printf "%s\n" "$ax_cv_cxx_compile_cxx17" >&6; } - if test x$ax_cv_cxx_compile_cxx17 = xyes; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx20" >&5 +printf "%s\n" "$ax_cv_cxx_compile_cxx20" >&6; } + if test x$ax_cv_cxx_compile_cxx20 = xyes; then ac_success=yes fi if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do switch="-std=gnu++${alternative}" - cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx17_$switch" | $as_tr_sh` - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++17 features with $switch" >&5 -printf %s "checking whether $CXX supports C++17 features with $switch... " >&6; } + cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx20_$switch" | $as_tr_sh` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++20 features with $switch" >&5 +printf %s "checking whether $CXX supports C++20 features with $switch... " >&6; } if eval test \${$cachevar+y} then : printf %s "(cached) " >&6 @@ -9219,6 +9245,32 @@ namespace cxx17 + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 202002L && !defined _MSC_VER + +#error "This is not a C++20 compiler" + +#else + +#include + +namespace cxx20 +{ + +// As C++20 supports feature test macros in the standard, there is no +// immediate need to actually test for feature availability on the +// Autoconf side. + +} // namespace cxx20 + +#endif // __cplusplus < 202002L && !defined _MSC_VER + + + _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : @@ -9246,9 +9298,9 @@ printf "%s\n" "$ac_res" >&6; } if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do - cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx17_$switch" | $as_tr_sh` - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++17 features with $switch" >&5 -printf %s "checking whether $CXX supports C++17 features with $switch... " >&6; } + cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx20_$switch" | $as_tr_sh` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++20 features with $switch" >&5 +printf %s "checking whether $CXX supports C++20 features with $switch... " >&6; } if eval test \${$cachevar+y} then : printf %s "(cached) " >&6 @@ -10047,6 +10099,32 @@ namespace cxx17 + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 202002L && !defined _MSC_VER + +#error "This is not a C++20 compiler" + +#else + +#include + +namespace cxx20 +{ + +// As C++20 supports feature test macros in the standard, there is no +// immediate need to actually test for feature availability on the +// Autoconf side. + +} // namespace cxx20 + +#endif // __cplusplus < 202002L && !defined _MSC_VER + + + _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : @@ -10080,19 +10158,19 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu - if test x$ax_cxx_compile_cxx17_required = xtrue; then + if test x$ax_cxx_compile_cxx20_required = xtrue; then if test x$ac_success = xno; then - as_fn_error $? "*** A compiler with support for C++17 language features is required." "$LINENO" 5 + as_fn_error $? "*** A compiler with support for C++20 language features is required." "$LINENO" 5 fi fi if test x$ac_success = xno; then - HAVE_CXX17=0 - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++17 support was found" >&5 -printf "%s\n" "$as_me: No compiler with C++17 support was found" >&6;} + HAVE_CXX20=0 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++20 support was found" >&5 +printf "%s\n" "$as_me: No compiler with C++20 support was found" >&6;} else - HAVE_CXX17=1 + HAVE_CXX20=1 -printf "%s\n" "#define HAVE_CXX17 1" >>confdefs.h +printf "%s\n" "#define HAVE_CXX20 1" >>confdefs.h fi diff --git a/configure.ac b/configure.ac index bfee372a3..0258c116e 100644 --- a/configure.ac +++ b/configure.ac @@ -66,7 +66,7 @@ AC_CHECK_FUNCS([arc4random getcontext getrandom memfd_create]) AM_CONDITIONAL([HAVE_GETCONTEXT], [test "x$ac_cv_func_getcontext" = xyes]) AM_CONDITIONAL([HAVE_MEMFD_CREATE], [test "x$ac_cv_func_memfd_create" = xyes]) -AX_CXX_COMPILE_STDCXX(17, , mandatory) +AX_CXX_COMPILE_STDCXX(20, , mandatory) dnl Test supported warning flags. WARN_CXXFLAGS= From 5fa919e19fec77acfb9685c43554133b4d9e9f2b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 18 Mar 2025 21:05:49 -0400 Subject: [PATCH 73/91] gtest: update to v1.16.0 release Passes `make check` on Linux for me, and it's close to the version the Chromium tree has been using for a while now. Certainly much closer than the 1.11.0 version we're pinned to. Change-Id: I494cbf540cf4bd525d4e35c28da2c22d59efec1b Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6367938 Reviewed-by: Lei Zhang --- DEPS | 2 +- default.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index cbcc5769f..f00f5d246 100644 --- a/DEPS +++ b/DEPS @@ -36,7 +36,7 @@ deps = { # Testing libraries and utilities. "src/src/testing": "https://github.com/google/googletest.git" + - "@release-1.11.0", + "@v1.16.0", # Protobuf. "src/src/third_party/protobuf/protobuf": diff --git a/default.xml b/default.xml index 08a0fee2d..72ff675b4 100644 --- a/default.xml +++ b/default.xml @@ -22,7 +22,7 @@ Date: Wed, 19 Mar 2025 12:10:53 -0400 Subject: [PATCH 74/91] Revert "Print additional argument that describes the crash" This reverts commit f8d05a9d0709ab0ec78582d220a939f8ceb41891. This reverts commit a70e77ea35a768a84078462c008c3f70e64d867e. This breaks src/processor/minidump_stackwalk_test on Linux: $ make check VERBOSE=1 ... ../src/src/processor/testdata/minidump2.stackwalk.out @@ -8,6 +8,9 @@ Crash reason: EXCEPTION_ACCESS_VIOLATION_WRITE Crash address: 0x45 +Crash parameters: + value: 1 description: + value: 69 description: Process uptime: 0 seconds Thread 0 (crashed) ... Change-Id: Iae755826913c5cbc97f3493bbe288d17aa0205d2 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6371501 Reviewed-by: Lei Zhang --- src/processor/stackwalk_common.cc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/processor/stackwalk_common.cc b/src/processor/stackwalk_common.cc index 72fceecdc..688b27823 100644 --- a/src/processor/stackwalk_common.cc +++ b/src/processor/stackwalk_common.cc @@ -1156,15 +1156,6 @@ void PrintProcessState(const ProcessState& process_state, if (process_state.crashed()) { printf("Crash reason: %s\n", process_state.crash_reason().c_str()); printf("Crash address: 0x%" PRIx64 "\n", process_state.crash_address()); - const std::vector* exception_param_vec = - process_state.exception_record()->parameters(); - if (exception_param_vec->size() > 0) { - printf("Crash parameters:\n"); - for (const auto& param : *exception_param_vec) { - printf(" value: %" PRIu64 "\tdescription: %s\n", param.value(), - param.description().c_str()); - } - } } else { printf("No crash\n"); } From 3dc19ab81fd93ee30a3c5ca146df561f8b7f90d7 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 12 Mar 2025 16:38:45 -0400 Subject: [PATCH 75/91] scoped_ptr.h: switch to std::unique_ptr Delete the scoped_ptr alias and switch code to std::unique_ptr directly. Change-Id: I3a25e07d66f0a27d16f82443b01c4db93a2cf0d9 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6367939 Reviewed-by: Lei Zhang --- src/client/ios/exception_handler_no_mach.cc | 4 +- src/client/ios/exception_handler_no_mach.h | 1 - src/client/linux/handler/exception_handler.h | 4 +- .../handler/exception_handler_unittest.cc | 6 +- .../microdump_writer_unittest.cc | 1 - src/client/mac/handler/exception_handler.cc | 3 +- src/client/mac/handler/exception_handler.h | 6 +- .../crash_generation_client.h | 1 - .../crash_generation_server.cc | 4 +- .../crash_generation_server.h | 1 - .../windows/handler/exception_handler.cc | 3 +- .../windows/handler/exception_handler.h | 4 +- .../unittests/exception_handler_death_test.cc | 11 ++-- src/common/basictypes.h | 2 +- src/common/dwarf/functioninfo.cc | 4 +- src/common/dwarf_cu_to_module.cc | 2 +- src/common/dwarf_cu_to_module.h | 8 +-- src/common/linux/dump_symbols.cc | 8 +-- src/common/mac/dump_syms.cc | 12 ++-- src/common/mac/dump_syms.h | 3 +- src/common/mac/file_id.cc | 5 +- src/common/scoped_ptr.h | 20 ++---- src/common/solaris/dump_symbols.cc | 1 - src/google_breakpad/processor/microdump.h | 10 +-- src/processor/basic_source_line_resolver.cc | 4 +- .../basic_source_line_resolver_types.h | 1 - .../basic_source_line_resolver_unittest.cc | 7 +-- src/processor/exploitability.cc | 1 - src/processor/exploitability_win.cc | 1 - src/processor/fast_source_line_resolver.cc | 20 +++--- .../fast_source_line_resolver_unittest.cc | 6 +- src/processor/microdump_processor.cc | 5 +- src/processor/microdump_stackwalk.cc | 5 +- src/processor/minidump.cc | 63 ++++++++++--------- src/processor/minidump_dump.cc | 1 - src/processor/minidump_processor.cc | 8 +-- src/processor/minidump_processor_unittest.cc | 2 - src/processor/minidump_stackwalk.cc | 5 +- src/processor/module_comparer.cc | 5 +- src/processor/module_serializer.cc | 5 +- src/processor/range_map_unittest.cc | 8 +-- src/processor/stack_frame_symbolizer.cc | 1 - src/processor/stackwalker.cc | 5 +- src/processor/stackwalker_amd64.cc | 9 +-- src/processor/stackwalker_arm.cc | 8 +-- src/processor/stackwalker_arm64.cc | 8 +-- src/processor/stackwalker_mips.cc | 11 ++-- src/processor/stackwalker_ppc.cc | 5 +- src/processor/stackwalker_ppc64.cc | 5 +- src/processor/stackwalker_riscv.cc | 9 +-- src/processor/stackwalker_riscv64.cc | 9 +-- src/processor/stackwalker_selftest.cc | 2 - src/processor/stackwalker_x86.cc | 7 ++- .../static_contained_range_map_unittest.cc | 8 ++- src/processor/static_range_map_unittest.cc | 6 +- src/tools/mac/dump_syms/dump_syms_tool.cc | 6 +- src/tools/windows/converter_exe/escaping.cc | 8 ++- 57 files changed, 189 insertions(+), 189 deletions(-) diff --git a/src/client/ios/exception_handler_no_mach.cc b/src/client/ios/exception_handler_no_mach.cc index 0b2182ea7..969e72a9c 100644 --- a/src/client/ios/exception_handler_no_mach.cc +++ b/src/client/ios/exception_handler_no_mach.cc @@ -33,6 +33,8 @@ #include #include +#include + #include "client/mac/handler/minidump_generator.h" #include "client/ios/exception_handler_no_mach.h" @@ -65,7 +67,7 @@ const int kExceptionSignals[] = { }; const int kNumHandledSignals = sizeof(kExceptionSignals) / sizeof(kExceptionSignals[0]); -struct scoped_ptr old_handlers[kNumHandledSignals]; +struct std::unique_ptr old_handlers[kNumHandledSignals]; static union { #if USE_PROTECTED_ALLOCATIONS diff --git a/src/client/ios/exception_handler_no_mach.h b/src/client/ios/exception_handler_no_mach.h index 57247e617..4d47b70b6 100644 --- a/src/client/ios/exception_handler_no_mach.h +++ b/src/client/ios/exception_handler_no_mach.h @@ -35,7 +35,6 @@ #include #include "client/mac/handler/ucontext_compat.h" -#include "common/scoped_ptr.h" namespace google_breakpad { diff --git a/src/client/linux/handler/exception_handler.h b/src/client/linux/handler/exception_handler.h index f12979322..adeee7069 100644 --- a/src/client/linux/handler/exception_handler.h +++ b/src/client/linux/handler/exception_handler.h @@ -34,12 +34,12 @@ #include #include +#include #include #include "client/linux/crash_generation/crash_generation_client.h" #include "client/linux/handler/minidump_descriptor.h" #include "client/linux/minidump_writer/minidump_writer.h" -#include "common/scoped_ptr.h" #include "common/using_std_string.h" #include "google_breakpad/common/minidump_format.h" @@ -252,7 +252,7 @@ class ExceptionHandler { const MinidumpCallback callback_; void* const callback_context_; - scoped_ptr crash_generation_client_; + std::unique_ptr crash_generation_client_; MinidumpDescriptor minidump_descriptor_; diff --git a/src/client/linux/handler/exception_handler_unittest.cc b/src/client/linux/handler/exception_handler_unittest.cc index d512bd8d7..39917af16 100644 --- a/src/client/linux/handler/exception_handler_unittest.cc +++ b/src/client/linux/handler/exception_handler_unittest.cc @@ -43,6 +43,7 @@ #include #endif +#include #include #include "breakpad_googletest_includes.h" @@ -51,6 +52,7 @@ #include "common/linux/eintr_wrapper.h" #include "common/linux/ignore_ret.h" #include "common/linux/linux_libc_support.h" +#include "common/scoped_ptr.h" #include "common/tests/auto_tempdir.h" #include "common/using_std_string.h" #include "third_party/lss/linux_syscall_support.h" @@ -224,7 +226,7 @@ void ChildCrash(bool use_fd) { const pid_t child = fork(); if (child == 0) { { - google_breakpad::scoped_ptr handler; + std::unique_ptr handler; if (use_fd) { handler.reset(new ExceptionHandler(MinidumpDescriptor(minidump_fd), NULL, NULL, NULL, true, -1)); @@ -280,7 +282,7 @@ TEST(ExceptionHandlerTest, ParallelChildCrashesDontHang) { AutoTempDir temp_dir; const pid_t child = fork(); if (child == 0) { - google_breakpad::scoped_ptr handler( + std::unique_ptr handler( new ExceptionHandler(MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1)); diff --git a/src/client/linux/microdump_writer/microdump_writer_unittest.cc b/src/client/linux/microdump_writer/microdump_writer_unittest.cc index b1d570eb4..640be4b6a 100644 --- a/src/client/linux/microdump_writer/microdump_writer_unittest.cc +++ b/src/client/linux/microdump_writer/microdump_writer_unittest.cc @@ -46,7 +46,6 @@ #include "common/linux/breakpad_getcontext.h" #include "common/linux/eintr_wrapper.h" #include "common/linux/ignore_ret.h" -#include "common/scoped_ptr.h" #include "common/tests/auto_tempdir.h" #include "common/using_std_string.h" diff --git a/src/client/mac/handler/exception_handler.cc b/src/client/mac/handler/exception_handler.cc index 968e551c1..b69ab539d 100644 --- a/src/client/mac/handler/exception_handler.cc +++ b/src/client/mac/handler/exception_handler.cc @@ -37,6 +37,7 @@ #include #include +#include #include "client/mac/handler/exception_handler.h" #include "client/mac/handler/minidump_generator.h" @@ -648,7 +649,7 @@ bool ExceptionHandler::InstallHandler() { sa.sa_sigaction = ExceptionHandler::SignalHandler; sa.sa_flags = SA_SIGINFO; - scoped_ptr old(new struct sigaction); + std::unique_ptr old(new struct sigaction); if (sigaction(SIGABRT, &sa, old.get()) == -1) { return false; } diff --git a/src/client/mac/handler/exception_handler.h b/src/client/mac/handler/exception_handler.h index ec7ffe7e0..d3dcef80c 100644 --- a/src/client/mac/handler/exception_handler.h +++ b/src/client/mac/handler/exception_handler.h @@ -38,10 +38,10 @@ #include #include +#include #include #include "client/mac/handler/ucontext_compat.h" -#include "common/scoped_ptr.h" #if !TARGET_OS_IPHONE #include "client/mac/crash_generation/crash_generation_client.h" @@ -267,11 +267,11 @@ class ExceptionHandler { // Old signal handler for SIGABRT. Used to be able to restore it when // uninstalling. - scoped_ptr old_handler_; + std::unique_ptr old_handler_; #if !TARGET_OS_IPHONE // Client for out-of-process dump generation. - scoped_ptr crash_generation_client_; + std::unique_ptr crash_generation_client_; #endif }; diff --git a/src/client/windows/crash_generation/crash_generation_client.h b/src/client/windows/crash_generation/crash_generation_client.h index f912bf5f9..6afd044e6 100644 --- a/src/client/windows/crash_generation/crash_generation_client.h +++ b/src/client/windows/crash_generation/crash_generation_client.h @@ -34,7 +34,6 @@ #include #include #include "client/windows/common/ipc_protocol.h" -#include "common/scoped_ptr.h" namespace google_breakpad { diff --git a/src/client/windows/crash_generation/crash_generation_server.cc b/src/client/windows/crash_generation/crash_generation_server.cc index 1e7a6ca70..a8689d83e 100644 --- a/src/client/windows/crash_generation/crash_generation_server.cc +++ b/src/client/windows/crash_generation/crash_generation_server.cc @@ -37,9 +37,9 @@ #include #include +#include #include "client/windows/common/auto_critical_section.h" -#include "common/scoped_ptr.h" #include "client/windows/crash_generation/client_info.h" namespace google_breakpad { @@ -429,7 +429,7 @@ void CrashGenerationServer::HandleReadDoneState() { return; } - scoped_ptr client_info( + std::unique_ptr client_info( new ClientInfo(this, msg_.id, msg_.dump_type, diff --git a/src/client/windows/crash_generation/crash_generation_server.h b/src/client/windows/crash_generation/crash_generation_server.h index 74275a748..b7004d6a9 100644 --- a/src/client/windows/crash_generation/crash_generation_server.h +++ b/src/client/windows/crash_generation/crash_generation_server.h @@ -33,7 +33,6 @@ #include #include "client/windows/common/ipc_protocol.h" #include "client/windows/crash_generation/minidump_generator.h" -#include "common/scoped_ptr.h" namespace google_breakpad { class ClientInfo; diff --git a/src/client/windows/handler/exception_handler.cc b/src/client/windows/handler/exception_handler.cc index bc56bd80b..d0da37f34 100644 --- a/src/client/windows/handler/exception_handler.cc +++ b/src/client/windows/handler/exception_handler.cc @@ -37,6 +37,7 @@ #include #include +#include #include "client/windows/common/ipc_protocol.h" #include "common/windows/guid_string.h" @@ -180,7 +181,7 @@ void ExceptionHandler::Initialize( // Attempt to use out-of-process if user has specified a pipe or a // crash generation client. - scoped_ptr client; + std::unique_ptr client; if (crash_generation_client) { client.reset(crash_generation_client); } else if (pipe_name) { diff --git a/src/client/windows/handler/exception_handler.h b/src/client/windows/handler/exception_handler.h index 963572bf3..596ff872d 100644 --- a/src/client/windows/handler/exception_handler.h +++ b/src/client/windows/handler/exception_handler.h @@ -65,12 +65,12 @@ #pragma warning(disable:4530) #include +#include #include #include #include "client/windows/common/ipc_protocol.h" #include "client/windows/crash_generation/crash_generation_client.h" -#include "common/scoped_ptr.h" #include "google_breakpad/common/minidump_format.h" namespace google_breakpad { @@ -385,7 +385,7 @@ class ExceptionHandler { MinidumpCallback callback_; void* callback_context_; - scoped_ptr crash_generation_client_; + std::unique_ptr crash_generation_client_; // The directory in which a minidump will be written, set by the dump_path // argument to the constructor, or set_dump_path. diff --git a/src/client/windows/unittests/exception_handler_death_test.cc b/src/client/windows/unittests/exception_handler_death_test.cc index 50d3fda9d..3129aab1c 100644 --- a/src/client/windows/unittests/exception_handler_death_test.cc +++ b/src/client/windows/unittests/exception_handler_death_test.cc @@ -36,6 +36,7 @@ #include #include +#include #include #include "breakpad_googletest_includes.h" @@ -127,7 +128,7 @@ TEST_F(ExceptionHandlerDeathTest, InProcTest) { // the semantics of the exception handler being inherited/not // inherited across CreateProcess(). ASSERT_TRUE(DoesPathExist(temp_path_)); - scoped_ptr exc( + std::unique_ptr exc( new google_breakpad::ExceptionHandler( temp_path_, NULL, @@ -152,7 +153,7 @@ void clientDumpCallback(void* dump_context, void ExceptionHandlerDeathTest::DoCrashAccessViolation( const OutOfProcGuarantee out_of_proc_guarantee) { - scoped_ptr exc; + std::unique_ptr exc; if (out_of_proc_guarantee == OUT_OF_PROC_GUARANTEED) { google_breakpad::CrashGenerationClient* client = @@ -314,7 +315,7 @@ wstring find_minidump_in_directory(const wstring& directory) { TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemory) { ASSERT_TRUE(DoesPathExist(temp_path_)); - scoped_ptr exc( + std::unique_ptr exc( new google_breakpad::ExceptionHandler( temp_path_, NULL, @@ -406,7 +407,7 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemory) { TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMinBound) { ASSERT_TRUE(DoesPathExist(temp_path_)); - scoped_ptr exc( + std::unique_ptr exc( new google_breakpad::ExceptionHandler( temp_path_, NULL, @@ -499,7 +500,7 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMinBound) { TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMaxBound) { ASSERT_TRUE(DoesPathExist(temp_path_)); - scoped_ptr exc( + std::unique_ptr exc( new google_breakpad::ExceptionHandler( temp_path_, NULL, diff --git a/src/common/basictypes.h b/src/common/basictypes.h index 79c9b7756..26b997d08 100644 --- a/src/common/basictypes.h +++ b/src/common/basictypes.h @@ -36,7 +36,7 @@ namespace google_breakpad { // that has been marked with __attribute__((warn_unused_result)), wrap it with // this. Example: // -// scoped_ptr my_var = ...; +// std::unique_ptr my_var = ...; // if (TakeOwnership(my_var.get()) == SUCCESS) // ignore_result(my_var.release()); // diff --git a/src/common/dwarf/functioninfo.cc b/src/common/dwarf/functioninfo.cc index 5b0ce81a4..39c24c8cb 100644 --- a/src/common/dwarf/functioninfo.cc +++ b/src/common/dwarf/functioninfo.cc @@ -38,12 +38,12 @@ #include #include +#include #include #include #include "common/dwarf/functioninfo.h" #include "common/dwarf/bytereader.h" -#include "common/scoped_ptr.h" #include "common/using_std_string.h" namespace google_breakpad { @@ -164,7 +164,7 @@ void CUFunctionInfoHandler::ProcessAttributeUnsigned(uint64_t offset, GetSectionByName(sections_, ".debug_line"); assert(iter != sections_.end()); - scoped_ptr lireader(new LineInfo(iter->second.first + data, + std::unique_ptr lireader(new LineInfo(iter->second.first + data, iter->second.second - data, reader_, linehandler_)); lireader->Start(); diff --git a/src/common/dwarf_cu_to_module.cc b/src/common/dwarf_cu_to_module.cc index 613f97854..edd3a99bf 100644 --- a/src/common/dwarf_cu_to_module.cc +++ b/src/common/dwarf_cu_to_module.cc @@ -960,7 +960,7 @@ void DwarfCUToModule::FuncHandler::Finish() { StringView name = name_.empty() ? name_omitted : name_; // Create a Module::Function based on the data we've gathered, and // add it to the functions_ list. - scoped_ptr func(new Module::Function(name, low_pc_)); + std::unique_ptr func(new Module::Function(name, low_pc_)); func->ranges = ranges; func->parameter_size = 0; // If the name was unqualified, prefer the Extern name if there's a mismatch diff --git a/src/common/dwarf_cu_to_module.h b/src/common/dwarf_cu_to_module.h index 82c25091d..90adde1ca 100644 --- a/src/common/dwarf_cu_to_module.h +++ b/src/common/dwarf_cu_to_module.h @@ -40,6 +40,7 @@ #include +#include #include #include @@ -47,7 +48,6 @@ #include "common/module.h" #include "common/dwarf/dwarf2diehandler.h" #include "common/dwarf/dwarf2reader.h" -#include "common/scoped_ptr.h" #include "common/using_std_string.h" namespace google_breakpad { @@ -118,7 +118,7 @@ class DwarfCUToModule: public RootDIEHandler { const bool handle_inter_cu_refs_; // Inter-compilation unit data used internally by the handlers. - scoped_ptr file_private_; + std::unique_ptr file_private_; std::vector uncompressed_sections_; }; @@ -391,10 +391,10 @@ class DwarfCUToModule: public RootDIEHandler { LineToModuleHandler* line_reader_; // This compilation unit's context. - scoped_ptr cu_context_; + std::unique_ptr cu_context_; // A context for our children. - scoped_ptr child_context_; + std::unique_ptr child_context_; // True if this compilation unit has source line information. bool has_source_line_info_; diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index 316d58a30..1b7d13138 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -55,6 +55,7 @@ #include #endif +#include #include #include #include @@ -103,7 +104,6 @@ using google_breakpad::PageAllocator; #ifndef NO_STABS_SUPPORT using google_breakpad::StabsToModule; #endif -using google_breakpad::scoped_ptr; using google_breakpad::wasteful_vector; // Define AARCH64 ELF architecture if host machine does not include this define. @@ -1159,7 +1159,7 @@ bool InitModuleForElfClass(const typename ElfClass::Ehdr* elf_header, const string& obj_filename, const string& obj_os, const string& module_id, - scoped_ptr& module, + std::unique_ptr& module, bool enable_multiple_field) { PageAllocator allocator; wasteful_vector identifier(&allocator, kDefaultBuildIdSize); @@ -1211,7 +1211,7 @@ bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, *out_module = NULL; - scoped_ptr module; + std::unique_ptr module; if (!InitModuleForElfClass(elf_header, obj_filename, obj_os, module_id, module, options.enable_multiple_field)) { return false; @@ -1324,7 +1324,7 @@ bool WriteSymbolFileHeader(const string& load_path, } int elfclass = ElfClass(elf_header); - scoped_ptr module; + std::unique_ptr module; if (elfclass == ELFCLASS32) { if (!InitModuleForElfClass( reinterpret_cast(elf_header), obj_file, obj_os, diff --git a/src/common/mac/dump_syms.cc b/src/common/mac/dump_syms.cc index 19c1bce1e..c8a1db195 100644 --- a/src/common/mac/dump_syms.cc +++ b/src/common/mac/dump_syms.cc @@ -49,6 +49,7 @@ #include #include +#include #include #include #include @@ -88,7 +89,6 @@ using google_breakpad::mach_o::Segment; using google_breakpad::Module; using google_breakpad::StabsReader; using google_breakpad::StabsToModule; -using google_breakpad::scoped_ptr; using std::make_pair; using std::pair; using std::string; @@ -270,7 +270,7 @@ void DumpSymbols::SetReportWarnings(bool report_warnings) { } string DumpSymbols::Identifier() { - scoped_ptr file_id; + std::unique_ptr file_id; if (from_disk_) { file_id.reset(new FileID(object_filename_.c_str())); @@ -278,7 +278,7 @@ string DumpSymbols::Identifier() { file_id.reset(new FileID(contents_.get(), size_)); } unsigned char identifier_bytes[16]; - scoped_ptr module; + std::unique_ptr module; if (!selected_object_file_) { if (!CreateEmptyModule(module)) return string(); @@ -364,7 +364,7 @@ class DumpSymbols::DumperLineToModule: ByteReader* byte_reader_; // WEAK }; -bool DumpSymbols::CreateEmptyModule(scoped_ptr& module) { +bool DumpSymbols::CreateEmptyModule(std::unique_ptr& module) { // Select an object file, if SetArchitecture hasn't been called to set one // explicitly. if (!selected_object_file_) { @@ -699,7 +699,7 @@ bool DumpSymbols::LoadCommandDumper::SymtabCommand(const ByteBuffer& entries, } bool DumpSymbols::ReadSymbolData(Module** out_module) { - scoped_ptr module; + std::unique_ptr module; if (!CreateEmptyModule(module)) return false; @@ -728,7 +728,7 @@ bool DumpSymbols::ReadSymbolData(Module** out_module) { // header only to |stream|. Return true on success; if an error occurs, report // it and return false. bool DumpSymbols::WriteSymbolFileHeader(std::ostream& stream) { - scoped_ptr module; + std::unique_ptr module; if (!CreateEmptyModule(module)) return false; diff --git a/src/common/mac/dump_syms.h b/src/common/mac/dump_syms.h index 2b09e1663..31d246ee4 100644 --- a/src/common/mac/dump_syms.h +++ b/src/common/mac/dump_syms.h @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -146,7 +147,7 @@ class DumpSymbols { cpu_type_t cpu_type, cpu_subtype_t cpu_subtype); // Creates an empty module object. - bool CreateEmptyModule(scoped_ptr& module); + bool CreateEmptyModule(std::unique_ptr& module); // Process the split dwarf file referenced by reader. void StartProcessSplitDwarf(google_breakpad::CompilationUnit* reader, diff --git a/src/common/mac/file_id.cc b/src/common/mac/file_id.cc index ee4a66bbe..f080a2114 100644 --- a/src/common/mac/file_id.cc +++ b/src/common/mac/file_id.cc @@ -42,8 +42,9 @@ #include #include +#include + #include "common/mac/macho_id.h" -#include "common/scoped_ptr.h" using MacFileUtilities::MachoID; @@ -61,7 +62,7 @@ FileID::FileID(void* memory, size_t size) bool FileID::MachoIdentifier(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype, unsigned char identifier[16]) { - scoped_ptr macho; + std::unique_ptr macho; if (memory_) { macho.reset(new MachoID(memory_, size_)); } else { diff --git a/src/common/scoped_ptr.h b/src/common/scoped_ptr.h index e7d2445ff..cec94c29b 100644 --- a/src/common/scoped_ptr.h +++ b/src/common/scoped_ptr.h @@ -32,8 +32,7 @@ #define COMMON_SCOPED_PTR_H_ // This is an implementation designed to match the anticipated future TR2 -// implementation of the scoped_ptr class, and its closely-related brethren, -// scoped_array. +// implementation of the scoped_array class. #include #include @@ -41,23 +40,14 @@ #include -namespace google_breakpad { - -template > -using scoped_ptr = std::unique_ptr; +#include "common/scoped_ptr.h" -// A function to convert T* into scoped_ptr -// Doing e.g. make_scoped_ptr(new FooBarBaz(arg)) is a shorter notation -// for scoped_ptr >(new FooBarBaz(arg)) -template -scoped_ptr make_scoped_ptr(T* ptr) { - return scoped_ptr(ptr); -} +namespace google_breakpad { -// scoped_array is like scoped_ptr, except that the caller must allocate +// scoped_array is like std::unique_ptr, except that the caller must allocate // with new [] and the destructor deletes objects with delete []. // -// As with scoped_ptr, a scoped_array either points to an object +// As with std::unique_ptr, a scoped_array either points to an object // or is NULL. A scoped_array owns the object that it points to. // scoped_array is thread-compatible, and once you index into it, // the returned objects have only the threadsafety guarantees of T. diff --git a/src/common/solaris/dump_symbols.cc b/src/common/solaris/dump_symbols.cc index 09e5b376b..6077ac114 100644 --- a/src/common/solaris/dump_symbols.cc +++ b/src/common/solaris/dump_symbols.cc @@ -46,7 +46,6 @@ #include #include -#include "common/scoped_ptr.h" #include "common/solaris/dump_symbols.h" #include "common/solaris/file_id.h" #include "common/solaris/guid_creator.h" diff --git a/src/google_breakpad/processor/microdump.h b/src/google_breakpad/processor/microdump.h index 7c2f3e662..2a2bdec6c 100644 --- a/src/google_breakpad/processor/microdump.h +++ b/src/google_breakpad/processor/microdump.h @@ -38,10 +38,10 @@ #ifndef GOOGLE_BREAKPAD_PROCESSOR_MICRODUMP_H__ #define GOOGLE_BREAKPAD_PROCESSOR_MICRODUMP_H__ +#include #include #include -#include "common/scoped_ptr.h" #include "common/using_std_string.h" #include "google_breakpad/processor/dump_context.h" #include "google_breakpad/processor/memory_region.h" @@ -121,10 +121,10 @@ class Microdump { string GetCrashReason() { return crash_reason_; } uint64_t GetCrashAddress() { return crash_address_; } private: - scoped_ptr context_; - scoped_ptr stack_region_; - scoped_ptr modules_; - scoped_ptr system_info_; + std::unique_ptr context_; + std::unique_ptr stack_region_; + std::unique_ptr modules_; + std::unique_ptr system_info_; string crash_reason_; uint64_t crash_address_; }; diff --git a/src/processor/basic_source_line_resolver.cc b/src/processor/basic_source_line_resolver.cc index 220bd746c..43128e7b7 100644 --- a/src/processor/basic_source_line_resolver.cc +++ b/src/processor/basic_source_line_resolver.cc @@ -352,7 +352,7 @@ void BasicSourceLineResolver::Module::LookupAddress( WindowsFrameInfo* BasicSourceLineResolver::Module::FindWindowsFrameInfo( const StackFrame* frame) const { MemAddr address = frame->instruction - frame->module->base_address(); - scoped_ptr result(new WindowsFrameInfo()); + std::unique_ptr result(new WindowsFrameInfo()); // We only know about WindowsFrameInfo::STACK_INFO_FRAME_DATA and // WindowsFrameInfo::STACK_INFO_FPO. Prefer them in this order. @@ -415,7 +415,7 @@ CFIFrameInfo* BasicSourceLineResolver::Module::FindCFIFrameInfo( // Create a frame info structure, and populate it with the rules from // the STACK CFI INIT record. - scoped_ptr rules(new CFIFrameInfo()); + std::unique_ptr rules(new CFIFrameInfo()); if (!ParseCFIRuleSet(initial_rules, rules.get())) return NULL; diff --git a/src/processor/basic_source_line_resolver_types.h b/src/processor/basic_source_line_resolver_types.h index 3c8b01c70..66fcbc6b8 100644 --- a/src/processor/basic_source_line_resolver_types.h +++ b/src/processor/basic_source_line_resolver_types.h @@ -39,7 +39,6 @@ #include #include -#include "common/scoped_ptr.h" #include "google_breakpad/processor/basic_source_line_resolver.h" #include "processor/source_line_resolver_base_types.h" diff --git a/src/processor/basic_source_line_resolver_unittest.cc b/src/processor/basic_source_line_resolver_unittest.cc index c496cbb97..8e51d24d1 100644 --- a/src/processor/basic_source_line_resolver_unittest.cc +++ b/src/processor/basic_source_line_resolver_unittest.cc @@ -33,10 +33,10 @@ #include #include +#include #include #include "breakpad_googletest_includes.h" -#include "common/scoped_ptr.h" #include "common/using_std_string.h" #include "google_breakpad/processor/basic_source_line_resolver.h" #include "google_breakpad/processor/code_module.h" @@ -55,7 +55,6 @@ using google_breakpad::CodeModule; using google_breakpad::MemoryRegion; using google_breakpad::StackFrame; using google_breakpad::WindowsFrameInfo; -using google_breakpad::scoped_ptr; using google_breakpad::SymbolParseHelper; class TestCodeModule : public CodeModule { @@ -187,8 +186,8 @@ TEST_F(TestBasicSourceLineResolver, TestLoadAndResolve) StackFrame frame; - scoped_ptr windows_frame_info; - scoped_ptr cfi_frame_info; + std::unique_ptr windows_frame_info; + std::unique_ptr cfi_frame_info; frame.instruction = 0x1000; frame.module = NULL; resolver.FillSourceLineInfo(&frame, nullptr); diff --git a/src/processor/exploitability.cc b/src/processor/exploitability.cc index e8b817449..79c7b088d 100644 --- a/src/processor/exploitability.cc +++ b/src/processor/exploitability.cc @@ -39,7 +39,6 @@ #include -#include "common/scoped_ptr.h" #include "google_breakpad/processor/exploitability.h" #include "google_breakpad/processor/minidump.h" #include "google_breakpad/processor/process_state.h" diff --git a/src/processor/exploitability_win.cc b/src/processor/exploitability_win.cc index b94e87255..f124e613d 100644 --- a/src/processor/exploitability_win.cc +++ b/src/processor/exploitability_win.cc @@ -41,7 +41,6 @@ #include "processor/exploitability_win.h" -#include "common/scoped_ptr.h" #include "google_breakpad/common/minidump_exception_win32.h" #include "google_breakpad/processor/minidump.h" #include "processor/disassembler_x86.h" diff --git a/src/processor/fast_source_line_resolver.cc b/src/processor/fast_source_line_resolver.cc index 044eea356..763ad8873 100644 --- a/src/processor/fast_source_line_resolver.cc +++ b/src/processor/fast_source_line_resolver.cc @@ -46,10 +46,10 @@ #include #include +#include #include #include -#include "common/scoped_ptr.h" #include "common/using_std_string.h" #include "processor/fast_source_line_resolver_types.h" #include "processor/logging.h" @@ -79,9 +79,9 @@ void FastSourceLineResolver::Module::LookupAddress( // extent of the PUBLIC symbol we find, below. This does mean we // need to check that address indeed falls within the function we // find; do the range comparison in an overflow-friendly way. - scoped_ptr func(new Function); + std::unique_ptr func(new Function); const Function* func_ptr = 0; - scoped_ptr public_symbol(new PublicSymbol); + std::unique_ptr public_symbol(new PublicSymbol); const PublicSymbol* public_symbol_ptr = 0; MemAddr function_base; MemAddr function_size; @@ -95,7 +95,7 @@ void FastSourceLineResolver::Module::LookupAddress( frame->function_base = frame->module->base_address() + function_base; frame->is_multiple = func->is_multiple; - scoped_ptr line(new Line); + std::unique_ptr line(new Line); const Line* line_ptr = 0; MemAddr line_base; if (func->lines.RetrieveRange(address, line_ptr, &line_base, NULL)) { @@ -133,13 +133,13 @@ void FastSourceLineResolver::Module::ConstructInlineFrames( } for (const char* inline_ptr : inline_ptrs) { - scoped_ptr in(new Inline); + std::unique_ptr in(new Inline); in->CopyFrom(inline_ptr); unique_ptr new_frame = unique_ptr(new StackFrame(*frame)); auto origin_iter = inline_origins_.find(in->origin_id); if (origin_iter != inline_origins_.end()) { - scoped_ptr origin(new InlineOrigin); + std::unique_ptr origin(new InlineOrigin); origin->CopyFrom(origin_iter.GetValuePtr()); new_frame->function_name = origin->name; } else { @@ -279,7 +279,7 @@ bool FastSourceLineResolver::Module::LoadMapFromMemory( WindowsFrameInfo* FastSourceLineResolver::Module::FindWindowsFrameInfo( const StackFrame* frame) const { MemAddr address = frame->instruction - frame->module->base_address(); - scoped_ptr result(new WindowsFrameInfo()); + std::unique_ptr result(new WindowsFrameInfo()); // We only know about WindowsFrameInfo::STACK_INFO_FRAME_DATA and // WindowsFrameInfo::STACK_INFO_FPO. Prefer them in this order. @@ -303,7 +303,7 @@ WindowsFrameInfo* FastSourceLineResolver::Module::FindWindowsFrameInfo( // below. However, this does mean we need to check that ADDRESS // falls within the retrieved function's range; do the range // comparison in an overflow-friendly way. - scoped_ptr function(new Function); + std::unique_ptr function(new Function); const Function* function_ptr = 0; MemAddr function_base, function_size; if (functions_.RetrieveNearestRange(address, function_ptr, @@ -317,7 +317,7 @@ WindowsFrameInfo* FastSourceLineResolver::Module::FindWindowsFrameInfo( // PUBLIC symbols might have a parameter size. Use the function we // found above to limit the range the public symbol covers. - scoped_ptr public_symbol(new PublicSymbol); + std::unique_ptr public_symbol(new PublicSymbol); const PublicSymbol* public_symbol_ptr = 0; MemAddr public_address; if (public_symbols_.Retrieve(address, public_symbol_ptr, &public_address) && @@ -346,7 +346,7 @@ CFIFrameInfo* FastSourceLineResolver::Module::FindCFIFrameInfo( // Create a frame info structure, and populate it with the rules from // the STACK CFI INIT record. - scoped_ptr rules(new CFIFrameInfo()); + std::unique_ptr rules(new CFIFrameInfo()); if (!ParseCFIRuleSet(initial_rules, rules.get())) return NULL; diff --git a/src/processor/fast_source_line_resolver_unittest.cc b/src/processor/fast_source_line_resolver_unittest.cc index 5a24d2870..df2536571 100644 --- a/src/processor/fast_source_line_resolver_unittest.cc +++ b/src/processor/fast_source_line_resolver_unittest.cc @@ -43,6 +43,7 @@ #include #include +#include #include #include @@ -67,7 +68,6 @@ using google_breakpad::CodeModule; using google_breakpad::MemoryRegion; using google_breakpad::StackFrame; using google_breakpad::WindowsFrameInfo; -using google_breakpad::scoped_ptr; class TestCodeModule : public CodeModule { public: @@ -215,8 +215,8 @@ TEST_F(TestFastSourceLineResolver, TestLoadAndResolve) { ASSERT_TRUE(fast_resolver.HasModule(&module2)); StackFrame frame; - scoped_ptr windows_frame_info; - scoped_ptr cfi_frame_info; + std::unique_ptr windows_frame_info; + std::unique_ptr cfi_frame_info; frame.instruction = 0x1000; frame.module = NULL; fast_resolver.FillSourceLineInfo(&frame, nullptr); diff --git a/src/processor/microdump_processor.cc b/src/processor/microdump_processor.cc index 3c25d5cf0..5493b1c8f 100644 --- a/src/processor/microdump_processor.cc +++ b/src/processor/microdump_processor.cc @@ -38,6 +38,7 @@ #include +#include #include #include "common/using_std_string.h" @@ -64,7 +65,7 @@ ProcessResult MicrodumpProcessor::Process(Microdump *microdump, process_state->Clear(); process_state->modules_ = microdump->GetModules()->Copy(); - scoped_ptr stackwalker( + std::unique_ptr stackwalker( Stackwalker::StackwalkerForCPU( &process_state->system_info_, microdump->GetContext(), @@ -73,7 +74,7 @@ ProcessResult MicrodumpProcessor::Process(Microdump *microdump, /* unloaded_modules= */ NULL, frame_symbolizer_)); - scoped_ptr stack(new CallStack()); + std::unique_ptr stack(new CallStack()); if (stackwalker.get()) { if (!stackwalker->Walk(stack.get(), &process_state->modules_without_symbols_, diff --git a/src/processor/microdump_stackwalk.cc b/src/processor/microdump_stackwalk.cc index 222310f76..585c40c93 100644 --- a/src/processor/microdump_stackwalk.cc +++ b/src/processor/microdump_stackwalk.cc @@ -38,11 +38,11 @@ #include #include +#include #include #include #include "common/path_helper.h" -#include "common/scoped_ptr.h" #include "common/using_std_string.h" #include "google_breakpad/processor/basic_source_line_resolver.h" #include "google_breakpad/processor/microdump.h" @@ -69,7 +69,6 @@ using google_breakpad::Microdump; using google_breakpad::MicrodumpProcessor; using google_breakpad::ProcessResult; using google_breakpad::ProcessState; -using google_breakpad::scoped_ptr; using google_breakpad::SimpleSymbolSupplier; using google_breakpad::StackFrameSymbolizer; @@ -96,7 +95,7 @@ int PrintMicrodumpProcess(const Options& options) { file_stream.read(&bytes[0], bytes.size()); string microdump_content(&bytes[0], bytes.size()); - scoped_ptr symbol_supplier; + std::unique_ptr symbol_supplier; if (!options.symbol_paths.empty()) { symbol_supplier.reset(new SimpleSymbolSupplier(options.symbol_paths)); } diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 2099a2a61..5d937c9ca 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -60,6 +60,7 @@ #include #include #include +#include #include #include "common/macros.h" @@ -258,7 +259,7 @@ inline void Swap(uint16_t* data, size_t size_in_bytes) { // CPU's endianness into consideration. It doesn't seems worth the trouble // of making it a dependency when we don't care about anything but UTF-16. string* UTF16ToUTF8(const vector& in, bool swap) { - scoped_ptr out(new string()); + std::unique_ptr out(new string()); // Set the string's initial capacity to the number of UTF-16 characters, // because the UTF-8 representation will always be at least this long. @@ -362,7 +363,7 @@ void ConvertUTF16BufferToUTF8String(const uint16_t* utf16_data, size_t byte_length = word_length * sizeof(utf16_data[0]); vector utf16_vector(word_length); memcpy(&utf16_vector[0], &utf16_data[0], byte_length); - scoped_ptr temp(UTF16ToUTF8(utf16_vector, swap)); + std::unique_ptr temp(UTF16ToUTF8(utf16_vector, swap)); if (temp.get()) { utf8_result->assign(*temp); } @@ -506,7 +507,7 @@ bool MinidumpContext::Read(uint32_t expected_size) { expected_size >= sizeof(MDRawContextAMD64))) { BPLOG(INFO) << "MinidumpContext: looks like AMD64 context"; - scoped_ptr context_amd64(new MDRawContextAMD64()); + std::unique_ptr context_amd64(new MDRawContextAMD64()); if (!minidump_->ReadBytes(context_amd64.get(), sizeof(MDRawContextAMD64))) { BPLOG(ERROR) << "MinidumpContext could not read amd64 context"; @@ -628,7 +629,7 @@ bool MinidumpContext::Read(uint32_t expected_size) { Swap(&context_flags); uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; - scoped_ptr context_ppc64(new MDRawContextPPC64()); + std::unique_ptr context_ppc64(new MDRawContextPPC64()); if (cpu_type == 0) { if (minidump_->GetContextCPUFlagsFromSystemInfo(&cpu_type)) { @@ -724,7 +725,7 @@ bool MinidumpContext::Read(uint32_t expected_size) { if (minidump_->swap()) Swap(&context_flags); - scoped_ptr context_arm64(new MDRawContextARM64_Old()); + std::unique_ptr context_arm64(new MDRawContextARM64_Old()); uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK; if (cpu_type == 0) { @@ -783,7 +784,7 @@ bool MinidumpContext::Read(uint32_t expected_size) { } } - scoped_ptr new_context(new MDRawContextARM64()); + std::unique_ptr new_context(new MDRawContextARM64()); ConvertOldARM64Context(*context_arm64.get(), new_context.get()); SetContextFlags(new_context->context_flags); SetContextARM64(new_context.release()); @@ -837,7 +838,7 @@ bool MinidumpContext::Read(uint32_t expected_size) { } } - scoped_ptr context_x86(new MDRawContextX86()); + std::unique_ptr context_x86(new MDRawContextX86()); // Set the context_flags member, which has already been read, and // read the rest of the structure beginning with the first member @@ -920,7 +921,7 @@ bool MinidumpContext::Read(uint32_t expected_size) { return false; } - scoped_ptr context_ppc(new MDRawContextPPC()); + std::unique_ptr context_ppc(new MDRawContextPPC()); // Set the context_flags member, which has already been read, and // read the rest of the structure beginning with the first member @@ -996,7 +997,7 @@ bool MinidumpContext::Read(uint32_t expected_size) { return false; } - scoped_ptr context_sparc(new MDRawContextSPARC()); + std::unique_ptr context_sparc(new MDRawContextSPARC()); // Set the context_flags member, which has already been read, and // read the rest of the structure beginning with the first member @@ -1052,7 +1053,7 @@ bool MinidumpContext::Read(uint32_t expected_size) { return false; } - scoped_ptr context_arm(new MDRawContextARM()); + std::unique_ptr context_arm(new MDRawContextARM()); // Set the context_flags member, which has already been read, and // read the rest of the structure beginning with the first member @@ -1107,7 +1108,7 @@ bool MinidumpContext::Read(uint32_t expected_size) { return false; } - scoped_ptr context_arm64(new MDRawContextARM64()); + std::unique_ptr context_arm64(new MDRawContextARM64()); // Set the context_flags member, which has already been read, and // read the rest of the structure beginning with the first member @@ -1162,7 +1163,7 @@ bool MinidumpContext::Read(uint32_t expected_size) { return false; } - scoped_ptr context_mips(new MDRawContextMIPS()); + std::unique_ptr context_mips(new MDRawContextMIPS()); // Set the context_flags member, which has already been read, and // read the rest of the structure beginning with the first member @@ -1227,7 +1228,7 @@ bool MinidumpContext::Read(uint32_t expected_size) { return false; } - scoped_ptr context_riscv(new MDRawContextRISCV()); + std::unique_ptr context_riscv(new MDRawContextRISCV()); // Set the context_flags member, which has already been read, and // read the rest of the structure beginning with the first member @@ -1304,7 +1305,7 @@ bool MinidumpContext::Read(uint32_t expected_size) { return false; } - scoped_ptr context_riscv64( + std::unique_ptr context_riscv64( new MDRawContextRISCV64()); // Set the context_flags member, which has already been read, and @@ -1541,7 +1542,7 @@ const uint8_t* MinidumpMemoryRegion::GetMemory() const { return NULL; } - scoped_ptr< vector > memory( + std::unique_ptr< vector > memory( new vector(descriptor_->memory.data_size)); if (!minidump_->ReadBytes(&(*memory)[0], descriptor_->memory.data_size)) { @@ -1822,7 +1823,7 @@ MinidumpContext* MinidumpThread::GetContext() { return NULL; } - scoped_ptr context(new MinidumpContext(minidump_)); + std::unique_ptr context(new MinidumpContext(minidump_)); if (!context->Read(thread_.thread_context.data_size)) { BPLOG(ERROR) << "MinidumpThread cannot read context"; @@ -1971,7 +1972,7 @@ bool MinidumpThreadList::Read(uint32_t expected_size) { } if (thread_count != 0) { - scoped_ptr threads( + std::unique_ptr threads( new MinidumpThreads(thread_count, MinidumpThread(minidump_))); for (unsigned int thread_index = 0; @@ -2211,7 +2212,7 @@ bool MinidumpThreadNameList::Read(uint32_t expected_size) { } if (thread_name_count != 0) { - scoped_ptr thread_names(new MinidumpThreadNames( + std::unique_ptr thread_names(new MinidumpThreadNames( thread_name_count, MinidumpThreadName(minidump_))); for (unsigned int thread_name_index = 0; @@ -2568,7 +2569,7 @@ string MinidumpModule::debug_file() const { // GetMiscRecord already byte-swapped the data[] field if it contains // UTF-16, so pass false as the swap argument. - scoped_ptr new_file(UTF16ToUTF8(string_utf16, false)); + std::unique_ptr new_file(UTF16ToUTF8(string_utf16, false)); if (new_file.get() != nullptr) { file = string(*new_file); } @@ -2754,7 +2755,7 @@ const uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) { // variable-sized due to their pdb_file_name fields; these structures // are not MDCVInfoPDB70_minsize or MDCVInfoPDB20_minsize and treating // them as such would result in incomplete structures or overruns. - scoped_ptr< vector > cv_record( + std::unique_ptr< vector > cv_record( new vector(module_.cv_record.data_size)); if (!minidump_->ReadBytes(&(*cv_record)[0], module_.cv_record.data_size)) { @@ -2896,7 +2897,7 @@ const MDImageDebugMisc* MinidumpModule::GetMiscRecord(uint32_t* size) { // because the MDImageDebugMisc is variable-sized due to its data field; // this structure is not MDImageDebugMisc_minsize and treating it as such // would result in an incomplete structure or an overrun. - scoped_ptr< vector > misc_record_mem( + std::unique_ptr< vector > misc_record_mem( new vector(module_.misc_record.data_size)); MDImageDebugMisc* misc_record = reinterpret_cast(&(*misc_record_mem)[0]); @@ -3170,7 +3171,7 @@ bool MinidumpModuleList::Read(uint32_t expected_size) { } if (module_count != 0) { - scoped_ptr modules( + std::unique_ptr modules( new MinidumpModules(module_count, MinidumpModule(minidump_))); for (uint32_t module_index = 0; module_index < module_count; @@ -3479,7 +3480,7 @@ bool MinidumpMemoryList::Read(uint32_t expected_size) { } if (region_count != 0) { - scoped_ptr descriptors( + std::unique_ptr descriptors( new MemoryDescriptors(region_count)); // Read the entire array in one fell swoop, instead of reading one entry @@ -3490,7 +3491,7 @@ bool MinidumpMemoryList::Read(uint32_t expected_size) { return false; } - scoped_ptr regions( + std::unique_ptr regions( new MemoryRegions(region_count, MinidumpMemoryRegion(minidump_))); for (unsigned int region_index = 0; @@ -3691,7 +3692,7 @@ MinidumpContext* MinidumpException::GetContext() { return NULL; } - scoped_ptr context(new MinidumpContext(minidump_)); + std::unique_ptr context(new MinidumpContext(minidump_)); // Don't log as an error if we can still fall back on the thread's context // (which must be possible if we got this far.) @@ -4383,7 +4384,7 @@ bool MinidumpUnloadedModuleList::Read(uint32_t expected_size) { } if (number_of_entries != 0) { - scoped_ptr modules( + std::unique_ptr modules( new MinidumpUnloadedModules(number_of_entries, MinidumpUnloadedModule(minidump_))); @@ -5052,7 +5053,7 @@ bool MinidumpMemoryInfoList::Read(uint32_t expected_size) { } if (header.number_of_entries != 0) { - scoped_ptr infos( + std::unique_ptr infos( new MinidumpMemoryInfos(header_number_of_entries, MinidumpMemoryInfo(minidump_))); @@ -5264,11 +5265,11 @@ bool MinidumpLinuxMapsList::Read(uint32_t expected_size) { return false; } - scoped_ptr maps(new MinidumpLinuxMappings()); + std::unique_ptr maps(new MinidumpLinuxMappings()); // Push mapping data into wrapper classes. for (size_t i = 0; i < all_regions.size(); i++) { - scoped_ptr ele(new MinidumpLinuxMaps(minidump_)); + std::unique_ptr ele(new MinidumpLinuxMaps(minidump_)); ele->region_ = all_regions[i]; ele->valid_ = true; maps->push_back(ele.release()); @@ -5781,7 +5782,7 @@ bool Minidump::Read() { } if (header_.stream_count != 0) { - scoped_ptr directory( + std::unique_ptr directory( new MinidumpDirectoryEntries(header_.stream_count)); // Read the entire array in one fell swoop, instead of reading one entry @@ -6493,7 +6494,7 @@ T* Minidump::GetStream(T** stream) { return NULL; } - scoped_ptr new_stream(new T(this)); + std::unique_ptr new_stream(new T(this)); if (!new_stream->Read(stream_length)) { BPLOG(ERROR) << "GetStream could not read stream type " << stream_type; diff --git a/src/processor/minidump_dump.cc b/src/processor/minidump_dump.cc index d3c33ad4f..e39d54884 100644 --- a/src/processor/minidump_dump.cc +++ b/src/processor/minidump_dump.cc @@ -40,7 +40,6 @@ #include #include "common/path_helper.h" -#include "common/scoped_ptr.h" #include "google_breakpad/processor/minidump.h" #include "processor/logging.h" diff --git a/src/processor/minidump_processor.cc b/src/processor/minidump_processor.cc index f4084005e..006787243 100644 --- a/src/processor/minidump_processor.cc +++ b/src/processor/minidump_processor.cc @@ -39,10 +39,10 @@ #include #include #include +#include #include #include -#include "common/scoped_ptr.h" #include "common/stdio_wrapper.h" #include "common/using_std_string.h" #include "google_breakpad/processor/call_stack.h" @@ -344,7 +344,7 @@ ProcessResult MinidumpProcessor::Process( // returns. process_state->modules_ is owned by the ProcessState object // (just like the StackFrame objects), and is much more suitable for this // task. - scoped_ptr stackwalker( + std::unique_ptr stackwalker( Stackwalker::StackwalkerForCPU(process_state->system_info(), context, thread_memory, @@ -352,7 +352,7 @@ ProcessResult MinidumpProcessor::Process( process_state->unloaded_modules_, frame_symbolizer_)); - scoped_ptr stack(new CallStack()); + std::unique_ptr stack(new CallStack()); if (stackwalker.get()) { if (!stackwalker->Walk(stack.get(), &process_state->modules_without_symbols_, @@ -393,7 +393,7 @@ ProcessResult MinidumpProcessor::Process( // If an exploitability run was requested we perform the platform specific // rating. if (enable_exploitability_) { - scoped_ptr exploitability( + std::unique_ptr exploitability( Exploitability::ExploitabilityForPlatform( dump, process_state, enable_objdump_for_exploitability_)); // The engine will be null if the platform is not supported diff --git a/src/processor/minidump_processor_unittest.cc b/src/processor/minidump_processor_unittest.cc index c9cf9d2b2..caef4f2b7 100644 --- a/src/processor/minidump_processor_unittest.cc +++ b/src/processor/minidump_processor_unittest.cc @@ -42,7 +42,6 @@ #include #include "breakpad_googletest_includes.h" -#include "common/scoped_ptr.h" #include "common/using_std_string.h" #include "google_breakpad/processor/basic_source_line_resolver.h" #include "google_breakpad/processor/call_stack.h" @@ -179,7 +178,6 @@ using google_breakpad::MockMinidumpThreadList; using google_breakpad::MockMinidumpUnloadedModule; using google_breakpad::MockMinidumpUnloadedModuleList; using google_breakpad::ProcessState; -using google_breakpad::scoped_ptr; using google_breakpad::SymbolSupplier; using google_breakpad::SystemInfo; using ::testing::_; diff --git a/src/processor/minidump_stackwalk.cc b/src/processor/minidump_stackwalk.cc index 74b41acf7..7fab30f4b 100644 --- a/src/processor/minidump_stackwalk.cc +++ b/src/processor/minidump_stackwalk.cc @@ -40,11 +40,11 @@ #include #include +#include #include #include #include "common/path_helper.h" -#include "common/scoped_ptr.h" #include "common/using_std_string.h" #include "google_breakpad/processor/basic_source_line_resolver.h" #include "google_breakpad/processor/minidump.h" @@ -74,7 +74,6 @@ using google_breakpad::MinidumpThreadList; using google_breakpad::MinidumpProcessor; using google_breakpad::ProcessState; using google_breakpad::SimpleSymbolSupplier; -using google_breakpad::scoped_ptr; // Processes |options.minidump_file| using MinidumpProcessor. // |options.symbol_path|, if non-empty, is the base directory of a @@ -88,7 +87,7 @@ using google_breakpad::scoped_ptr; // call stacks for each thread contained in the minidump. All information // is printed to stdout. bool PrintMinidumpProcess(const Options& options) { - scoped_ptr symbol_supplier; + std::unique_ptr symbol_supplier; if (!options.symbol_paths.empty()) { // TODO(mmentovai): check existence of symbol_path if specified? symbol_supplier.reset(new SimpleSymbolSupplier(options.symbol_paths)); diff --git a/src/processor/module_comparer.cc b/src/processor/module_comparer.cc index a6413038a..ccc2e4724 100644 --- a/src/processor/module_comparer.cc +++ b/src/processor/module_comparer.cc @@ -38,6 +38,7 @@ #include "processor/module_comparer.h" #include +#include #include #include "common/scoped_ptr.h" @@ -56,8 +57,8 @@ namespace google_breakpad { bool ModuleComparer::Compare(const string& symbol_data) { - scoped_ptr basic_module(new BasicModule("test_module")); - scoped_ptr fast_module(new FastModule("test_module")); + std::unique_ptr basic_module(new BasicModule("test_module")); + std::unique_ptr fast_module(new FastModule("test_module")); // Load symbol data into basic_module scoped_array buffer(new char[symbol_data.size() + 1]); diff --git a/src/processor/module_serializer.cc b/src/processor/module_serializer.cc index 5a744a56c..7000c8f94 100644 --- a/src/processor/module_serializer.cc +++ b/src/processor/module_serializer.cc @@ -42,6 +42,7 @@ #include #include +#include #include #include "common/scoped_ptr.h" @@ -176,7 +177,7 @@ bool ModuleSerializer::SerializeModuleAndLoadIntoFastResolver( string symbol_data_string(symbol_data.get(), size); symbol_data.reset(); - scoped_ptr code_module( + std::unique_ptr code_module( new BasicCodeModule(0, 0, iter->first, "", "", "", "")); return fast_resolver->LoadModuleUsingMapBuffer(code_module.get(), @@ -215,7 +216,7 @@ bool ModuleSerializer::ConvertOneModule( char* ModuleSerializer::SerializeSymbolFileData(const string& symbol_data, size_t* size) { - scoped_ptr module( + std::unique_ptr module( new BasicSourceLineResolver::Module("no name")); scoped_array buffer(new char[symbol_data.size() + 1]); memcpy(buffer.get(), symbol_data.c_str(), symbol_data.size()); diff --git a/src/processor/range_map_unittest.cc b/src/processor/range_map_unittest.cc index f8e3dfbe5..a15969a57 100644 --- a/src/processor/range_map_unittest.cc +++ b/src/processor/range_map_unittest.cc @@ -43,9 +43,10 @@ #include #include +#include + #include "processor/range_map-inl.h" -#include "common/scoped_ptr.h" #include "processor/linked_ptr.h" #include "processor/logging.h" @@ -54,7 +55,6 @@ namespace { using google_breakpad::AddIgnoringOverflow; using google_breakpad::linked_ptr; using google_breakpad::RangeMap; -using google_breakpad::scoped_ptr; // A CountedObject holds an int. A global (not thread safe!) count of // allocated CountedObjects is maintained to help test memory management. @@ -342,7 +342,7 @@ static bool RetrieveIndexTest(TestMap* range_map, int set) { // entry, however, it is supposed to retrieve the base address of entry as // stated in the comment in range_map.h. static bool RetrieveAtIndexTest2() { - scoped_ptr range_map(new TestMap()); + std::unique_ptr range_map(new TestMap()); // Store ranges with base address = 2 * object_id: const int range_size = 2; @@ -468,7 +468,7 @@ static bool RunTests() { // Maintain the range map in a pointer so that deletion can be meaningfully // tested. - scoped_ptr range_map(new TestMap()); + std::unique_ptr range_map(new TestMap()); // Run all of the test sets in sequence. unsigned int range_test_set_count = sizeof(range_test_sets) / diff --git a/src/processor/stack_frame_symbolizer.cc b/src/processor/stack_frame_symbolizer.cc index 3afd471b8..fd54fef5f 100644 --- a/src/processor/stack_frame_symbolizer.cc +++ b/src/processor/stack_frame_symbolizer.cc @@ -39,7 +39,6 @@ #include -#include "common/scoped_ptr.h" #include "google_breakpad/processor/code_module.h" #include "google_breakpad/processor/code_modules.h" #include "google_breakpad/processor/source_line_resolver_interface.h" diff --git a/src/processor/stackwalker.cc b/src/processor/stackwalker.cc index 1ff6cf7cb..6a33a326b 100644 --- a/src/processor/stackwalker.cc +++ b/src/processor/stackwalker.cc @@ -40,7 +40,8 @@ #include -#include "common/scoped_ptr.h" +#include + #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/code_module.h" #include "google_breakpad/processor/code_modules.h" @@ -136,7 +137,7 @@ bool Stackwalker::Walk( uint32_t scanned_frames = 0; // Take ownership of the pointer returned by GetContextFrame. - scoped_ptr frame(GetContextFrame()); + std::unique_ptr frame(GetContextFrame()); while (frame.get()) { // frame already contains a good frame with properly set instruction and diff --git a/src/processor/stackwalker_amd64.cc b/src/processor/stackwalker_amd64.cc index f3d7f119e..0870a8b5f 100644 --- a/src/processor/stackwalker_amd64.cc +++ b/src/processor/stackwalker_amd64.cc @@ -38,7 +38,8 @@ #include -#include "common/scoped_ptr.h" +#include + #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/memory_region.h" #include "google_breakpad/processor/source_line_resolver_interface.h" @@ -133,7 +134,7 @@ StackFrameAMD64* StackwalkerAMD64::GetCallerByCFIFrameInfo( CFIFrameInfo* cfi_frame_info) { StackFrameAMD64* last_frame = static_cast(frames.back()); - scoped_ptr frame(new StackFrameAMD64()); + std::unique_ptr frame(new StackFrameAMD64()); if (!cfi_walker_ .FindCallerRegisters(*memory_, *cfi_frame_info, last_frame->context, last_frame->context_validity, @@ -312,10 +313,10 @@ StackFrame* StackwalkerAMD64::GetCallerFrame(const CallStack* stack, const vector& frames = *stack->frames(); StackFrameAMD64* last_frame = static_cast(frames.back()); - scoped_ptr new_frame; + std::unique_ptr new_frame; // If we have CFI information, use it. - scoped_ptr cfi_frame_info( + std::unique_ptr cfi_frame_info( frame_symbolizer_->FindCFIFrameInfo(last_frame)); if (cfi_frame_info.get()) new_frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info.get())); diff --git a/src/processor/stackwalker_arm.cc b/src/processor/stackwalker_arm.cc index 5f6f3e8da..f9be5ba69 100644 --- a/src/processor/stackwalker_arm.cc +++ b/src/processor/stackwalker_arm.cc @@ -36,9 +36,9 @@ #include // Must come first #endif +#include #include -#include "common/scoped_ptr.h" #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/memory_region.h" #include "google_breakpad/processor/source_line_resolver_interface.h" @@ -106,7 +106,7 @@ StackFrameARM* StackwalkerARM::GetCallerByCFIFrameInfo( return NULL; // Construct a new stack frame given the values the CFI recovered. - scoped_ptr frame(new StackFrameARM()); + std::unique_ptr frame(new StackFrameARM()); for (int i = 0; register_names[i]; i++) { CFIFrameInfo::RegisterValueMap::iterator entry = caller_registers.find(register_names[i]); @@ -251,13 +251,13 @@ StackFrame* StackwalkerARM::GetCallerFrame(const CallStack* stack, const vector& frames = *stack->frames(); StackFrameARM* last_frame = static_cast(frames.back()); - scoped_ptr frame; + std::unique_ptr frame; // See if there is DWARF call frame information covering this address. // TODO(jperaza): Ignore iOS CFI info until it is properly collected. // https://bugs.chromium.org/p/google-breakpad/issues/detail?id=764 if (!system_info_ || system_info_->os != "iOS") { - scoped_ptr cfi_frame_info( + std::unique_ptr cfi_frame_info( frame_symbolizer_->FindCFIFrameInfo(last_frame)); if (cfi_frame_info.get()) frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info.get())); diff --git a/src/processor/stackwalker_arm64.cc b/src/processor/stackwalker_arm64.cc index 0fdc11018..a851eb0c8 100644 --- a/src/processor/stackwalker_arm64.cc +++ b/src/processor/stackwalker_arm64.cc @@ -40,9 +40,9 @@ #include +#include #include -#include "common/scoped_ptr.h" #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/memory_region.h" #include "google_breakpad/processor/source_line_resolver_interface.h" @@ -131,7 +131,7 @@ StackFrameARM64* StackwalkerARM64::GetCallerByCFIFrameInfo( return NULL; } // Construct a new stack frame given the values the CFI recovered. - scoped_ptr frame(new StackFrameARM64()); + std::unique_ptr frame(new StackFrameARM64()); for (int i = 0; register_names[i]; i++) { CFIFrameInfo::RegisterValueMap::iterator entry = caller_registers.find(register_names[i]); @@ -318,10 +318,10 @@ StackFrame* StackwalkerARM64::GetCallerFrame(const CallStack* stack, const vector& frames = *stack->frames(); StackFrameARM64* last_frame = static_cast(frames.back()); - scoped_ptr frame; + std::unique_ptr frame; // See if there is DWARF call frame information covering this address. - scoped_ptr cfi_frame_info( + std::unique_ptr cfi_frame_info( frame_symbolizer_->FindCFIFrameInfo(last_frame)); if (cfi_frame_info.get()) frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info.get())); diff --git a/src/processor/stackwalker_mips.cc b/src/processor/stackwalker_mips.cc index 7195c1627..2313cd2a8 100644 --- a/src/processor/stackwalker_mips.cc +++ b/src/processor/stackwalker_mips.cc @@ -36,7 +36,8 @@ #include // Must come first #endif -#include "common/scoped_ptr.h" +#include + #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/code_modules.h" #include "google_breakpad/processor/memory_region.h" @@ -143,7 +144,7 @@ StackFrameMIPS* StackwalkerMIPS::GetCallerByCFIFrameInfo( } caller_registers["$pc"] = pc; // Construct a new stack frame given the values the CFI recovered. - scoped_ptr frame(new StackFrameMIPS()); + std::unique_ptr frame(new StackFrameMIPS()); for (int i = 0; kRegisterNames[i]; ++i) { CFIFrameInfo::RegisterValueMap::const_iterator caller_entry = @@ -210,7 +211,7 @@ StackFrameMIPS* StackwalkerMIPS::GetCallerByCFIFrameInfo( } caller_registers["$pc"] = pc; // Construct a new stack frame given the values the CFI recovered. - scoped_ptr frame(new StackFrameMIPS()); + std::unique_ptr frame(new StackFrameMIPS()); for (int i = 0; kRegisterNames[i]; ++i) { CFIFrameInfo::RegisterValueMap::const_iterator caller_entry = @@ -257,10 +258,10 @@ StackFrame* StackwalkerMIPS::GetCallerFrame(const CallStack* stack, const vector& frames = *stack->frames(); StackFrameMIPS* last_frame = static_cast(frames.back()); - scoped_ptr new_frame; + std::unique_ptr new_frame; // See if there is DWARF call frame information covering this address. - scoped_ptr cfi_frame_info( + std::unique_ptr cfi_frame_info( frame_symbolizer_->FindCFIFrameInfo(last_frame)); if (cfi_frame_info.get()) new_frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info.get())); diff --git a/src/processor/stackwalker_ppc.cc b/src/processor/stackwalker_ppc.cc index 0083392b5..0731a4c6d 100644 --- a/src/processor/stackwalker_ppc.cc +++ b/src/processor/stackwalker_ppc.cc @@ -37,7 +37,8 @@ #include // Must come first #endif -#include "common/scoped_ptr.h" +#include + #include "processor/stackwalker_ppc.h" #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/memory_region.h" @@ -125,7 +126,7 @@ StackFrame* StackwalkerPPC::GetCallerFrame(const CallStack* stack, return NULL; } - scoped_ptr frame(new StackFramePPC()); + std::unique_ptr frame(new StackFramePPC()); frame->context = last_frame->context; frame->context.srr0 = instruction; diff --git a/src/processor/stackwalker_ppc64.cc b/src/processor/stackwalker_ppc64.cc index c36d16be3..973eb71fa 100644 --- a/src/processor/stackwalker_ppc64.cc +++ b/src/processor/stackwalker_ppc64.cc @@ -35,7 +35,8 @@ #include // Must come first #endif -#include "common/scoped_ptr.h" +#include + #include "processor/stackwalker_ppc64.h" #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/memory_region.h" @@ -116,7 +117,7 @@ StackFrame* StackwalkerPPC64::GetCallerFrame(const CallStack* stack, return NULL; } - scoped_ptr frame(new StackFramePPC64()); + std::unique_ptr frame(new StackFramePPC64()); frame->context = last_frame->context; frame->context.srr0 = instruction; diff --git a/src/processor/stackwalker_riscv.cc b/src/processor/stackwalker_riscv.cc index c3681a617..1b2fb5809 100644 --- a/src/processor/stackwalker_riscv.cc +++ b/src/processor/stackwalker_riscv.cc @@ -37,7 +37,8 @@ #include // Must come first #endif -#include "common/scoped_ptr.h" +#include + #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/code_modules.h" #include "google_breakpad/processor/memory_region.h" @@ -158,7 +159,7 @@ StackFrameRISCV* StackwalkerRISCV::GetCallerByCFIFrameInfo( // Construct a new stack frame given the values the CFI recovered. CFIFrameInfo::RegisterValueMap::iterator entry; - scoped_ptr frame(new StackFrameRISCV()); + std::unique_ptr frame(new StackFrameRISCV()); entry = caller_registers.find("pc"); if (entry != caller_registers.end()) { frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_PC; @@ -498,10 +499,10 @@ StackFrame* StackwalkerRISCV::GetCallerFrame(const CallStack* stack, const vector& frames = *stack->frames(); StackFrameRISCV* last_frame = static_cast(frames.back()); - scoped_ptr frame; + std::unique_ptr frame; // Try to recover caller information from CFI. - scoped_ptr cfi_frame_info( + std::unique_ptr cfi_frame_info( frame_symbolizer_->FindCFIFrameInfo(last_frame)); if (cfi_frame_info.get()) frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info.get())); diff --git a/src/processor/stackwalker_riscv64.cc b/src/processor/stackwalker_riscv64.cc index 0ed7b5e65..528aeed72 100644 --- a/src/processor/stackwalker_riscv64.cc +++ b/src/processor/stackwalker_riscv64.cc @@ -37,7 +37,8 @@ #include // Must come first #endif -#include "common/scoped_ptr.h" +#include + #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/code_modules.h" #include "google_breakpad/processor/memory_region.h" @@ -158,7 +159,7 @@ StackFrameRISCV64* StackwalkerRISCV64::GetCallerByCFIFrameInfo( // Construct a new stack frame given the values the CFI recovered. CFIFrameInfo::RegisterValueMap::iterator entry; - scoped_ptr frame(new StackFrameRISCV64()); + std::unique_ptr frame(new StackFrameRISCV64()); entry = caller_registers.find("pc"); if (entry != caller_registers.end()) { frame->context_validity |= StackFrameRISCV64::CONTEXT_VALID_PC; @@ -498,10 +499,10 @@ StackFrame* StackwalkerRISCV64::GetCallerFrame(const CallStack* stack, const vector& frames = *stack->frames(); StackFrameRISCV64* last_frame = static_cast(frames.back()); - scoped_ptr frame; + std::unique_ptr frame; // Try to recover caller information from CFI. - scoped_ptr cfi_frame_info( + std::unique_ptr cfi_frame_info( frame_symbolizer_->FindCFIFrameInfo(last_frame)); if (cfi_frame_info.get()) frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info.get())); diff --git a/src/processor/stackwalker_selftest.cc b/src/processor/stackwalker_selftest.cc index 4f3483b41..19330b53c 100644 --- a/src/processor/stackwalker_selftest.cc +++ b/src/processor/stackwalker_selftest.cc @@ -69,7 +69,6 @@ #include -#include "common/scoped_ptr.h" #include "google_breakpad/common/breakpad_types.h" #include "google_breakpad/common/minidump_format.h" #include "google_breakpad/processor/basic_source_line_resolver.h" @@ -83,7 +82,6 @@ using google_breakpad::BasicSourceLineResolver; using google_breakpad::CallStack; using google_breakpad::CodeModule; using google_breakpad::MemoryRegion; -using google_breakpad::scoped_ptr; using google_breakpad::StackFrame; using google_breakpad::StackFramePPC; using google_breakpad::StackFrameX86; diff --git a/src/processor/stackwalker_x86.cc b/src/processor/stackwalker_x86.cc index 9bda5f8c4..7ed22998b 100644 --- a/src/processor/stackwalker_x86.cc +++ b/src/processor/stackwalker_x86.cc @@ -37,9 +37,10 @@ #endif #include + +#include #include -#include "common/scoped_ptr.h" #include "google_breakpad/processor/call_stack.h" #include "google_breakpad/processor/code_modules.h" #include "google_breakpad/processor/memory_region.h" @@ -536,7 +537,7 @@ StackFrameX86* StackwalkerX86::GetCallerByCFIFrameInfo( StackFrameX86* last_frame = static_cast(frames.back()); last_frame->cfi_frame_info = cfi_frame_info; - scoped_ptr frame(new StackFrameX86()); + std::unique_ptr frame(new StackFrameX86()); if (!cfi_walker_ .FindCallerRegisters(*memory_, *cfi_frame_info, last_frame->context, last_frame->context_validity, @@ -658,7 +659,7 @@ StackFrame* StackwalkerX86::GetCallerFrame(const CallStack* stack, // The last frame can never be inline. A sequence of inline frames always // finishes with a conventional frame. assert(last_frame->trust != StackFrame::FRAME_TRUST_INLINE); - scoped_ptr new_frame; + std::unique_ptr new_frame; // If the resolver has Windows stack walking information, use that. WindowsFrameInfo* windows_frame_info diff --git a/src/processor/static_contained_range_map_unittest.cc b/src/processor/static_contained_range_map_unittest.cc index b9ed72489..261529e60 100644 --- a/src/processor/static_contained_range_map_unittest.cc +++ b/src/processor/static_contained_range_map_unittest.cc @@ -39,6 +39,8 @@ #include +#include + #include "breakpad_googletest_includes.h" #include "common/scoped_ptr.h" #include "processor/contained_range_map-inl.h" @@ -245,7 +247,7 @@ TEST_F(TestStaticCRMMap, TestEmptyMap) { uint64_t size; scoped_array serialized_data; serialized_data.reset(serializer_.Serialize(&empty_crm_map, &size)); - scoped_ptr test_map(new TestMap(serialized_data.get())); + std::unique_ptr test_map(new TestMap(serialized_data.get())); const unsigned int kCorrectSizeForEmptyMap = 24; ASSERT_EQ(kCorrectSizeForEmptyMap, size); @@ -265,7 +267,7 @@ TEST_F(TestStaticCRMMap, TestSingleElementMap) { uint64_t size; scoped_array serialized_data; serialized_data.reset(serializer_.Serialize(&crm_map, &size)); - scoped_ptr test_map(new TestMap(serialized_data.get())); + std::unique_ptr test_map(new TestMap(serialized_data.get())); const unsigned int kCorrectSizeForSingleElementMap = 60; ASSERT_EQ(kCorrectSizeForSingleElementMap, size); @@ -289,7 +291,7 @@ TEST_F(TestStaticCRMMap, TestRetrieveRangeEntries) { uint64_t size; scoped_array serialized_data; serialized_data.reset(serializer_.Serialize(&crm_map, &size)); - scoped_ptr test_map(new TestMap(serialized_data.get())); + std::unique_ptr test_map(new TestMap(serialized_data.get())); std::vector entry_tests; ASSERT_TRUE(test_map->RetrieveRanges(3, entry_tests)); diff --git a/src/processor/static_range_map_unittest.cc b/src/processor/static_range_map_unittest.cc index d4ddec0c5..a220d57d8 100644 --- a/src/processor/static_range_map_unittest.cc +++ b/src/processor/static_range_map_unittest.cc @@ -34,6 +34,8 @@ #include // Must come first #endif +#include + #include "breakpad_googletest_includes.h" #include "common/scoped_ptr.h" #include "processor/range_map-inl.h" @@ -355,7 +357,7 @@ void TestStaticRangeMap::RetrieveIndexTest(const TestMap* range_map, int set) { void TestStaticRangeMap::RunTestCase(int test_case) { // Maintain the range map in a pointer so that deletion can be meaningfully // tested. - scoped_ptr rmap(new RMap()); + std::unique_ptr rmap(new RMap()); const RangeTest* range_tests = range_test_sets[test_case].range_tests; unsigned int range_test_count = range_test_sets[test_case].range_test_count; @@ -374,7 +376,7 @@ void TestStaticRangeMap::RunTestCase(int test_case) { } scoped_array memaddr(serializer_.Serialize(*rmap, NULL)); - scoped_ptr static_range_map(new TestMap(memaddr.get())); + std::unique_ptr static_range_map(new TestMap(memaddr.get())); // The RangeMap's own count of objects should also match. EXPECT_EQ(static_range_map->GetCount(), stored_count); diff --git a/src/tools/mac/dump_syms/dump_syms_tool.cc b/src/tools/mac/dump_syms/dump_syms_tool.cc index cd8e565d7..fb966cd67 100644 --- a/src/tools/mac/dump_syms/dump_syms_tool.cc +++ b/src/tools/mac/dump_syms/dump_syms_tool.cc @@ -47,11 +47,9 @@ #include "common/mac/dump_syms.h" #include "common/mac/arch_utilities.h" #include "common/mac/macho_utilities.h" -#include "common/scoped_ptr.h" using google_breakpad::DumpSymbols; using google_breakpad::Module; -using google_breakpad::scoped_ptr; using std::vector; struct Options { @@ -177,7 +175,7 @@ static bool Start(const Options& options) { Module* module = NULL; if (!dump_symbols.ReadSymbolData(&module)) return false; - scoped_ptr scoped_module(module); + std::unique_ptr scoped_module(module); // If this is a split module, read the secondary Mach-O file, from which the // CFI data will be extracted. @@ -192,7 +190,7 @@ static bool Start(const Options& options) { Module* cfi_module = NULL; if (!dump_symbols.ReadSymbolData(&cfi_module)) return false; - scoped_ptr scoped_cfi_module(cfi_module); + std::unique_ptr scoped_cfi_module(cfi_module); bool name_matches; if (!options.module_name.empty()) { diff --git a/src/tools/windows/converter_exe/escaping.cc b/src/tools/windows/converter_exe/escaping.cc index e399c0f48..4f59a46bd 100644 --- a/src/tools/windows/converter_exe/escaping.cc +++ b/src/tools/windows/converter_exe/escaping.cc @@ -34,6 +34,10 @@ #include +#include + +#include "common/scoped_ptr.h" + #define kApb kAsciiPropertyBits const unsigned char kAsciiPropertyBits[256] = { @@ -60,10 +64,10 @@ static inline bool ascii_isspace(unsigned char c) { return !!(kApb[c] & 0x08); } /////////////////////////////////// // scoped_array /////////////////////////////////// -// scoped_array is like scoped_ptr, except that the caller must allocate +// scoped_array is like std::unique_ptr, except that the caller must allocate // with new [] and the destructor deletes objects with delete []. // -// As with scoped_ptr, a scoped_array either points to an object +// As with std::unique_ptr, a scoped_array either points to an object // or is NULL. A scoped_array owns the object that it points to. // scoped_array is thread-compatible, and once you index into it, // the returned objects have only the threadsafety guarantees of T. From f7c75d38e76fcc79b82d723ec1037d950a792cc5 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 21 Mar 2025 15:32:06 -0400 Subject: [PATCH 76/91] OWNERS: allow autoroller to push DEPS updates Someday the bot will send us LSS updates automatically. Change-Id: I99640b2d466e555b9a0623c28a437a3ddab502d4 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6381405 Reviewed-by: Lei Zhang --- OWNERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OWNERS b/OWNERS index 2fde281f9..ca36bef10 100644 --- a/OWNERS +++ b/OWNERS @@ -11,3 +11,6 @@ rsesek@chromium.org ted@mielczarek.org thestig@chromium.org vapier@chromium.org + +# Allow autoroller to update our DEPS file automatically. +per-file DEPS=* From 6ad2c4029fa7dcb9b389e64e0ab81c71ffff07e1 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 18 Mar 2025 23:00:30 -0400 Subject: [PATCH 77/91] migrate to nullptr Change NULL to nullptr across the codebase. Drop stddef.h in a few places where it is no longer needed. Change-Id: I9ca16bc243e0c7b8900b175b0426ee6c9a55ecef Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6381404 Reviewed-by: Lei Zhang --- android/sample_app/jni/test_breakpad.cpp | 6 +- .../crash_generation_client.cc | 2 +- .../crash_generation_server.cc | 4 +- src/client/linux/handler/exception_handler.cc | 37 +-- .../handler/exception_handler_unittest.cc | 115 +++---- .../linux/handler/minidump_descriptor.cc | 4 +- .../microdump_writer/microdump_writer.cc | 12 +- .../microdump_writer_unittest.cc | 7 +- .../directory_reader_unittest.cc | 2 +- .../linux_core_dumper_unittest.cc | 4 +- .../linux/minidump_writer/linux_dumper.cc | 14 +- .../linux_dumper_unittest_helper.cc | 4 +- .../minidump_writer/linux_ptrace_dumper.cc | 24 +- .../linux_ptrace_dumper_unittest.cc | 12 +- .../linux/minidump_writer/minidump_writer.cc | 32 +- .../minidump_writer_unittest.cc | 26 +- .../sender/google_crash_report_sender.cc | 2 +- .../crash_generation_server.cc | 8 +- src/client/mac/handler/breakpad_nlist_64.cc | 10 +- src/client/mac/handler/dynamic_images.cc | 2 +- src/client/mac/handler/dynamic_images.h | 2 +- src/client/mac/handler/exception_handler.cc | 38 +-- src/client/mac/handler/exception_handler.h | 2 +- src/client/mac/handler/minidump_generator.cc | 34 +- .../mac/handler/protected_memory_allocator.cc | 2 +- .../handler/testcases/breakpad_nlist_test.cc | 2 +- .../mac/tests/crash_generation_server_test.cc | 63 ++-- .../mac/tests/exception_handler_test.cc | 38 ++- .../mac/tests/minidump_generator_test.cc | 14 +- .../tests/minidump_generator_test_helper.cc | 3 +- src/client/mac/tests/spawn_child_process.h | 4 +- .../solaris/handler/exception_handler.cc | 20 +- .../solaris/handler/exception_handler_test.cc | 10 +- .../solaris/handler/minidump_generator.cc | 36 +-- src/client/solaris/handler/minidump_test.cc | 6 +- src/client/solaris/handler/solaris_lwp.cc | 28 +- src/client/solaris/handler/solaris_lwp.h | 2 +- src/client/windows/common/ipc_protocol.h | 14 +- .../windows/crash_generation/client_info.cc | 34 +- .../crash_generation_client.cc | 70 ++--- .../crash_generation_server.cc | 58 ++-- .../crash_generation/minidump_generator.cc | 34 +- .../windows/handler/exception_handler.cc | 129 ++++---- .../windows/handler/exception_handler.h | 4 +- .../windows/sender/crash_report_sender.cc | 4 +- .../crash_generation_app.cc | 50 +-- .../unittests/crash_generation_server_test.cc | 28 +- src/client/windows/unittests/dump_analysis.cc | 54 ++-- src/client/windows/unittests/dump_analysis.h | 15 +- .../unittests/exception_handler_death_test.cc | 64 ++-- .../exception_handler_nesting_test.cc | 18 +- .../unittests/exception_handler_test.cc | 32 +- src/client/windows/unittests/minidump_test.cc | 16 +- src/common/android/testing/mkdtemp.h | 16 +- src/common/android/testing/pthread_fixes.h | 4 +- src/common/byte_cursor.h | 2 +- src/common/byte_cursor_unittest.cc | 2 +- src/common/dwarf/bytereader.cc | 2 +- src/common/dwarf/cfi_assembler.cc | 2 +- src/common/dwarf/cfi_assembler.h | 2 +- src/common/dwarf/dwarf2diehandler.cc | 10 +- src/common/dwarf/dwarf2diehandler.h | 2 +- src/common/dwarf/dwarf2diehandler_unittest.cc | 2 +- src/common/dwarf/dwarf2reader.cc | 55 ++-- src/common/dwarf/elf_reader.cc | 89 +++--- src/common/dwarf/functioninfo.h | 2 +- src/common/dwarf_cu_to_module.cc | 28 +- src/common/dwarf_cu_to_module_unittest.cc | 89 +++--- src/common/language.cc | 2 +- src/common/linux/dump_symbols.cc | 16 +- src/common/linux/elf_core_dump.cc | 6 +- src/common/linux/elf_core_dump_unittest.cc | 22 +- src/common/linux/elf_symbols_to_module.cc | 2 +- src/common/linux/elfutils-inl.h | 8 +- src/common/linux/elfutils.cc | 10 +- .../linux/google_crashdump_uploader_test.cc | 12 +- src/common/linux/guid_creator.cc | 2 +- src/common/linux/http_upload.cc | 26 +- src/common/linux/linux_libc_support.cc | 4 +- .../linux/linux_libc_support_unittest.cc | 22 +- src/common/linux/memory_mapped_file.cc | 5 +- .../linux/memory_mapped_file_unittest.cc | 20 +- src/common/linux/tests/crash_generator.cc | 6 +- src/common/long_string_dictionary.cc | 2 +- src/common/long_string_dictionary_unittest.cc | 2 +- src/common/mac/MachIPC.h | 2 +- src/common/mac/dump_syms.cc | 2 +- src/common/mac/dump_syms.h | 2 +- src/common/mac/launch_reporter.cc | 2 +- src/common/mac/macho_id.cc | 4 +- src/common/mac/macho_reader.cc | 12 +- src/common/mac/macho_reader.h | 2 +- src/common/mac/macho_reader_unittest.cc | 6 +- src/common/mac/macho_walker.cc | 10 +- src/common/memory_allocator.h | 18 +- src/common/memory_allocator_unittest.cc | 6 +- src/common/memory_range_unittest.cc | 26 +- src/common/module.cc | 2 +- src/common/module_unittest.cc | 2 +- src/common/simple_string_dictionary.h | 4 +- .../simple_string_dictionary_unittest.cc | 8 +- src/common/solaris/dump_symbols.cc | 20 +- src/common/solaris/file_id.cc | 18 +- src/common/solaris/guid_creator.cc | 2 +- src/common/stabs_reader.cc | 4 +- src/common/stabs_reader_unittest.cc | 22 +- src/common/stabs_to_module.cc | 11 +- src/common/stabs_to_module.h | 6 +- src/common/stabs_to_module_unittest.cc | 10 +- src/common/test_assembler.cc | 8 +- src/common/test_assembler.h | 5 +- src/common/tests/auto_tempdir.h | 4 +- src/common/windows/dia_util.cc | 2 +- src/common/windows/http_upload.cc | 27 +- src/common/windows/omap.cc | 36 +-- src/common/windows/pdb_source_line_writer.cc | 33 +- src/common/windows/pe_util.cc | 8 +- src/common/windows/string_utils.cc | 18 +- src/google_breakpad/processor/code_modules.h | 2 - src/google_breakpad/processor/process_state.h | 2 +- src/google_breakpad/processor/stack_frame.h | 2 +- .../processor/stack_frame_cpu.h | 4 +- src/processor/address_map_unittest.cc | 2 +- src/processor/basic_code_modules.cc | 15 +- src/processor/basic_code_modules.h | 2 - src/processor/basic_source_line_resolver.cc | 43 +-- .../basic_source_line_resolver_unittest.cc | 4 +- src/processor/cfi_frame_info.cc | 2 +- src/processor/cfi_frame_info_unittest.cc | 10 +- src/processor/contained_range_map-inl.h | 4 +- src/processor/contained_range_map.h | 5 +- src/processor/disassembler_x86.cc | 2 +- src/processor/disassembler_x86.h | 3 +- src/processor/disassembler_x86_unittest.cc | 2 +- src/processor/dump_context.cc | 22 +- src/processor/exploitability.cc | 8 +- src/processor/exploitability_linux.cc | 10 +- src/processor/exploitability_unittest.cc | 2 +- src/processor/fast_source_line_resolver.cc | 10 +- .../fast_source_line_resolver_unittest.cc | 4 +- src/processor/linked_ptr.h | 6 +- src/processor/map_serializers-inl.h | 14 +- src/processor/map_serializers_unittest.cc | 2 +- src/processor/microdump_processor.cc | 2 +- src/processor/minidump.cc | 290 +++++++++--------- src/processor/minidump_dump.cc | 2 +- src/processor/minidump_processor.cc | 38 +-- src/processor/minidump_processor_unittest.cc | 40 +-- src/processor/minidump_unittest.cc | 144 ++++----- src/processor/module_serializer.cc | 6 +- src/processor/postfix_evaluator-inl.h | 4 +- src/processor/postfix_evaluator_unittest.cc | 2 +- src/processor/process_state.cc | 4 +- src/processor/range_map_unittest.cc | 15 +- src/processor/simple_serializer-inl.h | 10 +- src/processor/simple_symbol_supplier.cc | 2 +- src/processor/source_line_resolver_base.cc | 26 +- src/processor/stack_frame_symbolizer.cc | 8 +- src/processor/stackwalk_common.cc | 2 +- src/processor/stackwalker.cc | 6 +- src/processor/stackwalker_address_list.cc | 6 +- .../stackwalker_address_list_unittest.cc | 2 +- src/processor/stackwalker_amd64.cc | 58 ++-- src/processor/stackwalker_amd64_unittest.cc | 4 +- src/processor/stackwalker_arm.cc | 22 +- src/processor/stackwalker_arm64.cc | 20 +- src/processor/stackwalker_arm64_unittest.cc | 4 +- src/processor/stackwalker_arm_unittest.cc | 4 +- src/processor/stackwalker_mips.cc | 30 +- src/processor/stackwalker_mips64_unittest.cc | 4 +- src/processor/stackwalker_mips_unittest.cc | 4 +- src/processor/stackwalker_ppc.cc | 12 +- src/processor/stackwalker_ppc64.cc | 10 +- src/processor/stackwalker_riscv.cc | 18 +- src/processor/stackwalker_riscv64.cc | 18 +- src/processor/stackwalker_riscv64_unittest.cc | 4 +- src/processor/stackwalker_riscv_unittest.cc | 4 +- src/processor/stackwalker_selftest.cc | 12 +- src/processor/stackwalker_sparc.cc | 12 +- src/processor/stackwalker_unittest_utils.h | 2 +- src/processor/stackwalker_x86.cc | 40 +-- src/processor/stackwalker_x86_unittest.cc | 80 ++--- src/processor/static_address_map_unittest.cc | 6 +- .../static_contained_range_map-inl.h | 2 +- src/processor/static_map_iterator-inl.h | 4 +- src/processor/static_map_unittest.cc | 2 +- src/processor/static_range_map_unittest.cc | 10 +- src/processor/synth_minidump.h | 4 +- src/processor/testdata/linux_test_app.cc | 2 +- src/processor/testdata/test_app.cc | 2 +- src/processor/tokenize.cc | 4 +- src/processor/windows_frame_info.h | 28 +- src/tools/linux/md2core/minidump-2-core.cc | 10 +- .../md2core/minidump_memory_range_unittest.cc | 30 +- src/tools/linux/symupload/minidump_upload.cc | 2 +- src/tools/mac/dump_syms/dump_syms_tool.cc | 4 +- .../converter/ms_symbol_server_converter.cc | 6 +- src/tools/windows/converter_exe/converter.cc | 6 +- src/tools/windows/converter_exe/escaping.cc | 14 +- .../windows/converter_exe/http_download.cc | 20 +- .../windows/converter_exe/winhttp_client.cc | 16 +- .../windows/converter_exe/wininet_client.cc | 14 +- .../windows/dump_syms/dump_syms_unittest.cc | 24 +- src/tools/windows/symupload/symupload.cc | 6 +- 204 files changed, 1738 insertions(+), 1702 deletions(-) diff --git a/android/sample_app/jni/test_breakpad.cpp b/android/sample_app/jni/test_breakpad.cpp index 481cbe762..64ed4a2c8 100644 --- a/android/sample_app/jni/test_breakpad.cpp +++ b/android/sample_app/jni/test_breakpad.cpp @@ -41,7 +41,7 @@ bool DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, } void Crash() { - volatile int* a = reinterpret_cast(NULL); + volatile int* a = static_cast(nullptr); *a = 1; } @@ -49,8 +49,8 @@ void Crash() { int main(int argc, char* argv[]) { google_breakpad::MinidumpDescriptor descriptor("."); - google_breakpad::ExceptionHandler eh(descriptor, NULL, DumpCallback, - NULL, true, -1); + google_breakpad::ExceptionHandler eh(descriptor, nullptr, DumpCallback, + nullptr, true, -1); Crash(); return 0; } diff --git a/src/client/linux/crash_generation/crash_generation_client.cc b/src/client/linux/crash_generation/crash_generation_client.cc index 020c61466..23daec819 100644 --- a/src/client/linux/crash_generation/crash_generation_client.cc +++ b/src/client/linux/crash_generation/crash_generation_client.cc @@ -101,7 +101,7 @@ class CrashGenerationClientImpl : public CrashGenerationClient { // static CrashGenerationClient* CrashGenerationClient::TryCreate(int server_fd) { if (server_fd < 0) - return NULL; + return nullptr; return new CrashGenerationClientImpl(server_fd); } diff --git a/src/client/linux/crash_generation/crash_generation_server.cc b/src/client/linux/crash_generation/crash_generation_server.cc index e3270c9d4..f5f371a00 100644 --- a/src/client/linux/crash_generation/crash_generation_server.cc +++ b/src/client/linux/crash_generation/crash_generation_server.cc @@ -105,7 +105,7 @@ CrashGenerationServer::Start() control_pipe_in_ = control_pipe[0]; control_pipe_out_ = control_pipe[1]; - if (pthread_create(&thread_, NULL, + if (pthread_create(&thread_, nullptr, ThreadMain, reinterpret_cast(this))) return false; @@ -330,7 +330,7 @@ void* CrashGenerationServer::ThreadMain(void* arg) { reinterpret_cast(arg)->Run(); - return NULL; + return nullptr; } } // namespace google_breakpad diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc index 6267111fe..c65d03932 100644 --- a/src/client/linux/handler/exception_handler.cc +++ b/src/client/linux/handler/exception_handler.cc @@ -145,12 +145,12 @@ void InstallAlternateStackLocked() { // Only set an alternative stack if there isn't already one, or if the current // one is too small. - if (sys_sigaltstack(NULL, &old_stack) == -1 || !old_stack.ss_sp || + if (sys_sigaltstack(nullptr, &old_stack) == -1 || !old_stack.ss_sp || old_stack.ss_size < kSigStackSize) { new_stack.ss_sp = calloc(1, kSigStackSize); new_stack.ss_size = kSigStackSize; - if (sys_sigaltstack(&new_stack, NULL) == -1) { + if (sys_sigaltstack(&new_stack, nullptr) == -1) { free(new_stack.ss_sp); return; } @@ -164,19 +164,19 @@ void RestoreAlternateStackLocked() { return; stack_t current_stack; - if (sys_sigaltstack(NULL, ¤t_stack) == -1) + if (sys_sigaltstack(nullptr, ¤t_stack) == -1) return; // Only restore the old_stack if the current alternative stack is the one // installed by the call to InstallAlternateStackLocked. if (current_stack.ss_sp == new_stack.ss_sp) { if (old_stack.ss_sp) { - if (sys_sigaltstack(&old_stack, NULL) == -1) + if (sys_sigaltstack(&old_stack, nullptr) == -1) return; } else { stack_t disable_stack; disable_stack.ss_flags = SS_DISABLE; - if (sys_sigaltstack(&disable_stack, NULL) == -1) + if (sys_sigaltstack(&disable_stack, nullptr) == -1) return; } } @@ -197,7 +197,7 @@ void InstallDefaultHandler(int sig) { sys_sigemptyset(&sa.sa_mask); sa.sa_handler_ = SIG_DFL; sa.sa_flags = SA_RESTART; - sys_rt_sigaction(sig, &sa, NULL, sizeof(kernel_sigset_t)); + sys_rt_sigaction(sig, &sa, nullptr, sizeof(kernel_sigset_t)); #else signal(sig, SIG_DFL); #endif @@ -206,7 +206,7 @@ void InstallDefaultHandler(int sig) { // The global exception handler stack. This is needed because there may exist // multiple ExceptionHandler instances in a process. Each will have itself // registered in this stack. -std::vector* g_handler_stack_ = NULL; +std::vector* g_handler_stack_ = nullptr; pthread_mutex_t g_handler_stack_mutex_ = PTHREAD_MUTEX_INITIALIZER; // sizeof(CrashContext) can be too big w.r.t the size of alternatate stack @@ -229,7 +229,7 @@ ExceptionHandler::ExceptionHandler(const MinidumpDescriptor& descriptor, callback_(callback), callback_context_(callback_context), minidump_descriptor_(descriptor), - crash_handler_(NULL) { + crash_handler_(nullptr) { if (server_fd >= 0) crash_generation_client_.reset(CrashGenerationClient::TryCreate(server_fd)); @@ -266,7 +266,7 @@ ExceptionHandler::~ExceptionHandler() { g_handler_stack_->erase(handler); if (g_handler_stack_->empty()) { delete g_handler_stack_; - g_handler_stack_ = NULL; + g_handler_stack_ = nullptr; RestoreAlternateStackLocked(); RestoreHandlersLocked(); } @@ -281,7 +281,7 @@ bool ExceptionHandler::InstallHandlersLocked() { // Fail if unable to store all the old handlers. for (int i = 0; i < kNumHandledSignals; ++i) { - if (sigaction(kExceptionSignals[i], NULL, &old_handlers[i]) == -1) + if (sigaction(kExceptionSignals[i], nullptr, &old_handlers[i]) == -1) return false; } @@ -297,7 +297,7 @@ bool ExceptionHandler::InstallHandlersLocked() { sa.sa_flags = SA_ONSTACK | SA_SIGINFO; for (int i = 0; i < kNumHandledSignals; ++i) { - if (sigaction(kExceptionSignals[i], &sa, NULL) == -1) { + if (sigaction(kExceptionSignals[i], &sa, nullptr) == -1) { // At this point it is impractical to back out changes, and so failure to // install a signal is intentionally ignored. } @@ -314,7 +314,7 @@ void ExceptionHandler::RestoreHandlersLocked() { return; for (int i = 0; i < kNumHandledSignals; ++i) { - if (sigaction(kExceptionSignals[i], &old_handlers[i], NULL) == -1) { + if (sigaction(kExceptionSignals[i], &old_handlers[i], nullptr) == -1) { InstallDefaultHandler(kExceptionSignals[i]); } } @@ -355,7 +355,7 @@ void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) { // This forces the signal to be thrown again, but this time the kernel // will call the function with the right arguments. struct sigaction cur_handler; - if (sigaction(sig, NULL, &cur_handler) == 0 && + if (sigaction(sig, nullptr, &cur_handler) == 0 && cur_handler.sa_sigaction == SignalHandler && (cur_handler.sa_flags & SA_SIGINFO) == 0) { // Reset signal handler with the right flags. @@ -365,7 +365,7 @@ void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) { cur_handler.sa_sigaction = SignalHandler; cur_handler.sa_flags = SA_ONSTACK | SA_SIGINFO; - if (sigaction(sig, &cur_handler, NULL) == -1) { + if (sigaction(sig, &cur_handler, nullptr) == -1) { // When resetting the handler fails, try to reset the // default one to avoid an infinite loop here. InstallDefaultHandler(sig); @@ -473,7 +473,7 @@ bool ExceptionHandler::HandleSignal(int /*sig*/, siginfo_t* info, void* uc) { } #endif g_crash_context_.tid = syscall(__NR_gettid); - if (crash_handler_ != NULL) { + if (crash_handler_ != nullptr) { if (crash_handler_(&g_crash_context_, sizeof(g_crash_context_), callback_context_)) { return true; @@ -537,8 +537,8 @@ bool ExceptionHandler::GenerateDump(CrashContext* context) { } const pid_t child = sys_clone( - ThreadEntry, stack, CLONE_FS | CLONE_UNTRACED, &thread_arg, NULL, NULL, - NULL); + ThreadEntry, stack, CLONE_FS | CLONE_UNTRACED, &thread_arg, nullptr, + nullptr, nullptr); if (child == -1) { sys_close(fdes[0]); sys_close(fdes[1]); @@ -646,7 +646,8 @@ bool ExceptionHandler::WriteMinidump(const string& dump_path, MinidumpCallback callback, void* callback_context) { MinidumpDescriptor descriptor(dump_path); - ExceptionHandler eh(descriptor, NULL, callback, callback_context, false, -1); + ExceptionHandler eh(descriptor, nullptr, callback, callback_context, false, + -1); return eh.WriteMinidump(); } diff --git a/src/client/linux/handler/exception_handler_unittest.cc b/src/client/linux/handler/exception_handler_unittest.cc index 39917af16..876cb2df8 100644 --- a/src/client/linux/handler/exception_handler_unittest.cc +++ b/src/client/linux/handler/exception_handler_unittest.cc @@ -124,7 +124,7 @@ class ExceptionHandlerTest : public ::testing::Test { } void TearDown() { - sigaction(SIGCHLD, &old_action, NULL); + sigaction(SIGCHLD, &old_action, nullptr); } struct sigaction old_action; @@ -165,7 +165,7 @@ void ReadMinidumpPathFromPipe(int fd, string* path) { TEST(ExceptionHandlerTest, SimpleWithPath) { AutoTempDir temp_dir; ExceptionHandler handler( - MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1); + MinidumpDescriptor(temp_dir.path()), nullptr, nullptr, nullptr, true, -1); EXPECT_EQ(temp_dir.path(), handler.minidump_descriptor().directory()); string temp_subdir = temp_dir.path() + "/subdir"; handler.set_minidump_descriptor(MinidumpDescriptor(temp_subdir)); @@ -176,7 +176,8 @@ TEST(ExceptionHandlerTest, SimpleWithFD) { AutoTempDir temp_dir; string path; const int fd = CreateTMPFile(temp_dir.path(), &path); - ExceptionHandler handler(MinidumpDescriptor(fd), NULL, NULL, NULL, true, -1); + ExceptionHandler handler( + MinidumpDescriptor(fd), nullptr, nullptr, nullptr, true, -1); close(fd); } @@ -229,12 +230,13 @@ void ChildCrash(bool use_fd) { std::unique_ptr handler; if (use_fd) { handler.reset(new ExceptionHandler(MinidumpDescriptor(minidump_fd), - NULL, NULL, NULL, true, -1)); + nullptr, nullptr, nullptr, true, + -1)); } else { close(fds[0]); // Close the reading end. void* fd_param = reinterpret_cast(fds[1]); handler.reset(new ExceptionHandler(MinidumpDescriptor(temp_dir.path()), - NULL, DoneCallback, fd_param, + nullptr, DoneCallback, fd_param, true, -1)); } // Crash with the exception handler in scope. @@ -266,14 +268,14 @@ TEST(ExceptionHandlerTest, ChildCrashWithFD) { #if !defined(__ANDROID_API__) || __ANDROID_API__ >= __ANDROID_API_N__ static void* SleepFunction(void* unused) { while (true) usleep(1000000); - return NULL; + return nullptr; } static void* CrashFunction(void* b_ptr) { pthread_barrier_t* b = reinterpret_cast(b_ptr); pthread_barrier_wait(b); DoNullPointerDereference(); - return NULL; + return nullptr; } // Tests that concurrent crashes do not enter a loop by alternately triggering @@ -283,8 +285,8 @@ TEST(ExceptionHandlerTest, ParallelChildCrashesDontHang) { const pid_t child = fork(); if (child == 0) { std::unique_ptr handler( - new ExceptionHandler(MinidumpDescriptor(temp_dir.path()), NULL, NULL, - NULL, true, -1)); + new ExceptionHandler(MinidumpDescriptor(temp_dir.path()), nullptr, + nullptr, nullptr, true, -1)); // We start a number of threads to make sure handling the signal takes // enough time for the second thread to enter the signal handler. @@ -292,8 +294,8 @@ TEST(ExceptionHandlerTest, ParallelChildCrashesDontHang) { google_breakpad::scoped_array sleep_threads( new pthread_t[num_sleep_threads]); for (int i = 0; i < num_sleep_threads; ++i) { - ASSERT_EQ(0, pthread_create(&sleep_threads[i], NULL, SleepFunction, - NULL)); + ASSERT_EQ(0, pthread_create(&sleep_threads[i], nullptr, SleepFunction, + nullptr)); } int num_crash_threads = 2; @@ -301,13 +303,14 @@ TEST(ExceptionHandlerTest, ParallelChildCrashesDontHang) { new pthread_t[num_crash_threads]); // Barrier to synchronize crashing both threads at the same time. pthread_barrier_t b; - ASSERT_EQ(0, pthread_barrier_init(&b, NULL, num_crash_threads + 1)); + ASSERT_EQ(0, pthread_barrier_init(&b, nullptr, num_crash_threads + 1)); for (int i = 0; i < num_crash_threads; ++i) { - ASSERT_EQ(0, pthread_create(&crash_threads[i], NULL, CrashFunction, &b)); + ASSERT_EQ(0, + pthread_create(&crash_threads[i], nullptr, CrashFunction, &b)); } pthread_barrier_wait(&b); for (int i = 0; i < num_crash_threads; ++i) { - ASSERT_EQ(0, pthread_join(crash_threads[i], NULL)); + ASSERT_EQ(0, pthread_join(crash_threads[i], nullptr)); } } @@ -375,14 +378,14 @@ static bool InstallRaiseSIGKILL() { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = RaiseSIGKILL; - return sigaction(SIGSEGV, &sa, NULL) != -1; + return sigaction(SIGSEGV, &sa, nullptr) != -1; } static void CrashWithCallbacks(ExceptionHandler::FilterCallback filter, ExceptionHandler::MinidumpCallback done, const string& path) { ExceptionHandler handler( - MinidumpDescriptor(path), filter, done, NULL, true, -1); + MinidumpDescriptor(path), filter, done, nullptr, true, -1); // Crash with the exception handler in scope. DoNullPointerDereference(); } @@ -393,7 +396,7 @@ TEST(ExceptionHandlerTest, RedeliveryOnFilterCallbackFalse) { const pid_t child = fork(); if (child == 0) { ASSERT_TRUE(InstallRaiseSIGKILL()); - CrashWithCallbacks(FilterCallbackReturnFalse, NULL, temp_dir.path()); + CrashWithCallbacks(FilterCallbackReturnFalse, nullptr, temp_dir.path()); } ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL)); @@ -405,7 +408,7 @@ TEST(ExceptionHandlerTest, RedeliveryOnDoneCallbackFalse) { const pid_t child = fork(); if (child == 0) { ASSERT_TRUE(InstallRaiseSIGKILL()); - CrashWithCallbacks(NULL, DoneCallbackReturnFalse, temp_dir.path()); + CrashWithCallbacks(nullptr, DoneCallbackReturnFalse, temp_dir.path()); } ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL)); @@ -417,7 +420,7 @@ TEST(ExceptionHandlerTest, NoRedeliveryOnDoneCallbackTrue) { const pid_t child = fork(); if (child == 0) { ASSERT_TRUE(InstallRaiseSIGKILL()); - CrashWithCallbacks(NULL, DoneCallbackReturnTrue, temp_dir.path()); + CrashWithCallbacks(nullptr, DoneCallbackReturnTrue, temp_dir.path()); } ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV)); @@ -429,7 +432,7 @@ TEST(ExceptionHandlerTest, NoRedeliveryOnFilterCallbackTrue) { const pid_t child = fork(); if (child == 0) { ASSERT_TRUE(InstallRaiseSIGKILL()); - CrashWithCallbacks(FilterCallbackReturnTrue, NULL, temp_dir.path()); + CrashWithCallbacks(FilterCallbackReturnTrue, nullptr, temp_dir.path()); } ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV)); @@ -444,7 +447,7 @@ TEST(ExceptionHandlerTest, RedeliveryToDefaultHandler) { // are undesirable in this child. signal(SIGSEGV, SIG_DFL); - CrashWithCallbacks(FilterCallbackReturnFalse, NULL, temp_dir.path()); + CrashWithCallbacks(FilterCallbackReturnFalse, nullptr, temp_dir.path()); } // As RaiseSIGKILL wasn't installed, the redelivery should just kill the child @@ -466,8 +469,8 @@ TEST(ExceptionHandlerTest, RedeliveryOnBadSignalHandlerFlag) { // Create a new exception handler, this installs a new SIGSEGV // handler, after saving the old one. ExceptionHandler handler( - MinidumpDescriptor(temp_dir.path()), NULL, - DoneCallbackReturnFalse, NULL, true, -1); + MinidumpDescriptor(temp_dir.path()), nullptr, + DoneCallbackReturnFalse, nullptr, true, -1); // Install the default SIGSEGV handler, saving the current one. // Then re-install the current one with 'signal', this loses the @@ -491,12 +494,12 @@ TEST(ExceptionHandlerTest, StackedHandlersDeliveredToTop) { const pid_t child = fork(); if (child == 0) { ExceptionHandler bottom(MinidumpDescriptor(temp_dir.path()), - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, true, -1); - CrashWithCallbacks(NULL, DoneCallbackRaiseSIGKILL, temp_dir.path()); + CrashWithCallbacks(nullptr, DoneCallbackRaiseSIGKILL, temp_dir.path()); } ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL)); } @@ -507,12 +510,12 @@ TEST(ExceptionHandlerTest, StackedHandlersNotDeliveredToBottom) { const pid_t child = fork(); if (child == 0) { ExceptionHandler bottom(MinidumpDescriptor(temp_dir.path()), - NULL, + nullptr, DoneCallbackRaiseSIGKILL, - NULL, + nullptr, true, -1); - CrashWithCallbacks(NULL, NULL, temp_dir.path()); + CrashWithCallbacks(nullptr, nullptr, temp_dir.path()); } ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGSEGV)); } @@ -523,12 +526,12 @@ TEST(ExceptionHandlerTest, StackedHandlersFilteredToBottom) { const pid_t child = fork(); if (child == 0) { ExceptionHandler bottom(MinidumpDescriptor(temp_dir.path()), - NULL, + nullptr, DoneCallbackRaiseSIGKILL, - NULL, + nullptr, true, -1); - CrashWithCallbacks(FilterCallbackReturnFalse, NULL, temp_dir.path()); + CrashWithCallbacks(FilterCallbackReturnFalse, nullptr, temp_dir.path()); } ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL)); } @@ -539,12 +542,12 @@ TEST(ExceptionHandlerTest, StackedHandlersUnhandledToBottom) { const pid_t child = fork(); if (child == 0) { ExceptionHandler bottom(MinidumpDescriptor(temp_dir.path()), - NULL, + nullptr, DoneCallbackRaiseSIGKILL, - NULL, + nullptr, true, -1); - CrashWithCallbacks(NULL, DoneCallbackReturnFalse, temp_dir.path()); + CrashWithCallbacks(nullptr, DoneCallbackReturnFalse, temp_dir.path()); } ASSERT_NO_FATAL_FAILURE(WaitForProcessToTerminate(child, SIGKILL)); } @@ -562,7 +565,8 @@ TEST(ExceptionHandlerTest, FirstChanceHandlerRuns) { const pid_t child = fork(); if (child == 0) { ExceptionHandler handler( - MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1); + MinidumpDescriptor(temp_dir.path()), nullptr, nullptr, nullptr, true, + -1); google_breakpad::SetFirstChanceExceptionHandler(SimpleFirstChanceHandler); DoNullPointerDereference(); } @@ -599,12 +603,12 @@ TEST(ExceptionHandlerTest, InstructionPointerMemory) { const pid_t child = fork(); if (child == 0) { close(fds[0]); - ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL, + ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), nullptr, DoneCallback, reinterpret_cast(fds[1]), true, -1); // Get some executable memory. char* memory = - reinterpret_cast(mmap(NULL, + reinterpret_cast(mmap(nullptr, kMemorySize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, @@ -691,12 +695,12 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMinBound) { const pid_t child = fork(); if (child == 0) { close(fds[0]); - ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL, + ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), nullptr, DoneCallback, reinterpret_cast(fds[1]), true, -1); // Get some executable memory. char* memory = - reinterpret_cast(mmap(NULL, + reinterpret_cast(mmap(nullptr, kMemorySize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, @@ -782,12 +786,12 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) { const pid_t child = fork(); if (child == 0) { close(fds[0]); - ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL, + ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), nullptr, DoneCallback, reinterpret_cast(fds[1]), true, -1); // Get some executable memory. char* memory = - reinterpret_cast(mmap(NULL, + reinterpret_cast(mmap(nullptr, kMemorySize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, @@ -867,7 +871,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryNullPointer) { const pid_t child = fork(); if (child == 0) { close(fds[0]); - ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL, + ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), nullptr, DoneCallback, reinterpret_cast(fds[1]), true, -1); // Try calling a NULL pointer. @@ -875,7 +879,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryNullPointer) { // Volatile markings are needed to keep Clang from generating invalid // opcodes. See http://crbug.com/498354 for details. volatile void_function memory_function = - reinterpret_cast(NULL); + static_cast(nullptr); memory_function(); // not reached exit(1); @@ -943,7 +947,7 @@ TEST(ExceptionHandlerTest, ModuleInfo) { // Get some memory. char* memory = - reinterpret_cast(mmap(NULL, + reinterpret_cast(mmap(nullptr, kMemorySize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, @@ -954,7 +958,7 @@ TEST(ExceptionHandlerTest, ModuleInfo) { AutoTempDir temp_dir; ExceptionHandler handler( - MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1); + MinidumpDescriptor(temp_dir.path()), nullptr, nullptr, nullptr, true, -1); // Add info about the anonymous memory mapping. handler.AddMappingInfo(kMemoryName, @@ -1048,7 +1052,7 @@ TEST(ExceptionHandlerTest, ExternalDumper) { const pid_t child = fork(); if (child == 0) { close(fds[0]); - ExceptionHandler handler(MinidumpDescriptor("/tmp1"), NULL, NULL, + ExceptionHandler handler(MinidumpDescriptor("/tmp1"), nullptr, nullptr, reinterpret_cast(fds[1]), true, -1); handler.set_crash_handler(CrashHandler); DoNullPointerDereference(); @@ -1114,8 +1118,8 @@ TEST(ExceptionHandlerTest, ExternalDumper) { TEST(ExceptionHandlerTest, WriteMinidumpExceptionStream) { AutoTempDir temp_dir; - ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL, NULL, - NULL, false, -1); + ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), nullptr, + nullptr, nullptr, false, -1); ASSERT_TRUE(handler.WriteMinidump()); string minidump_path = handler.minidump_descriptor().path(); @@ -1135,7 +1139,8 @@ TEST(ExceptionHandlerTest, GenerateMultipleDumpsWithFD) { AutoTempDir temp_dir; string path; const int fd = CreateTMPFile(temp_dir.path(), &path); - ExceptionHandler handler(MinidumpDescriptor(fd), NULL, NULL, NULL, false, -1); + ExceptionHandler handler( + MinidumpDescriptor(fd), nullptr, nullptr, nullptr, false, -1); ASSERT_TRUE(handler.WriteMinidump()); // Check by the size of the data written to the FD that a minidump was // generated. @@ -1150,8 +1155,8 @@ TEST(ExceptionHandlerTest, GenerateMultipleDumpsWithFD) { TEST(ExceptionHandlerTest, GenerateMultipleDumpsWithPath) { AutoTempDir temp_dir; - ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), NULL, NULL, - NULL, false, -1); + ExceptionHandler handler(MinidumpDescriptor(temp_dir.path()), nullptr, + nullptr, nullptr, false, -1); ASSERT_TRUE(handler.WriteMinidump()); const MinidumpDescriptor& minidump_1 = handler.minidump_descriptor(); @@ -1195,7 +1200,7 @@ TEST(ExceptionHandlerTest, AdditionalMemory) { AutoTempDir temp_dir; ExceptionHandler handler( - MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1); + MinidumpDescriptor(temp_dir.path()), nullptr, nullptr, nullptr, true, -1); // Add the memory region to the list of memory to be included. handler.RegisterAppMemory(memory, kMemorySize); @@ -1234,7 +1239,7 @@ TEST(ExceptionHandlerTest, AdditionalMemoryRemove) { AutoTempDir temp_dir; ExceptionHandler handler( - MinidumpDescriptor(temp_dir.path()), NULL, NULL, NULL, true, -1); + MinidumpDescriptor(temp_dir.path()), nullptr, nullptr, nullptr, true, -1); // Add the memory region to the list of memory to be included. handler.RegisterAppMemory(memory, kMemorySize); diff --git a/src/client/linux/handler/minidump_descriptor.cc b/src/client/linux/handler/minidump_descriptor.cc index db2f9b180..a185b5e1a 100644 --- a/src/client/linux/handler/minidump_descriptor.cc +++ b/src/client/linux/handler/minidump_descriptor.cc @@ -46,7 +46,7 @@ MinidumpDescriptor::MinidumpDescriptor(const MinidumpDescriptor& descriptor) : mode_(descriptor.mode_), fd_(descriptor.fd_), directory_(descriptor.directory_), - c_path_(NULL), + c_path_(nullptr), size_limit_(descriptor.size_limit_), address_within_principal_mapping_( descriptor.address_within_principal_mapping_), @@ -70,7 +70,7 @@ MinidumpDescriptor& MinidumpDescriptor::operator=( path_.clear(); if (c_path_) { // This descriptor already had a path set, so generate a new one. - c_path_ = NULL; + c_path_ = nullptr; UpdatePath(); } size_limit_ = descriptor.size_limit_; diff --git a/src/client/linux/microdump_writer/microdump_writer.cc b/src/client/linux/microdump_writer/microdump_writer.cc index 93dae35e5..c7c163446 100644 --- a/src/client/linux/microdump_writer/microdump_writer.cc +++ b/src/client/linux/microdump_writer/microdump_writer.cc @@ -140,9 +140,9 @@ class MicrodumpWriter { bool sanitize_stack, const MicrodumpExtraInfo& microdump_extra_info, LinuxDumper* dumper) - : ucontext_(context ? &context->context : NULL), + : ucontext_(context ? &context->context : nullptr), #if GOOGLE_BREAKPAD_CRASH_CONTEXT_HAS_FLOAT_STATE - float_state_(context ? &context->float_state : NULL), + float_state_(context ? &context->float_state : nullptr), #endif dumper_(dumper), mapping_list_(mappings), @@ -151,8 +151,8 @@ class MicrodumpWriter { address_within_principal_mapping_(address_within_principal_mapping), sanitize_stack_(sanitize_stack), microdump_extra_info_(microdump_extra_info), - log_line_(NULL), - stack_copy_(NULL), + log_line_(nullptr), + stack_copy_(nullptr), stack_len_(0), stack_lower_bound_(0), stack_pointer_(0) { @@ -603,7 +603,7 @@ class MicrodumpWriter { continue; } - DumpModule(mapping, true, i, NULL); + DumpModule(mapping, true, i, nullptr); } // Next write all the mappings provided by the caller for (MappingList::const_iterator iter = mapping_list_.begin(); @@ -654,7 +654,7 @@ bool WriteMicrodump(pid_t crashing_process, bool sanitize_stack, const MicrodumpExtraInfo& microdump_extra_info) { LinuxPtraceDumper dumper(crashing_process); - const ExceptionHandler::CrashContext* context = NULL; + const ExceptionHandler::CrashContext* context = nullptr; if (blob) { if (blob_size != sizeof(ExceptionHandler::CrashContext)) return false; diff --git a/src/client/linux/microdump_writer/microdump_writer_unittest.cc b/src/client/linux/microdump_writer/microdump_writer_unittest.cc index 640be4b6a..93172824c 100644 --- a/src/client/linux/microdump_writer/microdump_writer_unittest.cc +++ b/src/client/linux/microdump_writer/microdump_writer_unittest.cc @@ -168,7 +168,8 @@ void ExtractMicrodumpStackContents(const string& microdump_content, result->reserve(result->size() + data.size() / 2); for (size_t i = 0; i < data.size(); i += 2) { std::string byte = data.substr(i, 2); - result->push_back(static_cast(strtoul(byte.c_str(), NULL, 16))); + result->push_back( + static_cast(strtoul(byte.c_str(), nullptr, 16))); } } } @@ -399,7 +400,7 @@ TEST(MicrodumpWriterTest, NoProductInfo) { MappingList no_mappings; const MicrodumpExtraInfo kMicrodumpExtraInfoNoProductInfo( - MakeMicrodumpExtraInfo(kBuildFingerprint, NULL, kGPUFingerprint)); + MakeMicrodumpExtraInfo(kBuildFingerprint, nullptr, kGPUFingerprint)); CrashAndGetMicrodump(no_mappings, kMicrodumpExtraInfoNoProductInfo, &buf); ASSERT_TRUE(ContainsMicrodump(buf)); @@ -414,7 +415,7 @@ TEST(MicrodumpWriterTest, NoGPUInfo) { MappingList no_mappings; const MicrodumpExtraInfo kMicrodumpExtraInfoNoGPUInfo( - MakeMicrodumpExtraInfo(kBuildFingerprint, kProductInfo, NULL)); + MakeMicrodumpExtraInfo(kBuildFingerprint, kProductInfo, nullptr)); CrashAndGetMicrodump(no_mappings, kMicrodumpExtraInfoNoGPUInfo, &buf); ASSERT_TRUE(ContainsMicrodump(buf)); diff --git a/src/client/linux/minidump_writer/directory_reader_unittest.cc b/src/client/linux/minidump_writer/directory_reader_unittest.cc index 708d586ed..975ace9e7 100644 --- a/src/client/linux/minidump_writer/directory_reader_unittest.cc +++ b/src/client/linux/minidump_writer/directory_reader_unittest.cc @@ -51,7 +51,7 @@ TEST(DirectoryReaderTest, CompareResults) { std::set dent_set; DIR* const dir = opendir("/proc/self"); - ASSERT_TRUE(dir != NULL); + ASSERT_TRUE(dir != nullptr); struct dirent* dent; while ((dent = readdir(dir))) diff --git a/src/client/linux/minidump_writer/linux_core_dumper_unittest.cc b/src/client/linux/minidump_writer/linux_core_dumper_unittest.cc index 72790422e..9ea064da9 100644 --- a/src/client/linux/minidump_writer/linux_core_dumper_unittest.cc +++ b/src/client/linux/minidump_writer/linux_core_dumper_unittest.cc @@ -64,9 +64,9 @@ TEST(LinuxCoreDumperTest, BuildProcPath) { EXPECT_TRUE(dumper.BuildProcPath(maps_path, pid, "maps")); EXPECT_STREQ(maps_path_expected, maps_path); - EXPECT_FALSE(dumper.BuildProcPath(NULL, pid, "maps")); + EXPECT_FALSE(dumper.BuildProcPath(nullptr, pid, "maps")); EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, "")); - EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, NULL)); + EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, nullptr)); char long_node[NAME_MAX]; size_t long_node_len = NAME_MAX - strlen(procfs_path) - 1; diff --git a/src/client/linux/minidump_writer/linux_dumper.cc b/src/client/linux/minidump_writer/linux_dumper.cc index 5c4c389c3..ae3a88205 100644 --- a/src/client/linux/minidump_writer/linux_dumper.cc +++ b/src/client/linux/minidump_writer/linux_dumper.cc @@ -329,7 +329,7 @@ LinuxDumper::ElfFileIdentifierForMapping(const MappingInfo& mapping, // Special-case linux-gate because it's not a real file. if (my_strcmp(mapping.name, kLinuxGateLibraryName) == 0) { - void* linux_gate = NULL; + void* linux_gate = nullptr; if (pid_ == sys_getpid()) { linux_gate = reinterpret_cast(mapping.start_addr); } else { @@ -488,7 +488,7 @@ void LinuxDumper::GetMappingEffectiveNameAndPath(const MappingInfo& mapping, // file_path := /path/to/libname.so // file_name := libname.so const char* basename = my_strrchr(file_path, '/'); - basename = basename == NULL ? file_path : (basename + 1); + basename = basename == nullptr ? file_path : (basename + 1); my_strlcpy(file_name, basename, file_name_size); return; } @@ -579,10 +579,10 @@ bool LinuxDumper::EnumerateMappings() { bool exec = (*(i2 + 3) == 'x'); const char* i3 = my_read_hex_ptr(&offset, i2 + 6 /* skip ' rwxp ' */); if (*i3 == ' ') { - const char* name = NULL; + const char* name = nullptr; // Only copy name if the name is a valid path name, or if // it's the VDSO image. - if (((name = my_strchr(line, '/')) == NULL) && + if (((name = my_strchr(line, '/')) == nullptr) && linux_gate_loc && reinterpret_cast(start_addr) == linux_gate_loc) { name = kLinuxGateLibraryName; @@ -615,7 +615,7 @@ bool LinuxDumper::EnumerateMappings() { module->size = end_addr - start_addr; module->offset = offset; module->exec = exec; - if (name != NULL) { + if (name != nullptr) { const unsigned l = my_strlen(name); if (l < sizeof(module->name)) my_memcpy(module->name, name, l); @@ -915,7 +915,7 @@ const MappingInfo* LinuxDumper::FindMapping(const void* address) const { return mappings_[i]; } - return NULL; + return nullptr; } // Find the mapping which the given memory address falls in. Uses the @@ -928,7 +928,7 @@ const MappingInfo* LinuxDumper::FindMappingNoBias(uintptr_t address) const { return mappings_[i]; } } - return NULL; + return nullptr; } bool LinuxDumper::HandleDeletedFileInMapping(char* path) const { diff --git a/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc b/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc index 5a135fda0..6865abe69 100644 --- a/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc +++ b/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc @@ -68,12 +68,12 @@ void* thread_function(void* data) { uint8_t byte = 1; if (write(pipefd, &byte, sizeof(byte)) != sizeof(byte)) { perror("ERROR: parent notification failed"); - return NULL; + return nullptr; } register volatile pid_t* thread_id_ptr asm(TID_PTR_REGISTER) = thread_id; while (true) asm volatile ("" : : "r" (thread_id_ptr)); - return NULL; + return nullptr; } int main(int argc, char* argv[]) { diff --git a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc index fb5b7e762..6d8b4cf92 100644 --- a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc +++ b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc @@ -81,7 +81,7 @@ typedef struct { static bool SuspendThread(pid_t pid) { // This may fail if the thread has just died or debugged. errno = 0; - if (sys_ptrace(PTRACE_ATTACH, pid, NULL, NULL) != 0 && + if (sys_ptrace(PTRACE_ATTACH, pid, nullptr, nullptr) != 0 && errno != 0) { return false; } @@ -89,7 +89,7 @@ static bool SuspendThread(pid_t pid) { int status; int r = HANDLE_EINTR(sys_waitpid(pid, &status, __WALL)); if (r < 0) { - sys_ptrace(PTRACE_DETACH, pid, NULL, NULL); + sys_ptrace(PTRACE_DETACH, pid, nullptr, nullptr); return false; } @@ -104,7 +104,7 @@ static bool SuspendThread(pid_t pid) { // Signals other than SIGSTOP that are received need to be reinjected, // or they will otherwise get lost. - r = sys_ptrace(PTRACE_CONT, pid, NULL, + r = sys_ptrace(PTRACE_CONT, pid, nullptr, reinterpret_cast(WSTOPSIG(status))); if (r < 0) return false; @@ -118,14 +118,14 @@ static bool SuspendThread(pid_t pid) { // We thus test the stack pointer and exclude any threads that are part of // the seccomp sandbox's trusted code. user_regs_struct regs; - if (sys_ptrace(PTRACE_GETREGS, pid, NULL, ®s) == -1 || + if (sys_ptrace(PTRACE_GETREGS, pid, nullptr, ®s) == -1 || #if defined(__i386) !regs.esp #elif defined(__x86_64) !regs.rsp #endif ) { - sys_ptrace(PTRACE_DETACH, pid, NULL, NULL); + sys_ptrace(PTRACE_DETACH, pid, nullptr, nullptr); return false; } #endif @@ -134,7 +134,7 @@ static bool SuspendThread(pid_t pid) { // Resumes a thread by detaching from it. static bool ResumeThread(pid_t pid) { - return sys_ptrace(PTRACE_DETACH, pid, NULL, NULL) >= 0; + return sys_ptrace(PTRACE_DETACH, pid, nullptr, nullptr) >= 0; } namespace google_breakpad { @@ -242,8 +242,8 @@ bool LinuxPtraceDumper::ReadRegisterSet(ThreadInfo* info, pid_t tid) bool LinuxPtraceDumper::ReadRegisters(ThreadInfo* info, pid_t tid) { #ifdef PTRACE_GETREGS void* gp_addr; - info->GetGeneralPurposeRegisters(&gp_addr, NULL); - if (sys_ptrace(PTRACE_GETREGS, tid, NULL, gp_addr) == -1) { + info->GetGeneralPurposeRegisters(&gp_addr, nullptr); + if (sys_ptrace(PTRACE_GETREGS, tid, nullptr, gp_addr) == -1) { return false; } @@ -260,8 +260,8 @@ bool LinuxPtraceDumper::ReadRegisters(ThreadInfo* info, pid_t tid) { // aren't written to the cpu context anyway, so just don't get them here. // See http://crbug.com/508324 void* fp_addr; - info->GetFloatingPointRegisters(&fp_addr, NULL); - if (sys_ptrace(PTRACE_GETFPREGS, tid, NULL, fp_addr) == -1) { + info->GetFloatingPointRegisters(&fp_addr, nullptr); + if (sys_ptrace(PTRACE_GETFPREGS, tid, nullptr, fp_addr) == -1) { // We are going to check if we can read VFP registers on ARM32. // Currently breakpad does not support VFP registers to be a part of minidump, // so this is only to confirm that we can actually read FP registers. @@ -299,7 +299,7 @@ bool LinuxPtraceDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) { pid_t tid = threads_[index]; - assert(info != NULL); + assert(info != nullptr); char status_path[NAME_MAX]; if (!BuildProcPath(status_path, tid, "status")) return false; @@ -342,7 +342,7 @@ bool LinuxPtraceDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) { int eax, ebx, ecx, edx; __cpuid(1, eax, ebx, ecx, edx); if (edx & bit_FXSAVE) { - if (sys_ptrace(PTRACE_GETFPXREGS, tid, NULL, &info->fpxregs) == -1) { + if (sys_ptrace(PTRACE_GETFPXREGS, tid, nullptr, &info->fpxregs) == -1) { return false; } } else { diff --git a/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc b/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc index 16a9daf1d..9dafa06c4 100644 --- a/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc +++ b/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc @@ -96,7 +96,7 @@ pid_t SetupChildProcess(int number_of_threads) { "linux_dumper_unittest_helper", pipe_fd_string, kNumberOfThreadsArgument, - NULL); + nullptr); // Kill if we get here. printf("Errno from exec: %d", errno); std::string err_str = "Exec of " + helper_path + " failed"; @@ -197,7 +197,7 @@ TEST_F(LinuxPtraceDumperChildTest, FindMappings) { ASSERT_TRUE(dumper.FindMapping(reinterpret_cast(getpid))); ASSERT_TRUE(dumper.FindMapping(reinterpret_cast(printf))); - ASSERT_FALSE(dumper.FindMapping(NULL)); + ASSERT_FALSE(dumper.FindMapping(nullptr)); } TEST_F(LinuxPtraceDumperChildTest, ThreadList) { @@ -220,7 +220,7 @@ TEST_F(LinuxPtraceDumperChildTest, ThreadList) { class StackHelper { public: StackHelper() - : fd_(-1), mapping_(NULL), size_(0) {} + : fd_(-1), mapping_(nullptr), size_(0) {} ~StackHelper() { if (size_) munmap(mapping_, size_); @@ -266,7 +266,7 @@ void LinuxPtraceDumperMappingsTest::SetUp() { ASSERT_NE(-1, fd) << "Failed to open file: " << helper_path_ << ", Error: " << strerror(errno); char* mapping = - reinterpret_cast(mmap(NULL, + reinterpret_cast(mmap(nullptr, kMappingSize, PROT_READ, MAP_SHARED, @@ -323,10 +323,10 @@ TEST_F(LinuxPtraceDumperChildTest, BuildProcPath) { EXPECT_TRUE(dumper.BuildProcPath(maps_path, pid, "maps")); EXPECT_STREQ(maps_path_expected, maps_path); - EXPECT_FALSE(dumper.BuildProcPath(NULL, pid, "maps")); + EXPECT_FALSE(dumper.BuildProcPath(nullptr, pid, "maps")); EXPECT_FALSE(dumper.BuildProcPath(maps_path, 0, "maps")); EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, "")); - EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, NULL)); + EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, nullptr)); char long_node[NAME_MAX]; size_t long_node_len = NAME_MAX - strlen("/proc/123") - 1; diff --git a/src/client/linux/minidump_writer/minidump_writer.cc b/src/client/linux/minidump_writer/minidump_writer.cc index a95dd2548..65032a50d 100644 --- a/src/client/linux/minidump_writer/minidump_writer.cc +++ b/src/client/linux/minidump_writer/minidump_writer.cc @@ -143,9 +143,9 @@ class MinidumpWriter { LinuxDumper* dumper) : fd_(minidump_fd), path_(minidump_path), - ucontext_(context ? &context->context : NULL), + ucontext_(context ? &context->context : nullptr), #if GOOGLE_BREAKPAD_CRASH_CONTEXT_HAS_FLOAT_STATE - float_state_(context ? &context->float_state : NULL), + float_state_(context ? &context->float_state : nullptr), #endif dumper_(dumper), minidump_size_limit_(-1), @@ -245,7 +245,7 @@ class MinidumpWriter { header.get()->signature = MD_HEADER_SIGNATURE; header.get()->version = MD_HEADER_VERSION; - header.get()->time_date_stamp = time(NULL); + header.get()->time_date_stamp = time(nullptr); header.get()->stream_count = kNumWriters; header.get()->stream_directory_rva = dir.position(); } @@ -325,7 +325,7 @@ class MinidumpWriter { bool FillThreadStack(MDRawThread* thread, uintptr_t stack_pointer, uintptr_t pc, int max_stack_len, uint8_t** stack_copy) { - *stack_copy = NULL; + *stack_copy = nullptr; const void* stack; size_t stack_len; @@ -610,7 +610,7 @@ class MinidumpWriter { continue; MDRawModule mod; - if (!FillRawModule(mapping, true, i, &mod, NULL)) + if (!FillRawModule(mapping, true, i, &mod, nullptr)) return false; list.CopyIndexAfterObject(j++, &mod, MD_MODULE_SIZE); } @@ -829,7 +829,7 @@ class MinidumpWriter { // The dynamic linker makes information available that helps gdb find all // DSOs loaded into the program. If this information is indeed available, // dump it to a MD_LINUX_DSO_DEBUG stream. - struct r_debug* r_debug = NULL; + struct r_debug* r_debug = nullptr; uint32_t dynamic_length = 0; for (int i = 0; ; ++i) { @@ -1330,7 +1330,7 @@ class MinidumpWriter { size_t len; uint8_t data[kBufSize]; }* buffers = reinterpret_cast(Alloc(sizeof(Buffers))); - buffers->next = NULL; + buffers->next = nullptr; buffers->len = 0; size_t total = 0; @@ -1348,7 +1348,7 @@ class MinidumpWriter { if (bufptr->len == kBufSize) { bufptr->next = reinterpret_cast(Alloc(sizeof(Buffers))); bufptr = bufptr->next; - bufptr->next = NULL; + bufptr->next = nullptr; bufptr->len = 0; } } @@ -1367,7 +1367,7 @@ class MinidumpWriter { // zero bytes being read after the final buffer was just allocated. if (buffers->len == 0) { // This can only occur with final buffer. - assert(buffers->next == NULL); + assert(buffers->next == nullptr); continue; } memory.Copy(pos, &buffers->data, buffers->len); @@ -1396,7 +1396,7 @@ class MinidumpWriter { uts.release, uts.version, uts.machine, - NULL + nullptr }; bool first_item = true; for (const char** cur_info = info_table; *cur_info; cur_info++) { @@ -1477,7 +1477,7 @@ bool WriteMinidumpImpl(const char* minidump_path, uintptr_t principal_mapping_address, bool sanitize_stacks) { LinuxPtraceDumper dumper(crashing_process); - const ExceptionHandler::CrashContext* context = NULL; + const ExceptionHandler::CrashContext* context = nullptr; if (blob) { if (blob_size != sizeof(ExceptionHandler::CrashContext)) return false; @@ -1517,7 +1517,7 @@ bool WriteMinidump(int minidump_fd, pid_t crashing_process, bool skip_stacks_if_mapping_unreferenced, uintptr_t principal_mapping_address, bool sanitize_stacks) { - return WriteMinidumpImpl(NULL, minidump_fd, -1, + return WriteMinidumpImpl(nullptr, minidump_fd, -1, crashing_process, blob, blob_size, MappingList(), AppMemoryList(), skip_stacks_if_mapping_unreferenced, @@ -1533,7 +1533,7 @@ bool WriteMinidump(const char* minidump_path, pid_t process, dumper.set_crash_thread(process_blamed_thread); MappingList mapping_list; AppMemoryList app_memory_list; - MinidumpWriter writer(minidump_path, -1, NULL, mapping_list, + MinidumpWriter writer(minidump_path, -1, nullptr, mapping_list, app_memory_list, false, 0, false, &dumper); if (!writer.Init()) return false; @@ -1562,7 +1562,7 @@ bool WriteMinidump(int minidump_fd, pid_t crashing_process, bool skip_stacks_if_mapping_unreferenced, uintptr_t principal_mapping_address, bool sanitize_stacks) { - return WriteMinidumpImpl(NULL, minidump_fd, -1, crashing_process, + return WriteMinidumpImpl(nullptr, minidump_fd, -1, crashing_process, blob, blob_size, mappings, appmem, skip_stacks_if_mapping_unreferenced, @@ -1594,7 +1594,7 @@ bool WriteMinidump(int minidump_fd, off_t minidump_size_limit, bool skip_stacks_if_mapping_unreferenced, uintptr_t principal_mapping_address, bool sanitize_stacks) { - return WriteMinidumpImpl(NULL, minidump_fd, minidump_size_limit, + return WriteMinidumpImpl(nullptr, minidump_fd, minidump_size_limit, crashing_process, blob, blob_size, mappings, appmem, skip_stacks_if_mapping_unreferenced, @@ -1606,7 +1606,7 @@ bool WriteMinidump(const char* filename, const MappingList& mappings, const AppMemoryList& appmem, LinuxDumper* dumper) { - MinidumpWriter writer(filename, -1, NULL, mappings, appmem, + MinidumpWriter writer(filename, -1, nullptr, mappings, appmem, false, 0, false, dumper); if (!writer.Init()) return false; diff --git a/src/client/linux/minidump_writer/minidump_writer_unittest.cc b/src/client/linux/minidump_writer/minidump_writer_unittest.cc index effedc5e1..3b1b3b4b6 100644 --- a/src/client/linux/minidump_writer/minidump_writer_unittest.cc +++ b/src/client/linux/minidump_writer/minidump_writer_unittest.cc @@ -145,7 +145,7 @@ TEST(MinidumpWriterTest, MappingInfo) { // Get some memory. char* memory = - reinterpret_cast(mmap(NULL, + reinterpret_cast(mmap(nullptr, memory_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, @@ -450,7 +450,7 @@ TEST(MinidumpWriterTest, MappingInfoContained) { lseek(fd, 0, SEEK_SET); char* memory = - reinterpret_cast(mmap(NULL, + reinterpret_cast(mmap(nullptr, memory_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, @@ -545,7 +545,7 @@ TEST(MinidumpWriterTest, DeletedBinary) { binpath.c_str(), pipe_fd_string, kNumberOfThreadsArgument.c_str(), - NULL); + nullptr); } close(fds[1]); // Wait for the child process to signal that it's ready. @@ -748,9 +748,9 @@ TEST(MinidumpWriterTest, InvalidStackPointer) { bool found_empty_stack = false; for (int i = 0; i < dump_thread_list->thread_count(); i++) { MinidumpThread* thread = dump_thread_list->GetThreadAtIndex(i); - ASSERT_TRUE(thread->thread() != NULL); + ASSERT_TRUE(thread->thread() != nullptr); // When the stack size is zero bytes, GetMemory() returns NULL. - if (thread->GetMemory() == NULL) { + if (thread->GetMemory() == nullptr) { found_empty_stack = true; break; } @@ -792,7 +792,7 @@ TEST(MinidumpWriterTest, MinidumpSizeLimit) { helper_path.c_str(), pipe_fd_string, number_of_threads_arg, - NULL); + nullptr); } close(fds[1]); @@ -829,7 +829,7 @@ TEST(MinidumpWriterTest, MinidumpSizeLimit) { string normal_dump = temp_dir.path() + "/minidump-writer-unittest.dmp"; ASSERT_TRUE(WriteMinidump(normal_dump.c_str(), -1, - child_pid, NULL, 0, + child_pid, nullptr, 0, MappingList(), AppMemoryList())); struct stat st; ASSERT_EQ(0, stat(normal_dump.c_str(), &st)); @@ -842,10 +842,10 @@ TEST(MinidumpWriterTest, MinidumpSizeLimit) { ASSERT_TRUE(dump_thread_list); for (unsigned int i = 0; i < dump_thread_list->thread_count(); i++) { MinidumpThread* thread = dump_thread_list->GetThreadAtIndex(i); - ASSERT_TRUE(thread->thread() != NULL); + ASSERT_TRUE(thread->thread() != nullptr); // When the stack size is zero bytes, GetMemory() returns NULL. MinidumpMemoryRegion* memory = thread->GetMemory(); - ASSERT_TRUE(memory != NULL); + ASSERT_TRUE(memory != nullptr); total_normal_stack_size += memory->GetSize(); } } @@ -860,7 +860,7 @@ TEST(MinidumpWriterTest, MinidumpSizeLimit) { string same_dump = temp_dir.path() + "/minidump-writer-unittest-same.dmp"; ASSERT_TRUE(WriteMinidump(same_dump.c_str(), minidump_size_limit, - child_pid, NULL, 0, + child_pid, nullptr, 0, MappingList(), AppMemoryList())); struct stat st; ASSERT_EQ(0, stat(same_dump.c_str(), &st)); @@ -893,7 +893,7 @@ TEST(MinidumpWriterTest, MinidumpSizeLimit) { string limit_dump = temp_dir.path() + "/minidump-writer-unittest-limit.dmp"; ASSERT_TRUE(WriteMinidump(limit_dump.c_str(), minidump_size_limit, - child_pid, NULL, 0, + child_pid, nullptr, 0, MappingList(), AppMemoryList())); struct stat st; ASSERT_EQ(0, stat(limit_dump.c_str(), &st)); @@ -910,10 +910,10 @@ TEST(MinidumpWriterTest, MinidumpSizeLimit) { int total_limit_stack_size = 0; for (unsigned int i = 0; i < dump_thread_list->thread_count(); i++) { MinidumpThread* thread = dump_thread_list->GetThreadAtIndex(i); - ASSERT_TRUE(thread->thread() != NULL); + ASSERT_TRUE(thread->thread() != nullptr); // When the stack size is zero bytes, GetMemory() returns NULL. MinidumpMemoryRegion* memory = thread->GetMemory(); - ASSERT_TRUE(memory != NULL); + ASSERT_TRUE(memory != nullptr); total_limit_stack_size += memory->GetSize(); } diff --git a/src/client/linux/sender/google_crash_report_sender.cc b/src/client/linux/sender/google_crash_report_sender.cc index f6e481939..2fa6a2b41 100644 --- a/src/client/linux/sender/google_crash_report_sender.cc +++ b/src/client/linux/sender/google_crash_report_sender.cc @@ -104,5 +104,5 @@ int main(int argc, char* argv[]) { FLAGS_crash_server, FLAGS_proxy_host, FLAGS_proxy_userpasswd); - g.Upload(NULL, NULL, NULL); + g.Upload(nullptr, nullptr, nullptr); } diff --git a/src/client/mac/crash_generation/crash_generation_server.cc b/src/client/mac/crash_generation/crash_generation_server.cc index 8d742f361..f099dd4c5 100644 --- a/src/client/mac/crash_generation/crash_generation_server.cc +++ b/src/client/mac/crash_generation/crash_generation_server.cc @@ -69,7 +69,7 @@ CrashGenerationServer::~CrashGenerationServer() { } bool CrashGenerationServer::Start() { - int thread_create_result = pthread_create(&server_thread_, NULL, + int thread_create_result = pthread_create(&server_thread_, nullptr, &WaitForMessages, this); started_ = thread_create_result == 0; return started_; @@ -85,7 +85,7 @@ bool CrashGenerationServer::Stop() { const mach_msg_timeout_t kSendTimeoutMs = 2 * 1000; kern_return_t result = sender.SendMessage(quit_message, kSendTimeoutMs); if (result == KERN_SUCCESS) { - int thread_join_result = pthread_join(server_thread_, NULL); + int thread_join_result = pthread_join(server_thread_, nullptr); started_ = thread_join_result != 0; } @@ -97,7 +97,7 @@ void* CrashGenerationServer::WaitForMessages(void* server) { CrashGenerationServer* self = reinterpret_cast(server); while (self->WaitForOneMessage()) {} - return NULL; + return nullptr; } bool CrashGenerationServer::WaitForOneMessage() { @@ -123,7 +123,7 @@ bool CrashGenerationServer::WaitForOneMessage() { ScopedTaskSuspend suspend(remote_task); MinidumpGenerator generator(remote_task, handler_thread); - dump_path = generator.UniqueNameInDirectory(dump_dir_, NULL); + dump_path = generator.UniqueNameInDirectory(dump_dir_, nullptr); if (info.exception_type && info.exception_code) { generator.SetExceptionInformation(info.exception_type, diff --git a/src/client/mac/handler/breakpad_nlist_64.cc b/src/client/mac/handler/breakpad_nlist_64.cc index d59c7b080..fcf09baef 100644 --- a/src/client/mac/handler/breakpad_nlist_64.cc +++ b/src/client/mac/handler/breakpad_nlist_64.cc @@ -221,7 +221,7 @@ int __breakpad_fdnlist(int fd, nlist_type* list, const char** symbolNames, /* Read in the fat archs */ struct fat_arch* fat_archs = (struct fat_arch*)malloc(fh.nfat_arch * sizeof(struct fat_arch)); - if (fat_archs == NULL) { + if (fat_archs == nullptr) { return -1; } if (read(fd, (char*)fat_archs, @@ -248,7 +248,7 @@ int __breakpad_fdnlist(int fd, nlist_type* list, const char** symbolNames, CFSwapInt32BigToHost(fat_archs[i].align); } - struct fat_arch* fap = NULL; + struct fat_arch* fap = nullptr; for (unsigned i = 0; i < fh.nfat_arch; i++) { if (fat_archs[i].cputype == cpu_type) { fap = &fat_archs[i]; @@ -286,7 +286,7 @@ int __breakpad_fdnlist(int fd, nlist_type* list, const char** symbolNames, struct load_command* load_commands = (struct load_command*)malloc(mh.sizeofcmds); - if (load_commands == NULL) { + if (load_commands == nullptr) { return -1; } if (read(fd, (char*)load_commands, mh.sizeofcmds) != @@ -294,7 +294,7 @@ int __breakpad_fdnlist(int fd, nlist_type* list, const char** symbolNames, free(load_commands); return -1; } - struct symtab_command* stp = NULL; + struct symtab_command* stp = nullptr; struct load_command* lcp = load_commands; // iterate through all load commands, looking for // LC_SYMTAB load command @@ -315,7 +315,7 @@ int __breakpad_fdnlist(int fd, nlist_type* list, const char** symbolNames, } lcp = (struct load_command*)((char*)lcp + lcp->cmdsize); } - if (stp == NULL) { + if (stp == nullptr) { free(load_commands); return -1; } diff --git a/src/client/mac/handler/dynamic_images.cc b/src/client/mac/handler/dynamic_images.cc index 3db7467bf..1ddb74af8 100644 --- a/src/client/mac/handler/dynamic_images.cc +++ b/src/client/mac/handler/dynamic_images.cc @@ -532,7 +532,7 @@ DynamicImage* DynamicImages::GetExecutableImage() { return GetImage(executable_index); } - return NULL; + return nullptr; } //============================================================================== diff --git a/src/client/mac/handler/dynamic_images.h b/src/client/mac/handler/dynamic_images.h index 4799fedfc..68a506956 100644 --- a/src/client/mac/handler/dynamic_images.h +++ b/src/client/mac/handler/dynamic_images.h @@ -254,7 +254,7 @@ class DynamicImages { if (i < (int)image_list_.size()) { return image_list_[i]; } - return NULL; + return nullptr; } // Returns the image corresponding to the main executable. diff --git a/src/client/mac/handler/exception_handler.cc b/src/client/mac/handler/exception_handler.cc index b69ab539d..d93666fcc 100644 --- a/src/client/mac/handler/exception_handler.cc +++ b/src/client/mac/handler/exception_handler.cc @@ -234,10 +234,10 @@ ExceptionHandler::ExceptionHandler(const string& dump_path, filter_(filter), callback_(callback), callback_context_(callback_context), - directCallback_(NULL), - handler_thread_(NULL), + directCallback_(nullptr), + handler_thread_(nullptr), handler_port_(MACH_PORT_NULL), - previous_(NULL), + previous_(nullptr), installed_exception_handler_(false), is_in_teardown_(false), last_minidump_write_result_(false), @@ -258,13 +258,13 @@ ExceptionHandler::ExceptionHandler(DirectCallback callback, void* callback_context, bool install_handler) : dump_path_(), - filter_(NULL), - callback_(NULL), + filter_(nullptr), + callback_(nullptr), callback_context_(callback_context), directCallback_(callback), - handler_thread_(NULL), + handler_thread_(nullptr), handler_port_(MACH_PORT_NULL), - previous_(NULL), + previous_(nullptr), installed_exception_handler_(false), is_in_teardown_(false), last_minidump_write_result_(false), @@ -312,8 +312,8 @@ bool ExceptionHandler::WriteMinidump(const string& dump_path, bool write_exception_stream, MinidumpCallback callback, void* callback_context) { - ExceptionHandler handler(dump_path, NULL, callback, callback_context, false, - NULL); + ExceptionHandler handler(dump_path, nullptr, callback, callback_context, + false, nullptr); return handler.WriteMinidump(write_exception_stream); } @@ -516,7 +516,7 @@ void* ExceptionHandler::WaitForMessage(void* exception_handler_class) { // Don't touch self, since this message could have been sent // from its destructor. if (receive.header.msgh_id == kShutdownMessage) - return NULL; + return nullptr; self->SuspendThreads(); @@ -545,7 +545,7 @@ void* ExceptionHandler::WaitForMessage(void* exception_handler_class) { // Write out the dump and save the result for later retrieval self->last_minidump_write_result_ = self->WriteMinidumpWithException(exception_type, exception_code, - 0, NULL, thread, + 0, nullptr, thread, false, false); #if USE_PROTECTED_ALLOCATIONS @@ -580,7 +580,7 @@ void* ExceptionHandler::WaitForMessage(void* exception_handler_class) { // Generate the minidump with the exception data. self->WriteMinidumpWithException(receive.exception, receive.code[0], - subcode, NULL, receive.thread.name, + subcode, nullptr, receive.thread.name, true, false); #if USE_PROTECTED_ALLOCATIONS @@ -613,7 +613,7 @@ void* ExceptionHandler::WaitForMessage(void* exception_handler_class) { } } - return NULL; + return nullptr; } // static @@ -638,7 +638,7 @@ void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) { bool ExceptionHandler::InstallHandler() { // If a handler is already installed, something is really wrong. - if (gProtectedData.handler != NULL) { + if (gProtectedData.handler != nullptr) { return false; } if (!IsOutOfProcess()) { @@ -699,13 +699,13 @@ bool ExceptionHandler::UninstallHandler(bool in_exception) { kern_return_t result = KERN_SUCCESS; if (old_handler_.get()) { - sigaction(SIGABRT, old_handler_.get(), NULL); + sigaction(SIGABRT, old_handler_.get(), nullptr); #if USE_PROTECTED_ALLOCATIONS mprotect(gProtectedData.protected_buffer, PAGE_SIZE, PROT_READ | PROT_WRITE); #endif old_handler_.reset(); - gProtectedData.handler = NULL; + gProtectedData.handler = nullptr; } if (installed_exception_handler_) { @@ -730,7 +730,7 @@ bool ExceptionHandler::UninstallHandler(bool in_exception) { #endif } - previous_ = NULL; + previous_ = nullptr; installed_exception_handler_ = false; } @@ -738,7 +738,7 @@ bool ExceptionHandler::UninstallHandler(bool in_exception) { } bool ExceptionHandler::Setup(bool install_handler) { - if (pthread_mutex_init(&minidump_write_mutex_, NULL)) + if (pthread_mutex_init(&minidump_write_mutex_, nullptr)) return false; // Create a receive right @@ -786,7 +786,7 @@ bool ExceptionHandler::Teardown() { return false; } - handler_thread_ = NULL; + handler_thread_ = nullptr; handler_port_ = MACH_PORT_NULL; pthread_mutex_destroy(&minidump_write_mutex_); diff --git a/src/client/mac/handler/exception_handler.h b/src/client/mac/handler/exception_handler.h index d3dcef80c..fc9340818 100644 --- a/src/client/mac/handler/exception_handler.h +++ b/src/client/mac/handler/exception_handler.h @@ -159,7 +159,7 @@ class ExceptionHandler { #if TARGET_OS_IPHONE return false; #else - return crash_generation_client_.get() != NULL; + return crash_generation_client_.get() != nullptr; #endif } diff --git a/src/client/mac/handler/minidump_generator.cc b/src/client/mac/handler/minidump_generator.cc index f30742160..8e26c2678 100644 --- a/src/client/mac/handler/minidump_generator.cc +++ b/src/client/mac/handler/minidump_generator.cc @@ -82,8 +82,8 @@ MinidumpGenerator::MinidumpGenerator() crashing_task_(mach_task_self()), handler_thread_(mach_thread_self()), cpu_type_(DynamicImages::GetNativeCPUType()), - task_context_(NULL), - dynamic_images_(NULL), + task_context_(nullptr), + dynamic_images_(nullptr), memory_blocks_(&allocator_) { GatherSystemInformation(); } @@ -100,14 +100,14 @@ MinidumpGenerator::MinidumpGenerator(mach_port_t crashing_task, crashing_task_(crashing_task), handler_thread_(handler_thread), cpu_type_(DynamicImages::GetNativeCPUType()), - task_context_(NULL), - dynamic_images_(NULL), + task_context_(nullptr), + dynamic_images_(nullptr), memory_blocks_(&allocator_) { if (crashing_task != mach_task_self()) { dynamic_images_ = new DynamicImages(crashing_task_); cpu_type_ = dynamic_images_->GetCPUType(); } else { - dynamic_images_ = NULL; + dynamic_images_ = nullptr; cpu_type_ = DynamicImages::GetNativeCPUType(); } @@ -133,11 +133,11 @@ void MinidumpGenerator::GatherSystemInformation() { CFStringRef vers_path = CFSTR("/System/Library/CoreServices/SystemVersion.plist"); CFURLRef sys_vers = - CFURLCreateWithFileSystemPath(NULL, + CFURLCreateWithFileSystemPath(nullptr, vers_path, kCFURLPOSIXPathStyle, false); - CFReadStreamRef read_stream = CFReadStreamCreateWithFile(NULL, sys_vers); + CFReadStreamRef read_stream = CFReadStreamCreateWithFile(nullptr, sys_vers); CFRelease(sys_vers); if (!read_stream) { return; @@ -146,7 +146,7 @@ void MinidumpGenerator::GatherSystemInformation() { CFRelease(read_stream); return; } - CFMutableDataRef data = NULL; + CFMutableDataRef data = nullptr; while (true) { // Actual data file tests: Mac at 480 bytes and iOS at 413 bytes. const CFIndex kMaxBufferLength = 1024; @@ -156,13 +156,13 @@ void MinidumpGenerator::GatherSystemInformation() { if (num_bytes_read < 0) { if (data) { CFRelease(data); - data = NULL; + data = nullptr; } break; } else if (num_bytes_read == 0) { break; } else if (!data) { - data = CFDataCreateMutable(NULL, 0); + data = CFDataCreateMutable(nullptr, 0); } CFDataAppendBytes(data, data_bytes, num_bytes_read); } @@ -173,7 +173,7 @@ void MinidumpGenerator::GatherSystemInformation() { } CFDictionaryRef list = static_cast(CFPropertyListCreateWithData( - NULL, data, kCFPropertyListImmutable, NULL, NULL)); + nullptr, data, kCFPropertyListImmutable, nullptr, nullptr)); CFRelease(data); if (!list) { return; @@ -201,8 +201,8 @@ void MinidumpGenerator::SetTaskContext(breakpad_ucontext_t* task_context) { string MinidumpGenerator::UniqueNameInDirectory(const string& dir, string* unique_name) { - CFUUIDRef uuid = CFUUIDCreate(NULL); - CFStringRef uuid_cfstr = CFUUIDCreateString(NULL, uuid); + CFUUIDRef uuid = CFUUIDCreate(nullptr); + CFStringRef uuid_cfstr = CFUUIDCreateString(nullptr, uuid); CFRelease(uuid); string file_name(ConvertToString(uuid_cfstr)); CFRelease(uuid_cfstr); @@ -1183,7 +1183,7 @@ bool MinidumpGenerator::WriteSystemInfoStream( // CPU Information uint32_t number_of_processors; size_t len = sizeof(number_of_processors); - sysctlbyname("hw.ncpu", &number_of_processors, &len, NULL, 0); + sysctlbyname("hw.ncpu", &number_of_processors, &len, nullptr, 0); MDRawSystemInfo* info_ptr = info.get(); switch (cpu_type_) { @@ -1560,7 +1560,7 @@ bool MinidumpGenerator::WriteMiscInfoStream(MDRawDirectory* misc_info_stream) { uint mibsize = static_cast(sizeof(mib) / sizeof(mib[0])); struct kinfo_proc proc; size_t size = sizeof(proc); - if (sysctl(mib, mibsize, &proc, &size, NULL, 0) == 0) { + if (sysctl(mib, mibsize, &proc, &size, nullptr, 0) == 0) { info_ptr->process_create_time = static_cast(proc.kp_proc.p_starttime.tv_sec); } @@ -1569,11 +1569,11 @@ bool MinidumpGenerator::WriteMiscInfoStream(MDRawDirectory* misc_info_stream) { uint64_t speed; const uint64_t kOneMillion = 1000 * 1000; size = sizeof(speed); - sysctlbyname("hw.cpufrequency_max", &speed, &size, NULL, 0); + sysctlbyname("hw.cpufrequency_max", &speed, &size, nullptr, 0); info_ptr->processor_max_mhz = static_cast(speed / kOneMillion); info_ptr->processor_mhz_limit = static_cast(speed / kOneMillion); size = sizeof(speed); - sysctlbyname("hw.cpufrequency", &speed, &size, NULL, 0); + sysctlbyname("hw.cpufrequency", &speed, &size, nullptr, 0); info_ptr->processor_current_mhz = static_cast(speed / kOneMillion); return true; diff --git a/src/client/mac/handler/protected_memory_allocator.cc b/src/client/mac/handler/protected_memory_allocator.cc index 8205a214d..8e70b05ed 100644 --- a/src/client/mac/handler/protected_memory_allocator.cc +++ b/src/client/mac/handler/protected_memory_allocator.cc @@ -69,7 +69,7 @@ char *ProtectedMemoryAllocator::Allocate(vm_size_t bytes) { return p; } - return NULL; // ran out of memory in our allocation block + return nullptr; // ran out of memory in our allocation block } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/client/mac/handler/testcases/breakpad_nlist_test.cc b/src/client/mac/handler/testcases/breakpad_nlist_test.cc index 3779e357a..aeec44fb5 100644 --- a/src/client/mac/handler/testcases/breakpad_nlist_test.cc +++ b/src/client/mac/handler/testcases/breakpad_nlist_test.cc @@ -73,7 +73,7 @@ void BreakpadNlistTest::CompareToNM() { symbolNames[0] = (const char*)symbolName; symbolNames[1] = "\0"; breakpad_nlist_64("/usr/lib/dyld", &list, symbolNames); - uint64_t nmAddr = strtol(oneNMAddr, NULL, 16); + uint64_t nmAddr = strtol(oneNMAddr, nullptr, 16); if (!IsSymbolMoreThanOnceInDyld(symbolName)) { CPTAssert(nmAddr == symbolList[0].n_value); } diff --git a/src/client/mac/tests/crash_generation_server_test.cc b/src/client/mac/tests/crash_generation_server_test.cc index 743b268e0..4dd18f900 100644 --- a/src/client/mac/tests/crash_generation_server_test.cc +++ b/src/client/mac/tests/crash_generation_server_test.cc @@ -102,12 +102,12 @@ int CrashGenerationServerTest::i = 0; // Test that starting and stopping a server works TEST_F(CrashGenerationServerTest, testStartStopServer) { CrashGenerationServer server(mach_port_name, - NULL, // filter callback - NULL, // filter context - NULL, // dump callback - NULL, // dump context - NULL, // exit callback - NULL, // exit context + nullptr, // filter callback + nullptr, // filter context + nullptr, // dump callback + nullptr, // dump context + nullptr, // exit callback + nullptr, // exit context false, // generate dumps ""); // dump path ASSERT_TRUE(server.Start()); @@ -118,12 +118,12 @@ TEST_F(CrashGenerationServerTest, testStartStopServer) { // Test without actually dumping TEST_F(CrashGenerationServerTest, testRequestDumpNoDump) { CrashGenerationServer server(mach_port_name, - NULL, // filter callback - NULL, // filter context - NULL, // dump callback - NULL, // dump context - NULL, // exit callback - NULL, // exit context + nullptr, // filter callback + nullptr, // filter context + nullptr, // dump callback + nullptr, // dump context + nullptr, // exit callback + nullptr, // exit context false, // don't generate dumps temp_dir.path()); // dump path ASSERT_TRUE(server.Start()); @@ -144,7 +144,7 @@ TEST_F(CrashGenerationServerTest, testRequestDumpNoDump) { // check that no minidump was written string pattern = temp_dir.path() + "/*"; glob_t dirContents; - ret = glob(pattern.c_str(), GLOB_NOSORT, NULL, &dirContents); + ret = glob(pattern.c_str(), GLOB_NOSORT, nullptr, &dirContents); EXPECT_EQ(GLOB_NOMATCH, ret); if (ret != GLOB_NOMATCH) globfree(&dirContents); @@ -170,12 +170,12 @@ void* RequestDump(void* context) { // Test that actually writing a minidump works TEST_F(CrashGenerationServerTest, testRequestDump) { CrashGenerationServer server(mach_port_name, - NULL, // filter callback - NULL, // filter context + nullptr, // filter callback + nullptr, // filter context dumpCallback, // dump callback this, // dump context - NULL, // exit callback - NULL, // exit context + nullptr, // exit callback + nullptr, // exit context true, // generate dumps temp_dir.path()); // dump path ASSERT_TRUE(server.Start()); @@ -187,7 +187,8 @@ TEST_F(CrashGenerationServerTest, testRequestDump) { // because MinidumpGenerator assumes the handler thread is not // the only thread pthread_t thread; - if (pthread_create(&thread, NULL, RequestDump, (void*)mach_port_name) != 0) + if (pthread_create(&thread, nullptr, RequestDump, (void*)mach_port_name) + != 0) exit(1); void* result; pthread_join(thread, &result); @@ -220,12 +221,12 @@ static void Crasher() { // the parent. TEST_F(CrashGenerationServerTest, testChildProcessCrash) { CrashGenerationServer server(mach_port_name, - NULL, // filter callback - NULL, // filter context + nullptr, // filter callback + nullptr, // filter context dumpCallback, // dump callback this, // dump context - NULL, // exit callback - NULL, // exit context + nullptr, // exit callback + nullptr, // exit context true, // generate dumps temp_dir.path()); // dump path ASSERT_TRUE(server.Start()); @@ -234,7 +235,7 @@ TEST_F(CrashGenerationServerTest, testChildProcessCrash) { ASSERT_NE(-1, pid); if (pid == 0) { // Instantiate an OOP exception handler. - ExceptionHandler eh("", NULL, NULL, NULL, true, mach_port_name); + ExceptionHandler eh("", nullptr, nullptr, nullptr, true, mach_port_name); Crasher(); // not reached exit(0); @@ -283,12 +284,12 @@ TEST_F(CrashGenerationServerTest, testChildProcessCrash) { // produces a valid minidump. TEST_F(CrashGenerationServerTest, testChildProcessCrashCrossArchitecture) { CrashGenerationServer server(mach_port_name, - NULL, // filter callback - NULL, // filter context + nullptr, // filter callback + nullptr, // filter context dumpCallback, // dump callback this, // dump context - NULL, // exit callback - NULL, // exit context + nullptr, // exit callback + nullptr, // exit context true, // generate dumps temp_dir.path()); // dump path ASSERT_TRUE(server.Start()); @@ -299,7 +300,7 @@ TEST_F(CrashGenerationServerTest, testChildProcessCrashCrossArchitecture) { helper_path.c_str(), "crash", mach_port_name, - NULL + nullptr }; pid_t pid = spawn_child_process(argv); ASSERT_NE(-1, pid); @@ -372,8 +373,8 @@ TEST_F(CrashGenerationServerTest, testFilter) { this, // filter context dumpCallback, // dump callback this, // dump context - NULL, // exit callback - NULL, // exit context + nullptr, // exit callback + nullptr, // exit context true, // generate dumps temp_dir.path()); // dump path ASSERT_TRUE(server.Start()); @@ -382,7 +383,7 @@ TEST_F(CrashGenerationServerTest, testFilter) { ASSERT_NE(-1, pid); if (pid == 0) { // Instantiate an OOP exception handler. - ExceptionHandler eh("", NULL, NULL, NULL, true, mach_port_name); + ExceptionHandler eh("", nullptr, nullptr, nullptr, true, mach_port_name); Crasher(); // not reached exit(0); diff --git a/src/client/mac/tests/exception_handler_test.cc b/src/client/mac/tests/exception_handler_test.cc index 91b931b94..fb42c8bb2 100644 --- a/src/client/mac/tests/exception_handler_test.cc +++ b/src/client/mac/tests/exception_handler_test.cc @@ -113,7 +113,8 @@ void ExceptionHandlerTest::InProcessCrash(bool aborting) { if (pid == 0) { // In the child process. close(fds[0]); - ExceptionHandler eh(tempDir.path(), NULL, MDCallback, &fds[1], true, NULL); + ExceptionHandler eh(tempDir.path(), nullptr, MDCallback, &fds[1], true, + nullptr); // crash SoonToCrash(aborting ? &AbortCrasher : &Crasher); // not reached @@ -195,8 +196,8 @@ static bool DumpNameMDCallback(const char* dump_dir, const char* file_name, } TEST_F(ExceptionHandlerTest, WriteMinidump) { - ExceptionHandler eh(tempDir.path(), NULL, DumpNameMDCallback, this, true, - NULL); + ExceptionHandler eh(tempDir.path(), nullptr, DumpNameMDCallback, this, true, + nullptr); ASSERT_TRUE(eh.WriteMinidump()); // Ensure that minidump file exists and is > 0 bytes. @@ -214,8 +215,8 @@ TEST_F(ExceptionHandlerTest, WriteMinidump) { } TEST_F(ExceptionHandlerTest, WriteMinidumpWithException) { - ExceptionHandler eh(tempDir.path(), NULL, DumpNameMDCallback, this, true, - NULL); + ExceptionHandler eh(tempDir.path(), nullptr, DumpNameMDCallback, this, true, + nullptr); ASSERT_TRUE(eh.WriteMinidump(true)); // Ensure that minidump file exists and is > 0 bytes. @@ -323,10 +324,11 @@ TEST_F(ExceptionHandlerTest, InstructionPointerMemory) { pid_t pid = fork(); if (pid == 0) { close(fds[0]); - ExceptionHandler eh(tempDir.path(), NULL, MDCallback, &fds[1], true, NULL); + ExceptionHandler eh(tempDir.path(), nullptr, MDCallback, &fds[1], true, + nullptr); // Get some executable memory. char* memory = - reinterpret_cast(mmap(NULL, + reinterpret_cast(mmap(nullptr, kMemorySize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, @@ -422,10 +424,11 @@ TEST_F(ExceptionHandlerTest, InstructionPointerMemoryMinBound) { pid_t pid = fork(); if (pid == 0) { close(fds[0]); - ExceptionHandler eh(tempDir.path(), NULL, MDCallback, &fds[1], true, NULL); + ExceptionHandler eh(tempDir.path(), nullptr, MDCallback, &fds[1], true, + nullptr); // Get some executable memory. char* memory = - reinterpret_cast(mmap(NULL, + reinterpret_cast(mmap(nullptr, kMemorySize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, @@ -521,10 +524,11 @@ TEST_F(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) { pid_t pid = fork(); if (pid == 0) { close(fds[0]); - ExceptionHandler eh(tempDir.path(), NULL, MDCallback, &fds[1], true, NULL); + ExceptionHandler eh(tempDir.path(), nullptr, MDCallback, &fds[1], true, + nullptr); // Get some executable memory. char* memory = - reinterpret_cast(mmap(NULL, + reinterpret_cast(mmap(nullptr, kMemorySize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, @@ -611,13 +615,14 @@ TEST_F(ExceptionHandlerTest, InstructionPointerMemoryNullPointer) { pid_t pid = fork(); if (pid == 0) { close(fds[0]); - ExceptionHandler eh(tempDir.path(), NULL, MDCallback, &fds[1], true, NULL); + ExceptionHandler eh(tempDir.path(), nullptr, MDCallback, &fds[1], true, + nullptr); // Try calling a NULL pointer. typedef void (*void_function)(void); // Volatile markings are needed to keep Clang from generating invalid // opcodes. See http://crbug.com/498354 for details. volatile void_function memory_function = - reinterpret_cast(NULL); + static_cast(nullptr); memory_function(); // not reached exit(1); @@ -657,7 +662,7 @@ TEST_F(ExceptionHandlerTest, InstructionPointerMemoryNullPointer) { static void* Junk(void*) { sleep(1000000); - return NULL; + return nullptr; } // Test that the memory list gets written correctly when multiple @@ -670,11 +675,12 @@ TEST_F(ExceptionHandlerTest, MemoryListMultipleThreads) { pid_t pid = fork(); if (pid == 0) { close(fds[0]); - ExceptionHandler eh(tempDir.path(), NULL, MDCallback, &fds[1], true, NULL); + ExceptionHandler eh(tempDir.path(), nullptr, MDCallback, &fds[1], true, + nullptr); // Run an extra thread so >2 memory regions will be written. pthread_t junk_thread; - if (pthread_create(&junk_thread, NULL, Junk, NULL) == 0) + if (pthread_create(&junk_thread, nullptr, Junk, nullptr) == 0) pthread_detach(junk_thread); // Just crash. diff --git a/src/client/mac/tests/minidump_generator_test.cc b/src/client/mac/tests/minidump_generator_test.cc index 2606e14f5..4ab6abfba 100644 --- a/src/client/mac/tests/minidump_generator_test.cc +++ b/src/client/mac/tests/minidump_generator_test.cc @@ -87,19 +87,19 @@ static void* Junk(void* data) { while (!*wait) { usleep(10000); } - return NULL; + return nullptr; } TEST_F(MinidumpGeneratorTest, InProcess) { MinidumpGenerator generator; string dump_filename = - MinidumpGenerator::UniqueNameInDirectory(tempDir.path(), NULL); + MinidumpGenerator::UniqueNameInDirectory(tempDir.path(), nullptr); // Run an extra thread since MinidumpGenerator assumes there // are 2 or more threads. pthread_t junk_thread; bool quit = false; - ASSERT_EQ(0, pthread_create(&junk_thread, NULL, Junk, &quit)); + ASSERT_EQ(0, pthread_create(&junk_thread, nullptr, Junk, &quit)); ASSERT_TRUE(generator.Write(dump_filename.c_str())); // Ensure that minidump file exists and is > 0 bytes. @@ -109,7 +109,7 @@ TEST_F(MinidumpGeneratorTest, InProcess) { // join the background thread quit = true; - pthread_join(junk_thread, NULL); + pthread_join(junk_thread, nullptr); // Read the minidump, sanity check some data. Minidump minidump(dump_filename.c_str()); @@ -184,7 +184,7 @@ TEST_F(MinidumpGeneratorTest, OutOfProcess) { // Write a minidump of the child process. MinidumpGenerator generator(child_task, MACH_PORT_NULL); string dump_filename = - MinidumpGenerator::UniqueNameInDirectory(tempDir.path(), NULL); + MinidumpGenerator::UniqueNameInDirectory(tempDir.path(), nullptr); ASSERT_TRUE(generator.Write(dump_filename.c_str())); // Ensure that minidump file exists and is > 0 bytes. @@ -248,7 +248,7 @@ TEST_F(MinidumpGeneratorTest, CrossArchitectureDump) { const char* argv[] = { helper_path.c_str(), machPortName, - NULL + nullptr }; pid_t pid = spawn_child_process(argv); ASSERT_NE(-1, pid); @@ -263,7 +263,7 @@ TEST_F(MinidumpGeneratorTest, CrossArchitectureDump) { // Write a minidump of the child process. MinidumpGenerator generator(child_task, MACH_PORT_NULL); string dump_filename = - MinidumpGenerator::UniqueNameInDirectory(tempDir.path(), NULL); + MinidumpGenerator::UniqueNameInDirectory(tempDir.path(), nullptr); ASSERT_TRUE(generator.Write(dump_filename.c_str())); // Ensure that minidump file exists and is > 0 bytes. diff --git a/src/client/mac/tests/minidump_generator_test_helper.cc b/src/client/mac/tests/minidump_generator_test_helper.cc index 8177eeab7..34f22c74d 100644 --- a/src/client/mac/tests/minidump_generator_test_helper.cc +++ b/src/client/mac/tests/minidump_generator_test_helper.cc @@ -67,7 +67,8 @@ int main(int argc, char** argv) { } } else if (argc == 3 && strcmp(argv[1], "crash") == 0) { // Instantiate an OOP exception handler - google_breakpad::ExceptionHandler eh("", NULL, NULL, NULL, true, argv[2]); + google_breakpad::ExceptionHandler eh("", nullptr, nullptr, nullptr, true, + argv[2]); // and crash. int *a = (int*)0x42; *a = 1; diff --git a/src/client/mac/tests/spawn_child_process.h b/src/client/mac/tests/spawn_child_process.h index cc8045116..983816fc3 100644 --- a/src/client/mac/tests/spawn_child_process.h +++ b/src/client/mac/tests/spawn_child_process.h @@ -129,9 +129,9 @@ pid_t spawn_child_process(const char** argv) { argv_v.push_back(strdup(*argv)); argv++; } - argv_v.push_back(NULL); + argv_v.push_back(nullptr); pid_t new_pid = 0; - int result = posix_spawnp(&new_pid, argv_v[0], NULL, &spawnattr, + int result = posix_spawnp(&new_pid, argv_v[0], nullptr, &spawnattr, &argv_v[0], *_NSGetEnviron()); posix_spawnattr_destroy(&spawnattr); diff --git a/src/client/solaris/handler/exception_handler.cc b/src/client/solaris/handler/exception_handler.cc index e3688581a..69d2d09e7 100644 --- a/src/client/solaris/handler/exception_handler.cc +++ b/src/client/solaris/handler/exception_handler.cc @@ -57,7 +57,7 @@ static const int kSigTable[] = { SIGBUS }; -std::vector* ExceptionHandler::handler_stack_ = NULL; +std::vector* ExceptionHandler::handler_stack_ = nullptr; int ExceptionHandler::handler_stack_index_ = 0; pthread_mutex_t ExceptionHandler::handler_stack_mutex_ = PTHREAD_MUTEX_INITIALIZER; @@ -81,7 +81,7 @@ ExceptionHandler::ExceptionHandler(const string& dump_path, if (install_handler) { pthread_mutex_lock(&handler_stack_mutex_); - if (handler_stack_ == NULL) + if (handler_stack_ == nullptr) handler_stack_ = new std::vector; handler_stack_->push_back(this); pthread_mutex_unlock(&handler_stack_mutex_); @@ -109,22 +109,22 @@ ExceptionHandler::~ExceptionHandler() { // When destroying the last ExceptionHandler that installed a handler, // clean up the handler stack. delete handler_stack_; - handler_stack_ = NULL; + handler_stack_ = nullptr; } pthread_mutex_unlock(&handler_stack_mutex_); } bool ExceptionHandler::WriteMinidump() { - return InternalWriteMinidump(0, 0, NULL); + return InternalWriteMinidump(0, 0, nullptr); } // static bool ExceptionHandler::WriteMinidump(const string& dump_path, MinidumpCallback callback, void* callback_context) { - ExceptionHandler handler(dump_path, NULL, callback, + ExceptionHandler handler(dump_path, nullptr, callback, callback_context, false); - return handler.InternalWriteMinidump(0, 0, NULL); + return handler.InternalWriteMinidump(0, 0, nullptr); } void ExceptionHandler::SetupHandler() { @@ -132,12 +132,12 @@ void ExceptionHandler::SetupHandler() { // of the crashing lwp. struct sigaltstack sig_stack; sig_stack.ss_sp = malloc(MINSIGSTKSZ); - if (sig_stack.ss_sp == NULL) + if (sig_stack.ss_sp == nullptr) return; sig_stack.ss_size = MINSIGSTKSZ; sig_stack.ss_flags = 0; - if (sigaltstack(&sig_stack, NULL) < 0) + if (sigaltstack(&sig_stack, nullptr) < 0) return; for (size_t i = 0; i < sizeof(kSigTable) / sizeof(kSigTable[0]); ++i) SetupHandler(kSigTable[i]); @@ -191,7 +191,7 @@ void ExceptionHandler::HandleException(int signo) { // Restore original handler. current_handler->TeardownHandler(signo); - ucontext_t* sig_ctx = NULL; + ucontext_t* sig_ctx = nullptr; if (current_handler->InternalWriteMinidump(signo, current_ebp, &sig_ctx)) { // if (current_handler->InternalWriteMinidump(signo, &sig_ctx)) { // Fully handled this exception, safe to exit. @@ -202,7 +202,7 @@ void ExceptionHandler::HandleException(int signo) { typedef void (*SignalHandler)(int signo); SignalHandler old_handler = reinterpret_cast(current_handler->old_handlers_[signo]); - if (old_handler != NULL) + if (old_handler != nullptr) old_handler(signo); } diff --git a/src/client/solaris/handler/exception_handler_test.cc b/src/client/solaris/handler/exception_handler_test.cc index 56ef94dd0..3d2f17930 100644 --- a/src/client/solaris/handler/exception_handler_test.cc +++ b/src/client/solaris/handler/exception_handler_test.cc @@ -69,18 +69,18 @@ static void* thread_crash(void*) { sleep(3); a = foo(a); printf("%x\n", a); - return NULL; + return nullptr; } static void* thread_main(void*) { while (!should_exit) sleep(1); - return NULL; + return nullptr; } static void CreateCrashThread() { pthread_t h; - pthread_create(&h, NULL, thread_crash, NULL); + pthread_create(&h, nullptr, thread_crash, nullptr); pthread_detach(h); } @@ -88,7 +88,7 @@ static void CreateCrashThread() { static void CreateThread(int num) { pthread_t h; for (int i = 0; i < num; ++i) { - pthread_create(&h, NULL, thread_main, NULL); + pthread_create(&h, nullptr, thread_main, nullptr); pthread_detach(h); } } @@ -109,7 +109,7 @@ static bool MinidumpCallback(const char* dump_path, int main(int argc, char* argv[]) { int handler_index = 1; - ExceptionHandler handler_ignore(".", NULL, MinidumpCallback, + ExceptionHandler handler_ignore(".", nullptr, MinidumpCallback, (void*)handler_index, true); CreateCrashThread(); CreateThread(10); diff --git a/src/client/solaris/handler/minidump_generator.cc b/src/client/solaris/handler/minidump_generator.cc index f9e1adfc6..2723a8a89 100644 --- a/src/client/solaris/handler/minidump_generator.cc +++ b/src/client/solaris/handler/minidump_generator.cc @@ -90,7 +90,7 @@ struct FindCrashLwpContext { int crashing_lwpid; FindCrashLwpContext() : - lwp_lister(NULL), + lwp_lister(nullptr), crashing_stack_bottom(0UL), crashing_lwpid(-1) { } @@ -156,7 +156,7 @@ bool WriteLwpStack(const SolarisLwp* lwp_lister, #if TARGET_CPU_SPARC bool WriteContext(MDRawContextSPARC* context, ucontext_t* sig_ctx) { - assert(sig_ctx != NULL); + assert(sig_ctx != nullptr); int* regs = sig_ctx->uc_mcontext.gregs; context->context_flags = MD_CONTEXT_SPARC_FULL; @@ -236,7 +236,7 @@ bool WriteCrashedLwpStream(MinidumpFileWriter* minidump_writer, const WriterArgument* writer_args, const lwpstatus_t* lsp, MDRawThread* lwp) { - assert(writer_args->sig_ctx != NULL); + assert(writer_args->sig_ctx != nullptr); lwp->thread_id = lsp->pr_lwpid; @@ -356,10 +356,10 @@ bool WriteOSInformation(MinidumpFileWriter* minidump_writer, uts.version, uts.machine, "OpenSolaris", - NULL + nullptr }; for (const char** cur_os_info = os_info_table; - *cur_os_info != NULL; + *cur_os_info != nullptr; ++cur_os_info) { if (cur_os_info != os_info_table && space_left > 1) { strcat(os_version, " "); @@ -402,7 +402,7 @@ bool LwpInformationCallback(lwpstatus_t* lsp, void* context) { memset(&lwp, 0, sizeof(MDRawThread)); if (lsp->pr_lwpid != callback_context->writer_args->crashed_lwpid || - callback_context->writer_args->sig_ctx == NULL) { + callback_context->writer_args->sig_ctx == nullptr) { success = WriteLwpStream(callback_context->minidump_writer, callback_context->writer_args->lwp_lister, lsp, &lwp); @@ -519,7 +519,7 @@ bool ModuleInfoCallback(const ModuleInfo& module_info, void* context) { return false; buf[count] = '\0'; - if ((realname = strrchr(buf, '/')) == NULL) + if ((realname = strrchr(buf, '/')) == nullptr) return false; realname++; @@ -581,7 +581,7 @@ bool WriteExceptionStream(MinidumpFileWriter* minidump_writer, const WriterArgument* writer_args, MDRawDirectory* dir) { // This happenes when this is not a crash, but a requested dump. - if (writer_args->sig_ctx == NULL) + if (writer_args->sig_ctx == nullptr) return false; TypedMDRVA exception(minidump_writer); @@ -595,7 +595,7 @@ bool WriteExceptionStream(MinidumpFileWriter* minidump_writer, exception.get()->exception_record.exception_flags = 0; #if TARGET_CPU_SPARC - if (writer_args->sig_ctx != NULL) { + if (writer_args->sig_ctx != nullptr) { exception.get()->exception_record.exception_address = writer_args->sig_ctx->uc_mcontext.gregs[REG_PC]; } else { @@ -610,7 +610,7 @@ bool WriteExceptionStream(MinidumpFileWriter* minidump_writer, memset(context.get(), 0, sizeof(MDRawContextSPARC)); return WriteContext(context.get(), writer_args->sig_ctx); #elif TARGET_CPU_X86 - if (writer_args->sig_ctx != NULL) { + if (writer_args->sig_ctx != nullptr) { exception.get()->exception_record.exception_address = writer_args->sig_ctx->uc_mcontext.gregs[EIP]; } else { @@ -625,7 +625,7 @@ bool WriteExceptionStream(MinidumpFileWriter* minidump_writer, memset(context.get(), 0, sizeof(MDRawContextX86)); return WriteContext(context.get(), (int*)&writer_args->sig_ctx->uc_mcontext.gregs, - NULL); + nullptr); #endif } @@ -693,7 +693,7 @@ void* Write(void* argument) { WriterArgument* writer_args = static_cast(argument); if (!writer_args->lwp_lister->ControlAllLwps(true)) - return NULL; + return nullptr; AutoLwpResumer lwpResumer(writer_args->lwp_lister); @@ -728,7 +728,7 @@ void* Write(void* argument) { return 0; header.get()->signature = MD_HEADER_SIGNATURE; header.get()->version = MD_HEADER_VERSION; - header.get()->time_date_stamp = time(NULL); + header.get()->time_date_stamp = time(nullptr); header.get()->stream_count = writer_count; header.get()->stream_directory_rva = dir.position(); @@ -761,9 +761,9 @@ bool MinidumpGenerator::WriteMinidumpToFile(const char* file_pathname, // The exception handler thread. pthread_t handler_thread; - assert(file_pathname != NULL); + assert(file_pathname != nullptr); - if (file_pathname == NULL) + if (file_pathname == nullptr) return false; MinidumpFileWriter minidump_writer; @@ -777,10 +777,10 @@ bool MinidumpGenerator::WriteMinidumpToFile(const char* file_pathname, argument.crashed_lwpid = pthread_self(); argument.signo = signo; argument.sighandler_ebp = sighandler_ebp; - argument.sig_ctx = NULL; + argument.sig_ctx = nullptr; - pthread_create(&handler_thread, NULL, Write, (void*)&argument); - pthread_join(handler_thread, NULL); + pthread_create(&handler_thread, nullptr, Write, (void*)&argument); + pthread_join(handler_thread, nullptr); return true; } diff --git a/src/client/solaris/handler/minidump_test.cc b/src/client/solaris/handler/minidump_test.cc index a8f690632..7a20eb827 100644 --- a/src/client/solaris/handler/minidump_test.cc +++ b/src/client/solaris/handler/minidump_test.cc @@ -51,10 +51,10 @@ static void* Reporter(void*) { snprintf(buffer, sizeof(buffer), "./minidump_test.out"); fprintf(stdout, "Writing %s\n", buffer); - md.WriteMinidumpToFile(buffer, 0, 0, NULL); + md.WriteMinidumpToFile(buffer, 0, 0, nullptr); doneWritingReport = true; - return NULL; + return nullptr; } static void SleepyFunction() { @@ -66,7 +66,7 @@ static void SleepyFunction() { int main(int argc, char * const argv[]) { pthread_t reporter_thread; - if (pthread_create(&reporter_thread, NULL, Reporter, NULL) == 0) { + if (pthread_create(&reporter_thread, nullptr, Reporter, nullptr) == 0) { pthread_detach(reporter_thread); } else { perror("pthread_create"); diff --git a/src/client/solaris/handler/solaris_lwp.cc b/src/client/solaris/handler/solaris_lwp.cc index fec9e3f3e..77c6bcd54 100644 --- a/src/client/solaris/handler/solaris_lwp.cc +++ b/src/client/solaris/handler/solaris_lwp.cc @@ -74,9 +74,9 @@ struct AddressValidatingContext { // Convert from string to int. static bool LocalAtoi(char* s, int* r) { - assert(s != NULL); - assert(r != NULL); - char* endptr = NULL; + assert(s != nullptr); + assert(r != nullptr); + char* endptr = nullptr; int ret = strtol(s, &endptr, 10); if (endptr == s) return false; @@ -107,11 +107,11 @@ static int IterateLwpAll(int pid, int count = 0; snprintf(lwp_path, sizeof (lwp_path), "/proc/%d/lwp", (int)pid); - if ((dir = opendir(lwp_path)) == NULL) + if ((dir = opendir(lwp_path)) == nullptr) return -1; - struct dirent* entry = NULL; - while ((entry = readdir(dir)) != NULL) { + struct dirent* entry = nullptr; + while ((entry = readdir(dir)) != nullptr) { if ((strcmp(entry->d_name, ".") != 0) && (strcmp(entry->d_name, "..") != 0)) { int lwpid = 0; @@ -135,11 +135,11 @@ static int IterateLwpAll(int pid, void* GetNextFrame(void** last_ebp) { void* sp = *last_ebp; if ((unsigned long)sp == (unsigned long)last_ebp) - return NULL; + return nullptr; if ((unsigned long)sp & (sizeof(void*) - 1)) - return NULL; + return nullptr; if ((unsigned long)sp - (unsigned long)last_ebp > 100000) - return NULL; + return nullptr; return sp; } #elif defined(__sparc) @@ -242,7 +242,7 @@ int SolarisLwp::ControlAllLwps(bool suspend) { } int SolarisLwp::GetLwpCount() const { - return IterateLwpAll(pid_, NULL); + return IterateLwpAll(pid_, nullptr); } int SolarisLwp::Lwp_iter_all(int pid, @@ -262,9 +262,9 @@ int SolarisLwp::Lwp_iter_all(int pid, * The /proc/pid/lstatus file has the array of lwpstatus_t's and the * /proc/pid/lpsinfo file has the array of lwpsinfo_t's. */ - if (read_lfile(pid, "lstatus", Lhp) == NULL) + if (read_lfile(pid, "lstatus", Lhp) == nullptr) return -1; - if (read_lfile(pid, "lpsinfo", Lphp) == NULL) { + if (read_lfile(pid, "lpsinfo", Lphp) == nullptr) { return -1; } @@ -276,7 +276,7 @@ int SolarisLwp::Lwp_iter_all(int pid, sp = Lsp; Lsp = (lwpstatus_t*)((uintptr_t)Lsp + Lhp->pr_entsize); } else { - sp = NULL; + sp = nullptr; } if (callback_param && !(callback_param->call_back)(sp, callback_param->context)) @@ -298,7 +298,7 @@ uintptr_t SolarisLwp::GetLwpStackBottom(uintptr_t current_esp) const { } int SolarisLwp::GetModuleCount() const { - return ListModules(NULL); + return ListModules(nullptr); } int SolarisLwp::ListModules( diff --git a/src/client/solaris/handler/solaris_lwp.h b/src/client/solaris/handler/solaris_lwp.h index f27d6b747..f2fe7c197 100644 --- a/src/client/solaris/handler/solaris_lwp.h +++ b/src/client/solaris/handler/solaris_lwp.h @@ -89,7 +89,7 @@ struct CallbackParam { // Callback context; void* context; - CallbackParam() : call_back(NULL), context(NULL) { + CallbackParam() : call_back(nullptr), context(nullptr) { } CallbackParam(CallbackFunc func, void* func_context) : diff --git a/src/client/windows/common/ipc_protocol.h b/src/client/windows/common/ipc_protocol.h index 7e0c24e3c..31667b567 100644 --- a/src/client/windows/common/ipc_protocol.h +++ b/src/client/windows/common/ipc_protocol.h @@ -46,8 +46,8 @@ struct CustomInfoEntry { CustomInfoEntry() { // Putting name and value in initializer list makes VC++ show warning 4351. - set_name(NULL); - set_value(NULL); + set_name(nullptr); + set_value(nullptr); } CustomInfoEntry(const wchar_t* name_arg, const wchar_t* value_arg) { @@ -105,12 +105,12 @@ struct ProtocolMessage { id(0), dump_type(MiniDumpNormal), thread_id(0), - exception_pointers(NULL), - assert_info(NULL), + exception_pointers(nullptr), + assert_info(nullptr), custom_client_info(), - dump_request_handle(NULL), - dump_generated_handle(NULL), - server_alive_handle(NULL) { + dump_request_handle(nullptr), + dump_generated_handle(nullptr), + server_alive_handle(nullptr) { } // Creates an instance with the given parameters. diff --git a/src/client/windows/crash_generation/client_info.cc b/src/client/windows/crash_generation/client_info.cc index 61ee21262..205336210 100644 --- a/src/client/windows/crash_generation/client_info.cc +++ b/src/client/windows/crash_generation/client_info.cc @@ -52,12 +52,12 @@ ClientInfo::ClientInfo(CrashGenerationServer* crash_server, assert_info_(assert_info), custom_client_info_(custom_client_info), thread_id_(thread_id), - process_handle_(NULL), - dump_requested_handle_(NULL), - dump_generated_handle_(NULL), - dump_request_wait_handle_(NULL), - process_exit_wait_handle_(NULL), - crash_id_(NULL) { + process_handle_(nullptr), + dump_requested_handle_(nullptr), + dump_generated_handle_(nullptr), + dump_request_wait_handle_(nullptr), + process_exit_wait_handle_(nullptr), + crash_id_(nullptr) { GetSystemTimeAsFileTime(&start_time_); } @@ -75,26 +75,26 @@ bool ClientInfo::Initialize() { } crash_id_ = start_time_.dwLowDateTime; - dump_requested_handle_ = CreateEvent(NULL, // Security attributes. - TRUE, // Manual reset. - FALSE, // Initial state. - NULL); // Name. + dump_requested_handle_ = CreateEvent(nullptr, // Security attributes. + TRUE, // Manual reset. + FALSE, // Initial state. + nullptr); // Name. if (!dump_requested_handle_) { return false; } - dump_generated_handle_ = CreateEvent(NULL, // Security attributes. - TRUE, // Manual reset. - FALSE, // Initial state. - NULL); // Name. - return dump_generated_handle_ != NULL; + dump_generated_handle_ = CreateEvent(nullptr, // Security attributes. + TRUE, // Manual reset. + FALSE, // Initial state. + nullptr); // Name. + return dump_generated_handle_ != nullptr; } void ClientInfo::UnregisterDumpRequestWaitAndBlockUntilNoPending() { if (dump_request_wait_handle_) { // Wait for callbacks that might already be running to finish. UnregisterWaitEx(dump_request_wait_handle_, INVALID_HANDLE_VALUE); - dump_request_wait_handle_ = NULL; + dump_request_wait_handle_ = nullptr; } } @@ -106,7 +106,7 @@ void ClientInfo::UnregisterProcessExitWait(bool block_until_no_pending) { } else { UnregisterWait(process_exit_wait_handle_); } - process_exit_wait_handle_ = NULL; + process_exit_wait_handle_ = nullptr; } } diff --git a/src/client/windows/crash_generation/crash_generation_client.cc b/src/client/windows/crash_generation/crash_generation_client.cc index 653fafdc2..cfacf27d3 100644 --- a/src/client/windows/crash_generation/crash_generation_client.cc +++ b/src/client/windows/crash_generation/crash_generation_client.cc @@ -84,7 +84,7 @@ static bool TransactNamedPipeDebugHelper(HANDLE pipe, in_buffer, in_size, bytes_count, - NULL)) { + nullptr)) { return false; } @@ -92,7 +92,7 @@ static bool TransactNamedPipeDebugHelper(HANDLE pipe, // and read. // Sleep(5000); - return ReadFile(pipe, out_buffer, out_size, bytes_count, NULL) != FALSE; + return ReadFile(pipe, out_buffer, out_size, bytes_count, nullptr) != FALSE; } **/ @@ -101,15 +101,15 @@ CrashGenerationClient::CrashGenerationClient( MINIDUMP_TYPE dump_type, const CustomClientInfo* custom_info) : pipe_name_(pipe_name), - pipe_handle_(NULL), + pipe_handle_(nullptr), custom_info_(), dump_type_(dump_type), - crash_event_(NULL), - crash_generated_(NULL), - server_alive_(NULL), + crash_event_(nullptr), + crash_generated_(nullptr), + server_alive_(nullptr), server_process_id_(0), thread_id_(0), - exception_pointers_(NULL) { + exception_pointers_(nullptr) { memset(&assert_info_, 0, sizeof(assert_info_)); if (custom_info) { custom_info_ = *custom_info; @@ -124,12 +124,12 @@ CrashGenerationClient::CrashGenerationClient( pipe_handle_(pipe_handle), custom_info_(), dump_type_(dump_type), - crash_event_(NULL), - crash_generated_(NULL), - server_alive_(NULL), + crash_event_(nullptr), + crash_generated_(nullptr), + server_alive_(nullptr), server_process_id_(0), thread_id_(0), - exception_pointers_(NULL) { + exception_pointers_(nullptr) { memset(&assert_info_, 0, sizeof(assert_info_)); if (custom_info) { custom_info_ = *custom_info; @@ -204,12 +204,12 @@ bool CrashGenerationClient::RequestUpload(DWORD crash_id) { return false; } - CustomClientInfo custom_info = {NULL, 0}; + CustomClientInfo custom_info = {nullptr, 0}; ProtocolMessage msg(MESSAGE_TAG_UPLOAD_REQUEST, crash_id, - static_cast(NULL), NULL, NULL, NULL, - custom_info, NULL, NULL, NULL); + static_cast(nullptr), nullptr, nullptr, + nullptr, custom_info, nullptr, nullptr, nullptr); DWORD bytes_count = 0; - bool success = WriteFile(pipe, &msg, sizeof(msg), &bytes_count, NULL) != 0; + bool success = WriteFile(pipe, &msg, sizeof(msg), &bytes_count, nullptr) != 0; CloseHandle(pipe); return success; @@ -220,13 +220,13 @@ HANDLE CrashGenerationClient::ConnectToServer() { kPipeDesiredAccess, kPipeFlagsAndAttributes); if (!pipe) { - return NULL; + return nullptr; } DWORD mode = kPipeMode; - if (!SetNamedPipeHandleState(pipe, &mode, NULL, NULL)) { + if (!SetNamedPipeHandleState(pipe, &mode, nullptr, nullptr)) { CloseHandle(pipe); - pipe = NULL; + pipe = nullptr; } return pipe; @@ -240,9 +240,9 @@ bool CrashGenerationClient::RegisterClient(HANDLE pipe) { &exception_pointers_, &assert_info_, custom_info_, - NULL, - NULL, - NULL); + nullptr, + nullptr, + nullptr); ProtocolMessage reply; DWORD bytes_count = 0; // The call to TransactNamedPipe below can be changed to a call @@ -254,7 +254,7 @@ bool CrashGenerationClient::RegisterClient(HANDLE pipe) { &reply, sizeof(ProtocolMessage), &bytes_count, - NULL)) { + nullptr)) { return false; } @@ -265,7 +265,7 @@ bool CrashGenerationClient::RegisterClient(HANDLE pipe) { ProtocolMessage ack_msg; ack_msg.tag = MESSAGE_TAG_REGISTRATION_ACK; - if (!WriteFile(pipe, &ack_msg, sizeof(ack_msg), &bytes_count, NULL)) { + if (!WriteFile(pipe, &ack_msg, sizeof(ack_msg), &bytes_count, nullptr)) { return false; } crash_event_ = reply.dump_request_handle; @@ -281,7 +281,7 @@ HANDLE CrashGenerationClient::ConnectToPipe(const wchar_t* pipe_name, DWORD flags_attrs) { if (pipe_handle_) { HANDLE t = pipe_handle_; - pipe_handle_ = NULL; + pipe_handle_ = nullptr; return t; } @@ -289,10 +289,10 @@ HANDLE CrashGenerationClient::ConnectToPipe(const wchar_t* pipe_name, HANDLE pipe = CreateFile(pipe_name, pipe_access, 0, - NULL, + nullptr, OPEN_EXISTING, flags_attrs, - NULL); + nullptr); if (pipe != INVALID_HANDLE_VALUE) { return pipe; } @@ -309,20 +309,20 @@ HANDLE CrashGenerationClient::ConnectToPipe(const wchar_t* pipe_name, } } - return NULL; + return nullptr; } bool CrashGenerationClient::ValidateResponse( const ProtocolMessage& msg) const { return (msg.tag == MESSAGE_TAG_REGISTRATION_RESPONSE) && (msg.id != 0) && - (msg.dump_request_handle != NULL) && - (msg.dump_generated_handle != NULL) && - (msg.server_alive_handle != NULL); + (msg.dump_request_handle != nullptr) && + (msg.dump_generated_handle != nullptr) && + (msg.server_alive_handle != nullptr); } bool CrashGenerationClient::IsRegistered() const { - return crash_event_ != NULL; + return crash_event_ != nullptr; } bool CrashGenerationClient::RequestDump(EXCEPTION_POINTERS* ex_info, @@ -344,11 +344,11 @@ bool CrashGenerationClient::RequestDump(EXCEPTION_POINTERS* ex_info, } bool CrashGenerationClient::RequestDump(EXCEPTION_POINTERS* ex_info) { - return RequestDump(ex_info, NULL); + return RequestDump(ex_info, nullptr); } bool CrashGenerationClient::RequestDump(MDRawAssertionInfo* assert_info) { - return RequestDump(NULL, assert_info); + return RequestDump(nullptr, assert_info); } bool CrashGenerationClient::SignalCrashEventAndWait() { @@ -383,8 +383,8 @@ HANDLE CrashGenerationClient::DuplicatePipeToClientProcess(const wchar_t* pipe_n HANDLE hProcess) { for (int i = 0; i < kPipeConnectMaxAttempts; ++i) { HANDLE local_pipe = CreateFile(pipe_name, kPipeDesiredAccess, - 0, NULL, OPEN_EXISTING, - kPipeFlagsAndAttributes, NULL); + 0, nullptr, OPEN_EXISTING, + kPipeFlagsAndAttributes, nullptr); if (local_pipe != INVALID_HANDLE_VALUE) { HANDLE remotePipe = INVALID_HANDLE_VALUE; if (DuplicateHandle(GetCurrentProcess(), local_pipe, diff --git a/src/client/windows/crash_generation/crash_generation_server.cc b/src/client/windows/crash_generation/crash_generation_server.cc index a8689d83e..c60b10d29 100644 --- a/src/client/windows/crash_generation/crash_generation_server.cc +++ b/src/client/windows/crash_generation/crash_generation_server.cc @@ -86,9 +86,9 @@ static bool IsClientRequestValid(const ProtocolMessage& msg) { return msg.tag == MESSAGE_TAG_UPLOAD_REQUEST || (msg.tag == MESSAGE_TAG_REGISTRATION_REQUEST && msg.id != 0 && - msg.thread_id != NULL && - msg.exception_pointers != NULL && - msg.assert_info != NULL); + msg.thread_id != nullptr && + msg.exception_pointers != nullptr && + msg.assert_info != nullptr); } #ifndef NDEBUG @@ -115,9 +115,9 @@ CrashGenerationServer::CrashGenerationServer( const std::wstring* dump_path) : pipe_name_(pipe_name), pipe_sec_attrs_(pipe_sec_attrs), - pipe_(NULL), - pipe_wait_handle_(NULL), - server_alive_handle_(NULL), + pipe_(nullptr), + pipe_wait_handle_(nullptr), + server_alive_handle_(nullptr), connect_callback_(connect_callback), connect_context_(connect_context), dump_callback_(dump_callback), @@ -132,7 +132,7 @@ CrashGenerationServer::CrashGenerationServer( server_state_(IPC_SERVER_STATE_UNINITIALIZED), shutting_down_(false), overlapped_(), - client_info_(NULL) { + client_info_(nullptr) { InitializeCriticalSection(&sync_); } @@ -221,16 +221,16 @@ bool CrashGenerationServer::Start() { server_state_ = IPC_SERVER_STATE_INITIAL; - server_alive_handle_ = CreateMutex(NULL, TRUE, NULL); + server_alive_handle_ = CreateMutex(nullptr, TRUE, nullptr); if (!server_alive_handle_) { return false; } // Event to signal the client connection and pipe reads and writes. - overlapped_.hEvent = CreateEvent(NULL, // Security descriptor. - TRUE, // Manual reset. - FALSE, // Initially nonsignaled. - NULL); // Name. + overlapped_.hEvent = CreateEvent(nullptr, // Security descriptor. + TRUE, // Manual reset. + FALSE, // Initially nonsignaled. + nullptr); // Name. if (!overlapped_.hEvent) { return false; } @@ -284,17 +284,17 @@ void CrashGenerationServer::HandleErrorState() { if (pipe_wait_handle_) { UnregisterWait(pipe_wait_handle_); - pipe_wait_handle_ = NULL; + pipe_wait_handle_ = nullptr; } if (pipe_) { CloseHandle(pipe_); - pipe_ = NULL; + pipe_ = nullptr; } if (overlapped_.hEvent) { CloseHandle(overlapped_.hEvent); - overlapped_.hEvent = NULL; + overlapped_.hEvent = nullptr; } } @@ -563,13 +563,13 @@ void CrashGenerationServer::HandleDisconnectingState() { assert(server_state_ == IPC_SERVER_STATE_DISCONNECTING); // Done serving the client. - client_info_ = NULL; + client_info_ = nullptr; - overlapped_.Internal = NULL; - overlapped_.InternalHigh = NULL; + overlapped_.Internal = nullptr; + overlapped_.InternalHigh = nullptr; overlapped_.Offset = 0; overlapped_.OffsetHigh = 0; - overlapped_.Pointer = NULL; + overlapped_.Pointer = nullptr; if (!ResetEvent(overlapped_.hEvent)) { EnterErrorState(); @@ -621,34 +621,34 @@ bool CrashGenerationServer::PrepareReply(const ClientInfo& client_info, if (reply->dump_request_handle) { DuplicateHandle(client_info.process_handle(), // hSourceProcessHandle reply->dump_request_handle, // hSourceHandle - NULL, // hTargetProcessHandle + nullptr, // hTargetProcessHandle 0, // lpTargetHandle 0, // dwDesiredAccess FALSE, // bInheritHandle DUPLICATE_CLOSE_SOURCE); // dwOptions - reply->dump_request_handle = NULL; + reply->dump_request_handle = nullptr; } if (reply->dump_generated_handle) { DuplicateHandle(client_info.process_handle(), // hSourceProcessHandle reply->dump_generated_handle, // hSourceHandle - NULL, // hTargetProcessHandle + nullptr, // hTargetProcessHandle 0, // lpTargetHandle 0, // dwDesiredAccess FALSE, // bInheritHandle DUPLICATE_CLOSE_SOURCE); // dwOptions - reply->dump_generated_handle = NULL; + reply->dump_generated_handle = nullptr; } if (reply->server_alive_handle) { DuplicateHandle(client_info.process_handle(), // hSourceProcessHandle reply->server_alive_handle, // hSourceHandle - NULL, // hTargetProcessHandle + nullptr, // hTargetProcessHandle 0, // lpTargetHandle 0, // dwDesiredAccess FALSE, // bInheritHandle DUPLICATE_CLOSE_SOURCE); // dwOptions - reply->server_alive_handle = NULL; + reply->server_alive_handle = nullptr; } return false; @@ -776,7 +776,7 @@ void CrashGenerationServer::HandleConnectionRequest() { } bool CrashGenerationServer::AddClient(ClientInfo* client_info) { - HANDLE request_wait_handle = NULL; + HANDLE request_wait_handle = nullptr; if (!RegisterWaitForSingleObject(&request_wait_handle, client_info->dump_requested_handle(), OnDumpRequest, @@ -789,7 +789,7 @@ bool CrashGenerationServer::AddClient(ClientInfo* client_info) { client_info->set_dump_request_wait_handle(request_wait_handle); // OnClientEnd will be called when the client process terminates. - HANDLE process_wait_handle = NULL; + HANDLE process_wait_handle = nullptr; if (!RegisterWaitForSingleObject(&process_wait_handle, client_info->process_handle(), OnClientEnd, @@ -895,7 +895,7 @@ void CrashGenerationServer::HandleDumpRequest(const ClientInfo& client_info) { } if (dump_callback_ && execute_callback) { - std::wstring* ptr_dump_path = (dump_path == L"") ? NULL : &dump_path; + std::wstring* ptr_dump_path = (dump_path == L"") ? nullptr : &dump_path; dump_callback_(dump_context_, &client_info, ptr_dump_path); } @@ -909,7 +909,7 @@ bool CrashGenerationServer::GenerateDump(const ClientInfo& client, // We have to get the address of EXCEPTION_INFORMATION from // the client process address space. - EXCEPTION_POINTERS* client_ex_info = NULL; + EXCEPTION_POINTERS* client_ex_info = nullptr; if (!client.GetClientExceptionInfo(&client_ex_info)) { return false; } diff --git a/src/client/windows/crash_generation/minidump_generator.cc b/src/client/windows/crash_generation/minidump_generator.cc index a0454cf94..c6d332e42 100644 --- a/src/client/windows/crash_generation/minidump_generator.cc +++ b/src/client/windows/crash_generation/minidump_generator.cc @@ -104,9 +104,9 @@ class HandleTraceData { }; HandleTraceData::HandleTraceData() - : verifier_module_(NULL), - enumerate_resource_(NULL), - handle_(NULL) { + : verifier_module_(nullptr), + enumerate_resource_(nullptr), + handle_(nullptr) { } HandleTraceData::~HandleTraceData() { @@ -211,7 +211,7 @@ bool HandleTraceData::ReadExceptionCode( exception_pointers, &pointers, sizeof(pointers), - NULL)) { + nullptr)) { return false; } @@ -219,7 +219,7 @@ bool HandleTraceData::ReadExceptionCode( pointers.ExceptionRecord, exception_code, sizeof(*exception_code), - NULL)) { + nullptr)) { return false; } @@ -261,10 +261,10 @@ MinidumpGenerator::MinidumpGenerator( MDRawAssertionInfo* assert_info, const MINIDUMP_TYPE dump_type, const bool is_client_pointers) - : dbghelp_module_(NULL), - write_dump_(NULL), - rpcrt4_module_(NULL), - create_uuid_(NULL), + : dbghelp_module_(nullptr), + write_dump_(nullptr), + rpcrt4_module_(nullptr), + create_uuid_(nullptr), process_handle_(process_handle), process_id_(process_id), thread_id_(thread_id), @@ -279,8 +279,8 @@ MinidumpGenerator::MinidumpGenerator( full_dump_file_(INVALID_HANDLE_VALUE), dump_file_is_internal_(false), full_dump_file_is_internal_(false), - additional_streams_(NULL), - callback_info_(NULL) { + additional_streams_(nullptr), + callback_info_(nullptr) { uuid_ = {0}; InitializeCriticalSection(&module_load_sync_); InitializeCriticalSection(&get_proc_address_sync_); @@ -319,7 +319,7 @@ bool MinidumpGenerator::WriteMinidump() { return false; } - MINIDUMP_EXCEPTION_INFORMATION* dump_exception_pointers = NULL; + MINIDUMP_EXCEPTION_INFORMATION* dump_exception_pointers = nullptr; MINIDUMP_EXCEPTION_INFORMATION dump_exception_info; // Setup the exception information object only if it's a dump @@ -437,7 +437,7 @@ bool MinidumpGenerator::WriteMinidump() { | MiniDumpWithHandleData), dump_exception_pointers, &user_streams, - NULL) != FALSE; + nullptr) != FALSE; } // Add handle operations trace stream to the minidump if it was collected. @@ -474,10 +474,10 @@ bool MinidumpGenerator::GenerateDumpFile(wstring* dump_path) { dump_file_ = CreateFile(dump_file_path.c_str(), GENERIC_WRITE, 0, - NULL, + nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, - NULL); + nullptr); if (dump_file_ == INVALID_HANDLE_VALUE) { return false; } @@ -509,10 +509,10 @@ bool MinidumpGenerator::GenerateFullDumpFile(wstring* full_dump_path) { full_dump_file_ = CreateFile(full_dump_file_path.c_str(), GENERIC_WRITE, 0, - NULL, + nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, - NULL); + nullptr); if (full_dump_file_ == INVALID_HANDLE_VALUE) { return false; } diff --git a/src/client/windows/handler/exception_handler.cc b/src/client/windows/handler/exception_handler.cc index d0da37f34..d1bbc3373 100644 --- a/src/client/windows/handler/exception_handler.cc +++ b/src/client/windows/handler/exception_handler.cc @@ -56,7 +56,7 @@ typedef struct { #define DBG_PRINTEXCEPTION_WIDE_C ((DWORD)0x4001000A) #endif -vector* ExceptionHandler::handler_stack_ = NULL; +vector* ExceptionHandler::handler_stack_ = nullptr; LONG ExceptionHandler::handler_stack_index_ = 0; CRITICAL_SECTION ExceptionHandler::handler_stack_critical_section_; volatile LONG ExceptionHandler::instance_count_ = 0; @@ -76,8 +76,8 @@ ExceptionHandler::ExceptionHandler(const wstring& dump_path, handler_types, dump_type, pipe_name, - NULL, // pipe_handle - NULL, // crash_generation_client + nullptr, // pipe_handle + nullptr, // crash_generation_client custom_info); } @@ -95,9 +95,9 @@ ExceptionHandler::ExceptionHandler(const wstring& dump_path, callback_context, handler_types, dump_type, - NULL, // pipe_name + nullptr, // pipe_name pipe_handle, - NULL, // crash_generation_client + nullptr, // crash_generation_client custom_info); } @@ -116,10 +116,10 @@ ExceptionHandler::ExceptionHandler( callback_context, handler_types, MiniDumpNormal, // dump_type - not used - NULL, // pipe_name - not used - NULL, // pipe_handle + nullptr, // pipe_name - not used + nullptr, // pipe_handle crash_generation_client, - NULL); // custom_info - not used + nullptr); // custom_info - not used } ExceptionHandler::ExceptionHandler(const wstring& dump_path, @@ -133,10 +133,10 @@ ExceptionHandler::ExceptionHandler(const wstring& dump_path, callback_context, handler_types, MiniDumpNormal, - NULL, // pipe_name - NULL, // pipe_handle - NULL, // crash_generation_client - NULL); // custom_info + nullptr, // pipe_name + nullptr, // pipe_handle + nullptr, // crash_generation_client + nullptr); // custom_info } void ExceptionHandler::Initialize( @@ -154,27 +154,27 @@ void ExceptionHandler::Initialize( filter_ = filter; callback_ = callback; callback_context_ = callback_context; - dump_path_c_ = NULL; - next_minidump_id_c_ = NULL; - next_minidump_path_c_ = NULL; - dbghelp_module_ = NULL; - minidump_write_dump_ = NULL; + dump_path_c_ = nullptr; + next_minidump_id_c_ = nullptr; + next_minidump_path_c_ = nullptr; + dbghelp_module_ = nullptr; + minidump_write_dump_ = nullptr; dump_type_ = dump_type; - rpcrt4_module_ = NULL; - uuid_create_ = NULL; + rpcrt4_module_ = nullptr; + uuid_create_ = nullptr; handler_types_ = handler_types; - previous_filter_ = NULL; + previous_filter_ = nullptr; #if _MSC_VER >= 1400 // MSVC 2005/8 - previous_iph_ = NULL; + previous_iph_ = nullptr; #endif // _MSC_VER >= 1400 - previous_pch_ = NULL; - handler_thread_ = NULL; + previous_pch_ = nullptr; + handler_thread_ = nullptr; is_shutdown_ = false; - handler_start_semaphore_ = NULL; - handler_finish_semaphore_ = NULL; + handler_start_semaphore_ = nullptr; + handler_finish_semaphore_ = nullptr; requesting_thread_id_ = 0; - exception_info_ = NULL; - assertion_ = NULL; + exception_info_ = nullptr; + assertion_ = nullptr; handler_return_value_ = false; handle_debug_exceptions_ = false; consume_invalid_handle_exceptions_ = false; @@ -192,7 +192,7 @@ void ExceptionHandler::Initialize( new CrashGenerationClient(pipe_handle, dump_type_, custom_info)); } - if (client.get() != NULL) { + if (client.get() != nullptr) { // If successful in registering with the monitoring process, // there is no need to setup in-process crash generation. if (client->Register()) { @@ -211,23 +211,24 @@ void ExceptionHandler::Initialize( // and it allows an easy way to get a snapshot of the requesting thread's // context outside of an exception. InitializeCriticalSection(&handler_critical_section_); - handler_start_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL); - assert(handler_start_semaphore_ != NULL); + handler_start_semaphore_ = CreateSemaphore(nullptr, 0, 1, nullptr); + assert(handler_start_semaphore_ != nullptr); - handler_finish_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL); - assert(handler_finish_semaphore_ != NULL); + handler_finish_semaphore_ = CreateSemaphore(nullptr, 0, 1, nullptr); + assert(handler_finish_semaphore_ != nullptr); // Don't attempt to create the thread if we could not create the semaphores. - if (handler_finish_semaphore_ != NULL && handler_start_semaphore_ != NULL) { + if (handler_finish_semaphore_ != nullptr && + handler_start_semaphore_ != nullptr) { DWORD thread_id; const int kExceptionHandlerThreadInitialStackSize = 64 * 1024; - handler_thread_ = CreateThread(NULL, // lpThreadAttributes + handler_thread_ = CreateThread(nullptr, // lpThreadAttributes kExceptionHandlerThreadInitialStackSize, ExceptionHandlerThreadMain, this, // lpParameter 0, // dwCreationFlags &thread_id); - assert(handler_thread_ != NULL); + assert(handler_thread_ != nullptr); } dbghelp_module_ = LoadLibrary(L"dbghelp.dll"); @@ -252,7 +253,7 @@ void ExceptionHandler::Initialize( // Reserve one element for the instruction memory AppMemory instruction_memory; - instruction_memory.ptr = NULL; + instruction_memory.ptr = nullptr; instruction_memory.length = 0; app_memory_info_.push_back(instruction_memory); @@ -339,7 +340,7 @@ ExceptionHandler::~ExceptionHandler() { // When destroying the last ExceptionHandler that installed a handler, // clean up the handler stack. delete handler_stack_; - handler_stack_ = NULL; + handler_stack_ = nullptr; } LeaveCriticalSection(&handler_stack_critical_section_); @@ -356,7 +357,7 @@ ExceptionHandler::~ExceptionHandler() { // deadlock if the exception handler is destroyed while executing code // inside DllMain. is_shutdown_ = true; - ReleaseSemaphore(handler_start_semaphore_, 1, NULL); + ReleaseSemaphore(handler_start_semaphore_, 1, nullptr); const int kWaitForHandlerThreadMs = 60000; WaitForSingleObject(handler_thread_, kWaitForHandlerThreadMs); #else @@ -364,7 +365,7 @@ ExceptionHandler::~ExceptionHandler() { #endif // BREAKPAD_NO_TERMINATE_THREAD CloseHandle(handler_thread_); - handler_thread_ = NULL; + handler_thread_ = nullptr; DeleteCriticalSection(&handler_critical_section_); CloseHandle(handler_start_semaphore_); CloseHandle(handler_finish_semaphore_); @@ -389,8 +390,8 @@ bool ExceptionHandler::RequestUpload(DWORD crash_id) { DWORD ExceptionHandler::ExceptionHandlerThreadMain(void* lpParameter) { ExceptionHandler* self = reinterpret_cast(lpParameter); assert(self); - assert(self->handler_start_semaphore_ != NULL); - assert(self->handler_finish_semaphore_ != NULL); + assert(self->handler_start_semaphore_ != nullptr); + assert(self->handler_finish_semaphore_ != nullptr); for (;;) { if (WaitForSingleObject(self->handler_start_semaphore_, INFINITE) == @@ -407,7 +408,7 @@ DWORD ExceptionHandler::ExceptionHandlerThreadMain(void* lpParameter) { } // Allow the requesting thread to proceed. - ReleaseSemaphore(self->handler_finish_semaphore_, 1, NULL); + ReleaseSemaphore(self->handler_finish_semaphore_, 1, nullptr); } } @@ -508,9 +509,9 @@ LONG ExceptionHandler::HandleException(EXCEPTION_POINTERS* exinfo) { success = current_handler->WriteMinidumpWithException( GetCurrentThreadId(), exinfo, - NULL); + nullptr); } else { - success = current_handler->WriteMinidumpOnHandlerThread(exinfo, NULL); + success = current_handler->WriteMinidumpOnHandlerThread(exinfo, nullptr); } } @@ -708,14 +709,14 @@ bool ExceptionHandler::WriteMinidumpOnHandlerThread( // There isn't much we can do if the handler thread // was not successfully created. - if (handler_thread_ == NULL) { + if (handler_thread_ == nullptr) { LeaveCriticalSection(&handler_critical_section_); return false; } // The handler thread should only be created when the semaphores are valid. - assert(handler_start_semaphore_ != NULL); - assert(handler_finish_semaphore_ != NULL); + assert(handler_start_semaphore_ != nullptr); + assert(handler_finish_semaphore_ != nullptr); // Set up data to be passed in to the handler thread. requesting_thread_id_ = GetCurrentThreadId(); @@ -723,7 +724,7 @@ bool ExceptionHandler::WriteMinidumpOnHandlerThread( assertion_ = assertion; // This causes the handler thread to call WriteMinidumpWithException. - ReleaseSemaphore(handler_start_semaphore_, 1, NULL); + ReleaseSemaphore(handler_start_semaphore_, 1, nullptr); // Wait until WriteMinidumpWithException is done and collect its return value. WaitForSingleObject(handler_finish_semaphore_, INFINITE); @@ -731,8 +732,8 @@ bool ExceptionHandler::WriteMinidumpOnHandlerThread( // Clean up. requesting_thread_id_ = 0; - exception_info_ = NULL; - assertion_ = NULL; + exception_info_ = nullptr; + assertion_ = nullptr; LeaveCriticalSection(&handler_critical_section_); @@ -760,10 +761,10 @@ bool ExceptionHandler::WriteMinidumpForException(EXCEPTION_POINTERS* exinfo) { if (IsOutOfProcess()) { return WriteMinidumpWithException(GetCurrentThreadId(), exinfo, - NULL); + nullptr); } - bool success = WriteMinidumpOnHandlerThread(exinfo, NULL); + bool success = WriteMinidumpOnHandlerThread(exinfo, nullptr); UpdateNextID(); return success; } @@ -773,8 +774,8 @@ bool ExceptionHandler::WriteMinidump(const wstring& dump_path, MinidumpCallback callback, void* callback_context, MINIDUMP_TYPE dump_type) { - ExceptionHandler handler(dump_path, NULL, callback, callback_context, - HANDLER_NONE, dump_type, (HANDLE)NULL, NULL); + ExceptionHandler handler(dump_path, nullptr, callback, callback_context, + HANDLER_NONE, dump_type, (HANDLE)nullptr, nullptr); return handler.WriteMinidump(); } @@ -787,7 +788,7 @@ bool ExceptionHandler::WriteMinidumpForChild(HANDLE child, MINIDUMP_TYPE dump_type) { EXCEPTION_RECORD ex; CONTEXT ctx; - EXCEPTION_POINTERS exinfo = { NULL, NULL }; + EXCEPTION_POINTERS exinfo = { nullptr, nullptr }; // As documented on MSDN, on failure SuspendThread returns (DWORD) -1 const DWORD kFailedToSuspendThread = static_cast(-1); DWORD last_suspend_count = kFailedToSuspendThread; @@ -798,7 +799,7 @@ bool ExceptionHandler::WriteMinidumpForChild(HANDLE child, child_blamed_thread); // This thread may have died already, so not opening the handle is a // non-fatal error. - if (child_thread_handle != NULL) { + if (child_thread_handle != nullptr) { last_suspend_count = SuspendThread(child_thread_handle); if (last_suspend_count != kFailedToSuspendThread) { ctx.ContextFlags = CONTEXT_ALL; @@ -816,12 +817,12 @@ bool ExceptionHandler::WriteMinidumpForChild(HANDLE child, } } - ExceptionHandler handler(dump_path, NULL, callback, callback_context, - HANDLER_NONE, dump_type, (HANDLE)NULL, NULL); + ExceptionHandler handler(dump_path, nullptr, callback, callback_context, + HANDLER_NONE, dump_type, (HANDLE)nullptr, nullptr); bool success = handler.WriteMinidumpWithExceptionForProcess( child_blamed_thread, - exinfo.ExceptionRecord ? &exinfo : NULL, - NULL, child, false); + exinfo.ExceptionRecord ? &exinfo : nullptr, + nullptr, child, false); if (last_suspend_count != kFailedToSuspendThread) { ResumeThread(child_thread_handle); @@ -831,7 +832,7 @@ bool ExceptionHandler::WriteMinidumpForChild(HANDLE child, if (callback) { success = callback(handler.dump_path_c_, handler.next_minidump_id_c_, - callback_context, NULL, NULL, success); + callback_context, nullptr, nullptr, success); } return success; @@ -924,10 +925,10 @@ bool ExceptionHandler::WriteMinidumpWithExceptionForProcess( HANDLE dump_file = CreateFile(next_minidump_path_c_, GENERIC_WRITE, 0, // no sharing - NULL, + nullptr, CREATE_NEW, // fail if exists FILE_ATTRIBUTE_NORMAL, - NULL); + nullptr); if (dump_file != INVALID_HANDLE_VALUE) { MINIDUMP_EXCEPTION_INFORMATION except_info; except_info.ThreadId = requesting_thread_id; @@ -1030,7 +1031,7 @@ bool ExceptionHandler::WriteMinidumpWithExceptionForProcess( GetProcessId(process), dump_file, dump_type_, - exinfo ? &except_info : NULL, + exinfo ? &except_info : nullptr, &user_streams, &callback) == TRUE); diff --git a/src/client/windows/handler/exception_handler.h b/src/client/windows/handler/exception_handler.h index 596ff872d..37ee68aaa 100644 --- a/src/client/windows/handler/exception_handler.h +++ b/src/client/windows/handler/exception_handler.h @@ -274,7 +274,9 @@ class ExceptionHandler { } // Returns whether out-of-process dump generation is used or not. - bool IsOutOfProcess() const { return crash_generation_client_.get() != NULL; } + bool IsOutOfProcess() const { + return crash_generation_client_.get() != nullptr; + } // Calling RegisterAppMemory(p, len) causes len bytes starting // at address p to be copied to the minidump when a crash happens. diff --git a/src/client/windows/sender/crash_report_sender.cc b/src/client/windows/sender/crash_report_sender.cc index 6ce0026ce..1433bd722 100644 --- a/src/client/windows/sender/crash_report_sender.cc +++ b/src/client/windows/sender/crash_report_sender.cc @@ -72,7 +72,7 @@ ReportResult CrashReportSender::SendCrashReport( int http_response = 0; bool result = HTTPUpload::SendMultipartPostRequest( - url, parameters, files, NULL, report_code, + url, parameters, files, nullptr, report_code, &http_response); if (result) { @@ -135,7 +135,7 @@ int CrashReportSender::OpenCheckpointFile(const wchar_t* mode, FILE** fd) { return _wfopen_s(fd, checkpoint_file_.c_str(), mode); #else *fd = _wfopen(checkpoint_file_.c_str(), mode); - if (*fd == NULL) { + if (*fd == nullptr) { return errno; } return 0; diff --git a/src/client/windows/tests/crash_generation_app/crash_generation_app.cc b/src/client/windows/tests/crash_generation_app/crash_generation_app.cc index 9ae4679e3..7bc22286e 100644 --- a/src/client/windows/tests/crash_generation_app/crash_generation_app.cc +++ b/src/client/windows/tests/crash_generation_app/crash_generation_app.cc @@ -62,7 +62,7 @@ const DWORD kEditBoxStyles = WS_CHILD | const size_t kMaximumLineLength = 256; // CS to access edit control in a thread safe way. -static CRITICAL_SECTION* cs_edit = NULL; +static CRITICAL_SECTION* cs_edit = nullptr; // Edit control. static HWND client_status_edit_box; @@ -82,8 +82,8 @@ static CustomInfoEntry kCustomInfoEntries[] = { CustomInfoEntry(L"ver", L"1.0"), }; -static ExceptionHandler* handler = NULL; -static CrashGenerationServer* crash_server = NULL; +static ExceptionHandler* handler = nullptr; +static CrashGenerationServer* crash_server = nullptr; // Registers the window class. // @@ -102,7 +102,7 @@ ATOM MyRegisterClass(HINSTANCE instance) { wcex.hInstance = instance; wcex.hIcon = LoadIcon(instance, MAKEINTRESOURCE(IDI_CRASHGENERATIONAPP)); - wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_CRASHGENERATIONAPP); wcex.lpszClassName = window_class; @@ -124,10 +124,10 @@ BOOL InitInstance(HINSTANCE instance, int command_show) { 0, CW_USEDEFAULT, 0, - NULL, - NULL, + nullptr, + nullptr, instance, - NULL); + nullptr); if (!wnd) { return FALSE; @@ -288,33 +288,33 @@ void CrashServerStart() { std::wstring dump_path = L"C:\\Dumps\\"; if (_wmkdir(dump_path.c_str()) && (errno != EEXIST)) { - MessageBoxW(NULL, L"Unable to create dump directory", L"Dumper", MB_OK); + MessageBoxW(nullptr, L"Unable to create dump directory", L"Dumper", MB_OK); return; } crash_server = new CrashGenerationServer(kPipeName, - NULL, + nullptr, ShowClientConnected, - NULL, + nullptr, ShowClientCrashed, - NULL, + nullptr, ShowClientExited, - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, true, &dump_path); if (!crash_server->Start()) { - MessageBoxW(NULL, L"Unable to start server", L"Dumper", MB_OK); + MessageBoxW(nullptr, L"Unable to start server", L"Dumper", MB_OK); delete crash_server; - crash_server = NULL; + crash_server = nullptr; } } void CrashServerStop() { delete crash_server; - crash_server = NULL; + crash_server = nullptr; } void DerefZeroCrash() { @@ -323,7 +323,7 @@ void DerefZeroCrash() { } void InvalidParamCrash() { - printf(NULL); + printf(nullptr); } void PureCallCrash() { @@ -332,7 +332,7 @@ void PureCallCrash() { void RequestDump() { if (!handler->WriteMinidump()) { - MessageBoxW(NULL, L"Dump request failed", L"Dumper", MB_OK); + MessageBoxW(nullptr, L"Dump request failed", L"Dumper", MB_OK); } kCustomInfoEntries[1].set_value(L"1.1"); } @@ -407,16 +407,16 @@ LRESULT CALLBACK WndProc(HWND wnd, break; case WM_CREATE: client_status_edit_box = CreateWindow(TEXT("EDIT"), - NULL, + nullptr, kEditBoxStyles, 0, 0, 0, 0, wnd, - NULL, + nullptr, instance, - NULL); + nullptr); break; case WM_SIZE: // Make the edit control the size of the window's client area. @@ -487,9 +487,9 @@ int APIENTRY _tWinMain(HINSTANCE instance, // failures and instead let the code handle it. _CrtSetReportMode(_CRT_ASSERT, 0); handler = new ExceptionHandler(L"C:\\dumps\\", - NULL, + nullptr, google_breakpad::ShowDumpResults, - NULL, + nullptr, ExceptionHandler::HANDLER_ALL, MiniDumpNormal, kPipeName, @@ -514,7 +514,7 @@ int APIENTRY _tWinMain(HINSTANCE instance, // Main message loop. MSG msg; - while (GetMessage(&msg, NULL, 0, 0)) { + while (GetMessage(&msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, accel_table, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); diff --git a/src/client/windows/unittests/crash_generation_server_test.cc b/src/client/windows/unittests/crash_generation_server_test.cc index adb03f400..cc117040b 100644 --- a/src/client/windows/unittests/crash_generation_server_test.cc +++ b/src/client/windows/unittests/crash_generation_server_test.cc @@ -61,15 +61,15 @@ class CrashGenerationServerTest : public ::testing::Test { public: CrashGenerationServerTest() : crash_generation_server_(kPipeName, - NULL, + nullptr, CallOnClientConnected, &mock_callbacks_, CallOnClientDumpRequested, &mock_callbacks_, CallOnClientExited, &mock_callbacks_, CallOnClientUploadRequested, &mock_callbacks_, false, - NULL), + nullptr), thread_id_(0), - exception_pointers_(NULL) { + exception_pointers_(nullptr) { memset(&assert_info_, 0, sizeof(assert_info_)); } @@ -106,10 +106,10 @@ class CrashGenerationServerTest : public ::testing::Test { HANDLE pipe = CreateFile(kPipeName, kPipeDesiredAccess, 0, - NULL, + nullptr, OPEN_EXISTING, kPipeFlagsAndAttributes, - NULL); + nullptr); if (pipe == INVALID_HANDLE_VALUE) { ASSERT_EQ(ERROR_PIPE_BUSY, GetLastError()); @@ -120,16 +120,16 @@ class CrashGenerationServerTest : public ::testing::Test { pipe = CreateFile(kPipeName, kPipeDesiredAccess, 0, - NULL, + nullptr, OPEN_EXISTING, kPipeFlagsAndAttributes, - NULL); + nullptr); } ASSERT_NE(pipe, INVALID_HANDLE_VALUE); DWORD mode = kPipeMode; - ASSERT_TRUE(SetNamedPipeHandleState(pipe, &mode, NULL, NULL)); + ASSERT_TRUE(SetNamedPipeHandleState(pipe, &mode, nullptr, nullptr)); DoFaultyClient(fault_type, pipe); @@ -177,9 +177,9 @@ class CrashGenerationServerTest : public ::testing::Test { &exception_pointers_, &assert_info_, custom_info, - NULL, - NULL, - NULL); + nullptr, + nullptr, + nullptr); DWORD bytes_count = 0; @@ -188,7 +188,7 @@ class CrashGenerationServerTest : public ::testing::Test { fault_type == TRUNCATE_REGISTRATION ? sizeof(msg) / 2 : sizeof(msg), &bytes_count, - NULL)); + nullptr)); if (fault_type == CLOSE_AFTER_REGISTRATION) { return; @@ -202,7 +202,7 @@ class CrashGenerationServerTest : public ::testing::Test { sizeof(google_breakpad::ProtocolMessage) / 2 : sizeof(google_breakpad::ProtocolMessage), &bytes_count, - NULL)) { + nullptr)) { switch (fault_type) { case TRUNCATE_REGISTRATION: case RESPONSE_BUFFER_TOO_SMALL: @@ -226,7 +226,7 @@ class CrashGenerationServerTest : public ::testing::Test { SEND_INVALID_ACK ? sizeof(ack_msg) : sizeof(ack_msg) / 2, &bytes_count, - NULL)); + nullptr)); return; } diff --git a/src/client/windows/unittests/dump_analysis.cc b/src/client/windows/unittests/dump_analysis.cc index c403d8556..5dd3dc338 100644 --- a/src/client/windows/unittests/dump_analysis.cc +++ b/src/client/windows/unittests/dump_analysis.cc @@ -38,52 +38,52 @@ #include "client/windows/unittests/dump_analysis.h" // NOLINT DumpAnalysis::~DumpAnalysis() { - if (dump_file_view_ != NULL) { + if (dump_file_view_ != nullptr) { EXPECT_TRUE(::UnmapViewOfFile(dump_file_view_)); ::CloseHandle(dump_file_mapping_); - dump_file_mapping_ = NULL; + dump_file_mapping_ = nullptr; } - if (dump_file_handle_ != NULL) { + if (dump_file_handle_ != nullptr) { ::CloseHandle(dump_file_handle_); - dump_file_handle_ = NULL; + dump_file_handle_ = nullptr; } } void DumpAnalysis::EnsureDumpMapped() { - if (dump_file_view_ == NULL) { + if (dump_file_view_ == nullptr) { dump_file_handle_ = ::CreateFile(dump_file_.c_str(), GENERIC_READ, 0, - NULL, + nullptr, OPEN_EXISTING, 0, - NULL); - ASSERT_TRUE(dump_file_handle_ != NULL); - ASSERT_TRUE(dump_file_mapping_ == NULL); + nullptr); + ASSERT_TRUE(dump_file_handle_ != nullptr); + ASSERT_TRUE(dump_file_mapping_ == nullptr); dump_file_mapping_ = ::CreateFileMapping(dump_file_handle_, - NULL, + nullptr, PAGE_READONLY, 0, 0, - NULL); - ASSERT_TRUE(dump_file_mapping_ != NULL); + nullptr); + ASSERT_TRUE(dump_file_mapping_ != nullptr); dump_file_view_ = ::MapViewOfFile(dump_file_mapping_, FILE_MAP_READ, 0, 0, 0); - ASSERT_TRUE(dump_file_view_ != NULL); + ASSERT_TRUE(dump_file_view_ != nullptr); } } bool DumpAnalysis::HasTebs() const { - MINIDUMP_THREAD_LIST* thread_list = NULL; + MINIDUMP_THREAD_LIST* thread_list = nullptr; size_t thread_list_size = GetStream(ThreadListStream, &thread_list); - if (thread_list_size > 0 && thread_list != NULL) { + if (thread_list_size > 0 && thread_list != nullptr) { for (ULONG i = 0; i < thread_list->NumberOfThreads; ++i) { if (!HasMemory(thread_list->Threads[i].Teb)) return false; @@ -97,12 +97,12 @@ bool DumpAnalysis::HasTebs() const { } bool DumpAnalysis::HasPeb() const { - MINIDUMP_THREAD_LIST* thread_list = NULL; + MINIDUMP_THREAD_LIST* thread_list = nullptr; size_t thread_list_size = GetStream(ThreadListStream, &thread_list); - if (thread_list_size > 0 && thread_list != NULL && + if (thread_list_size > 0 && thread_list != nullptr && thread_list->NumberOfThreads > 0) { - FakeTEB* teb = NULL; + FakeTEB* teb = nullptr; if (!HasMemory(thread_list->Threads[0].Teb, &teb)) return false; @@ -113,13 +113,13 @@ bool DumpAnalysis::HasPeb() const { } bool DumpAnalysis::HasStream(ULONG stream_number) const { - void* stream = NULL; + void* stream = nullptr; size_t stream_size = GetStreamImpl(stream_number, &stream); - return stream_size > 0 && stream != NULL; + return stream_size > 0 && stream != nullptr; } size_t DumpAnalysis::GetStreamImpl(ULONG stream_number, void** stream) const { - MINIDUMP_DIRECTORY* directory = NULL; + MINIDUMP_DIRECTORY* directory = nullptr; ULONG memory_list_size = 0; BOOL ret = ::MiniDumpReadDumpStream(dump_file_view_, stream_number, @@ -133,9 +133,9 @@ size_t DumpAnalysis::GetStreamImpl(ULONG stream_number, void** stream) const { bool DumpAnalysis::HasMemoryImpl(const void* addr_in, size_t structuresize, void** structure) const { uintptr_t address = reinterpret_cast(addr_in); - MINIDUMP_MEMORY_LIST* memory_list = NULL; + MINIDUMP_MEMORY_LIST* memory_list = nullptr; size_t memory_list_size = GetStream(MemoryListStream, &memory_list); - if (memory_list_size > 0 && memory_list != NULL) { + if (memory_list_size > 0 && memory_list != nullptr) { for (ULONG i = 0; i < memory_list->NumberOfMemoryRanges; ++i) { MINIDUMP_MEMORY_DESCRIPTOR& descr = memory_list->MemoryRanges[i]; const uintptr_t range_start = @@ -146,7 +146,7 @@ bool DumpAnalysis::HasMemoryImpl(const void* addr_in, size_t structuresize, address + structuresize < range_end) { // The start address falls in the range, and the end address is // in bounds, return a pointer to the structure if requested. - if (structure != NULL) + if (structure != nullptr) *structure = RVA_TO_ADDR(dump_file_view_, descr.Memory.Rva); return true; @@ -157,9 +157,9 @@ bool DumpAnalysis::HasMemoryImpl(const void* addr_in, size_t structuresize, // We didn't find the range in a MINIDUMP_MEMORY_LIST, so maybe this // is a full dump using MINIDUMP_MEMORY64_LIST with all the memory at the // end of the dump file. - MINIDUMP_MEMORY64_LIST* memory64_list = NULL; + MINIDUMP_MEMORY64_LIST* memory64_list = nullptr; memory_list_size = GetStream(Memory64ListStream, &memory64_list); - if (memory_list_size > 0 && memory64_list != NULL) { + if (memory_list_size > 0 && memory64_list != nullptr) { // Keep track of where the current descriptor maps to. RVA64 curr_rva = memory64_list->BaseRva; for (ULONG i = 0; i < memory64_list->NumberOfMemoryRanges; ++i) { @@ -172,7 +172,7 @@ bool DumpAnalysis::HasMemoryImpl(const void* addr_in, size_t structuresize, address + structuresize < range_end) { // The start address falls in the range, and the end address is // in bounds, return a pointer to the structure if requested. - if (structure != NULL) + if (structure != nullptr) *structure = RVA_TO_ADDR(dump_file_view_, curr_rva); return true; diff --git a/src/client/windows/unittests/dump_analysis.h b/src/client/windows/unittests/dump_analysis.h index f8acc268d..87116b902 100644 --- a/src/client/windows/unittests/dump_analysis.h +++ b/src/client/windows/unittests/dump_analysis.h @@ -40,8 +40,10 @@ struct FakeTEB { class DumpAnalysis { public: explicit DumpAnalysis(const std::wstring& file_path) - : dump_file_(file_path), dump_file_view_(NULL), dump_file_mapping_(NULL), - dump_file_handle_(NULL) { + : dump_file_(file_path), + dump_file_view_(nullptr), + dump_file_mapping_(nullptr), + dump_file_handle_(nullptr) { EnsureDumpMapped(); } ~DumpAnalysis(); @@ -59,15 +61,15 @@ class DumpAnalysis { bool HasTebs() const; bool HasPeb() const; bool HasMemory(ULONG64 address) const { - return HasMemory(address, NULL); + return HasMemory(address, nullptr); } bool HasMemory(const void* address) const { - return HasMemory(address, NULL); + return HasMemory(address, nullptr); } template - bool HasMemory(ULONG64 address, StructureType** structure = NULL) const { + bool HasMemory(ULONG64 address, StructureType** structure = nullptr) const { // We can't cope with 64 bit addresses for now. if (address > 0xFFFFFFFFUL) return false; @@ -76,7 +78,8 @@ class DumpAnalysis { } template - bool HasMemory(const void* addr_in, StructureType** structure = NULL) const { + bool HasMemory(const void* addr_in, + StructureType** structure = nullptr) const { return HasMemoryImpl(addr_in, sizeof(StructureType), reinterpret_cast(structure)); } diff --git a/src/client/windows/unittests/exception_handler_death_test.cc b/src/client/windows/unittests/exception_handler_death_test.cc index 3129aab1c..e7868aefe 100644 --- a/src/client/windows/unittests/exception_handler_death_test.cc +++ b/src/client/windows/unittests/exception_handler_death_test.cc @@ -93,7 +93,7 @@ void ExceptionHandlerDeathTest::SetUp() { assert(false); } StringCchPrintfW(temp_path_, MAX_PATH, L"%s%s", temp_path, test_name_wide); - CreateDirectory(temp_path_, NULL); + CreateDirectory(temp_path_, nullptr); } BOOL DoesPathExist(const TCHAR* path_name) { @@ -131,15 +131,15 @@ TEST_F(ExceptionHandlerDeathTest, InProcTest) { std::unique_ptr exc( new google_breakpad::ExceptionHandler( temp_path_, - NULL, + nullptr, &MinidumpWrittenCallback, - NULL, + nullptr, google_breakpad::ExceptionHandler::HANDLER_ALL)); // Disable GTest SEH handler testing::DisableExceptionHandlerInScope disable_exception_handler; - int* i = NULL; + int* i = nullptr; ASSERT_DEATH((*i)++, kSuccessIndicator); } @@ -159,26 +159,26 @@ void ExceptionHandlerDeathTest::DoCrashAccessViolation( google_breakpad::CrashGenerationClient* client = new google_breakpad::CrashGenerationClient(kPipeName, MiniDumpNormal, - NULL); // custom_info + nullptr); // custom_info ASSERT_TRUE(client->Register()); exc.reset(new google_breakpad::ExceptionHandler( temp_path_, - NULL, // filter - NULL, // callback - NULL, // callback_context + nullptr, // filter + nullptr, // callback + nullptr, // callback_context google_breakpad::ExceptionHandler::HANDLER_ALL, client)); } else { ASSERT_TRUE(out_of_proc_guarantee == OUT_OF_PROC_BEST_EFFORT); exc.reset(new google_breakpad::ExceptionHandler( temp_path_, - NULL, // filter - NULL, // callback - NULL, // callback_context + nullptr, // filter + nullptr, // callback + nullptr, // callback_context google_breakpad::ExceptionHandler::HANDLER_ALL, MiniDumpNormal, kPipeName, - NULL)); // custom_info + nullptr)); // custom_info } // Disable GTest SEH handler @@ -188,7 +188,7 @@ void ExceptionHandlerDeathTest::DoCrashAccessViolation( // if it's not true we'll still get an error rather than the crash // being expected. ASSERT_TRUE(exc->IsOutOfProcess()); - int* i = NULL; + int* i = nullptr; printf("%d\n", (*i)++); } @@ -204,8 +204,8 @@ TEST_F(ExceptionHandlerDeathTest, OutOfProcTest) { ASSERT_TRUE(DoesPathExist(temp_path_)); std::wstring dump_path(temp_path_); google_breakpad::CrashGenerationServer server( - kPipeName, NULL, NULL, NULL, &clientDumpCallback, NULL, NULL, NULL, NULL, - NULL, true, &dump_path); + kPipeName, nullptr, nullptr, nullptr, &clientDumpCallback, nullptr, + nullptr, nullptr, nullptr, nullptr, true, &dump_path); // This HAS to be EXPECT_, because when this test case is executed in the // child process, the server registration will fail due to the named pipe @@ -227,8 +227,8 @@ TEST_F(ExceptionHandlerDeathTest, OutOfProcGuaranteedTest) { ASSERT_TRUE(DoesPathExist(temp_path_)); std::wstring dump_path(temp_path_); google_breakpad::CrashGenerationServer server( - kPipeName, NULL, NULL, NULL, &clientDumpCallback, NULL, NULL, NULL, NULL, - NULL, true, &dump_path); + kPipeName, nullptr, nullptr, nullptr, &clientDumpCallback, nullptr, + nullptr, nullptr, nullptr, nullptr, true, &dump_path); // This HAS to be EXPECT_, because when this test case is executed in the // child process, the server registration will fail due to the named pipe @@ -243,7 +243,7 @@ TEST_F(ExceptionHandlerDeathTest, InvalidParameterTest) { using google_breakpad::ExceptionHandler; ASSERT_TRUE(DoesPathExist(temp_path_)); - ExceptionHandler handler(temp_path_, NULL, NULL, NULL, + ExceptionHandler handler(temp_path_, nullptr, nullptr, nullptr, ExceptionHandler::HANDLER_INVALID_PARAMETER); // Disable the message box for assertions @@ -251,7 +251,7 @@ TEST_F(ExceptionHandlerDeathTest, InvalidParameterTest) { // Call with a bad argument. The invalid parameter will be swallowed // and a dump will be generated, the process will exit(0). - ASSERT_EXIT(printf(NULL), ::testing::ExitedWithCode(0), ""); + ASSERT_EXIT(printf(nullptr), ::testing::ExitedWithCode(0), ""); } @@ -277,7 +277,7 @@ TEST_F(ExceptionHandlerDeathTest, PureVirtualCallTest) { using google_breakpad::ExceptionHandler; ASSERT_TRUE(DoesPathExist(temp_path_)); - ExceptionHandler handler(temp_path_, NULL, NULL, NULL, + ExceptionHandler handler(temp_path_, nullptr, nullptr, nullptr, ExceptionHandler::HANDLER_PURECALL); // Disable the message box for assertions @@ -318,9 +318,9 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemory) { std::unique_ptr exc( new google_breakpad::ExceptionHandler( temp_path_, - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, google_breakpad::ExceptionHandler::HANDLER_ALL)); // Disable GTest SEH handler @@ -331,7 +331,7 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemory) { const int kOffset = kMemorySize / 2; // This crashes with SIGILL on x86/x86-64/arm. const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff }; - char* memory = reinterpret_cast(VirtualAlloc(NULL, + char* memory = reinterpret_cast(VirtualAlloc(nullptr, kMemorySize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)); @@ -410,9 +410,9 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMinBound) { std::unique_ptr exc( new google_breakpad::ExceptionHandler( temp_path_, - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, google_breakpad::ExceptionHandler::HANDLER_ALL)); // Disable GTest SEH handler @@ -428,7 +428,7 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMinBound) { const unsigned char instructions[] = { 0xff, 0xff, 0xff, 0xff }; // Get some executable memory. Specifically, reserve two pages, // but only commit the second. - char* all_memory = reinterpret_cast(VirtualAlloc(NULL, + char* all_memory = reinterpret_cast(VirtualAlloc(nullptr, kPageSize * 2, MEM_RESERVE, PAGE_NOACCESS)); @@ -503,9 +503,9 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMaxBound) { std::unique_ptr exc( new google_breakpad::ExceptionHandler( temp_path_, - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, google_breakpad::ExceptionHandler::HANDLER_ALL)); // Disable GTest SEH handler @@ -520,7 +520,7 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMaxBound) { const int kOffset = kPageSize - sizeof(instructions); // Get some executable memory. Specifically, reserve two pages, // but only commit the first. - char* memory = reinterpret_cast(VirtualAlloc(NULL, + char* memory = reinterpret_cast(VirtualAlloc(nullptr, kPageSize * 2, MEM_RESERVE, PAGE_NOACCESS)); diff --git a/src/client/windows/unittests/exception_handler_nesting_test.cc b/src/client/windows/unittests/exception_handler_nesting_test.cc index 7fa6ac226..5b6420b3e 100644 --- a/src/client/windows/unittests/exception_handler_nesting_test.cc +++ b/src/client/windows/unittests/exception_handler_nesting_test.cc @@ -136,7 +136,7 @@ void DoCrash(const char* message) { fprintf(stderr, "%s", message); fflush(stderr); } - int* i = NULL; + int* i = nullptr; (*i)++; ASSERT_TRUE(false); @@ -156,23 +156,23 @@ void InstallExceptionHandlerAndCrash(bool install_filter, (filter_return_value ? &CrashHandlerFilter : &CrashHandlerFilter) : - NULL, + nullptr, install_callback ? (callback_return_value ? &MinidumpWrittenCallback : &MinidumpWrittenCallback) : - NULL, - NULL, // callback_context + nullptr, + nullptr, // callback_context google_breakpad::ExceptionHandler::HANDLER_EXCEPTION); // Disable GTest SEH handler testing::DisableExceptionHandlerInScope disable_exception_handler; - DoCrash(NULL); + DoCrash(nullptr); } TEST(AssertDeathSanity, Simple) { - ASSERT_DEATH(DoCrash(NULL), ""); + ASSERT_DEATH(DoCrash(nullptr), ""); } TEST(AssertDeathSanity, Regex) { @@ -264,7 +264,7 @@ TEST(ExceptionHandlerNesting, Skip_From_Inner_Filter) { temp_path, &CrashHandlerFilter, &MinidumpWrittenCallback, - NULL, // callback_context + nullptr, // callback_context google_breakpad::ExceptionHandler::HANDLER_EXCEPTION); ASSERT_DEATH( @@ -288,7 +288,7 @@ TEST(ExceptionHandlerNesting, Skip_From_Inner_Callback) { temp_path, &CrashHandlerFilter, &MinidumpWrittenCallback, - NULL, // callback_context + nullptr, // callback_context google_breakpad::ExceptionHandler::HANDLER_EXCEPTION); ASSERT_DEATH( @@ -313,7 +313,7 @@ TEST(ExceptionHandlerNesting, Handled_By_Inner_Handler) { temp_path, &CrashHandlerFilter, &MinidumpWrittenCallback, - NULL, // callback_context + nullptr, // callback_context google_breakpad::ExceptionHandler::HANDLER_EXCEPTION); ASSERT_DEATH( diff --git a/src/client/windows/unittests/exception_handler_test.cc b/src/client/windows/unittests/exception_handler_test.cc index f658726ba..1b4bc24fd 100644 --- a/src/client/windows/unittests/exception_handler_test.cc +++ b/src/client/windows/unittests/exception_handler_test.cc @@ -130,7 +130,7 @@ void ExceptionHandlerTest::SetUp() { assert(false); } StringCchPrintfW(temp_path_, MAX_PATH, L"%s%s", temp_path, test_name_wide); - CreateDirectory(temp_path_, NULL); + CreateDirectory(temp_path_, nullptr); } void ExceptionHandlerTest::TearDown() { @@ -179,9 +179,9 @@ bool ExceptionHandlerTest::DumpCallback(const wchar_t* dump_path, void ExceptionHandlerTest::DoCrashInvalidParameter() { google_breakpad::ExceptionHandler* exc = new google_breakpad::ExceptionHandler( - temp_path_, NULL, NULL, NULL, + temp_path_, nullptr, nullptr, nullptr, google_breakpad::ExceptionHandler::HANDLER_INVALID_PARAMETER, - kFullDumpType, kPipeName, NULL); + kFullDumpType, kPipeName, nullptr); // Disable the message box for assertions _CrtSetReportMode(_CRT_ASSERT, 0); @@ -190,7 +190,7 @@ void ExceptionHandlerTest::DoCrashInvalidParameter() { // if it's not true we'll still get an error rather than the crash // being expected. ASSERT_TRUE(exc->IsOutOfProcess()); - printf(NULL); + printf(nullptr); } @@ -211,9 +211,9 @@ struct PureVirtualCall : public PureVirtualCallBase { void ExceptionHandlerTest::DoCrashPureVirtualCall() { google_breakpad::ExceptionHandler* exc = new google_breakpad::ExceptionHandler( - temp_path_, NULL, NULL, NULL, + temp_path_, nullptr, nullptr, nullptr, google_breakpad::ExceptionHandler::HANDLER_PURECALL, - kFullDumpType, kPipeName, NULL); + kFullDumpType, kPipeName, nullptr); // Disable the message box for assertions _CrtSetReportMode(_CRT_ASSERT, 0); @@ -238,8 +238,8 @@ TEST_F(ExceptionHandlerTest, InvalidParameterMiniDumpTest) { ASSERT_TRUE(DoesPathExist(temp_path_)); wstring dump_path(temp_path_); google_breakpad::CrashGenerationServer server( - kPipeName, NULL, NULL, NULL, ClientDumpCallback, NULL, NULL, NULL, NULL, - NULL, true, &dump_path); + kPipeName, nullptr, nullptr, nullptr, ClientDumpCallback, nullptr, + nullptr, nullptr, nullptr, nullptr, true, &dump_path); ASSERT_TRUE(dump_file.empty() && full_dump_file.empty()); @@ -310,8 +310,8 @@ TEST_F(ExceptionHandlerTest, PureVirtualCallMiniDumpTest) { ASSERT_TRUE(DoesPathExist(temp_path_)); wstring dump_path(temp_path_); google_breakpad::CrashGenerationServer server( - kPipeName, NULL, NULL, NULL, ClientDumpCallback, NULL, NULL, NULL, NULL, - NULL, true, &dump_path); + kPipeName, nullptr, nullptr, nullptr, ClientDumpCallback, nullptr, + nullptr, nullptr, nullptr, nullptr, true, &dump_path); ASSERT_TRUE(dump_file.empty() && full_dump_file.empty()); @@ -377,9 +377,9 @@ TEST_F(ExceptionHandlerTest, PureVirtualCallMiniDumpTest) { // some expected structures. TEST_F(ExceptionHandlerTest, WriteMinidumpTest) { ExceptionHandler handler(temp_path_, - NULL, + nullptr, DumpCallback, - NULL, + nullptr, ExceptionHandler::HANDLER_ALL); // Disable GTest SEH handler @@ -415,9 +415,9 @@ TEST_F(ExceptionHandlerTest, AdditionalMemory) { } ExceptionHandler handler(temp_path_, - NULL, + nullptr, DumpCallback, - NULL, + nullptr, ExceptionHandler::HANDLER_ALL); // Disable GTest SEH handler @@ -469,9 +469,9 @@ TEST_F(ExceptionHandlerTest, AdditionalMemoryRemove) { } ExceptionHandler handler(temp_path_, - NULL, + nullptr, DumpCallback, - NULL, + nullptr, ExceptionHandler::HANDLER_ALL); // Disable GTest SEH handler diff --git a/src/client/windows/unittests/minidump_test.cc b/src/client/windows/unittests/minidump_test.cc index 741447df4..1fe52f5cc 100644 --- a/src/client/windows/unittests/minidump_test.cc +++ b/src/client/windows/unittests/minidump_test.cc @@ -68,12 +68,12 @@ class MinidumpTest: public testing::Test { virtual void SetUp() { // Make sure URLMon isn't loaded into our process. - ASSERT_EQ(NULL, ::GetModuleHandle(L"urlmon.dll")); + ASSERT_EQ(nullptr, ::GetModuleHandle(L"urlmon.dll")); // Then load and unload it to ensure we have something to // stock the unloaded module list with. HMODULE urlmon = ::LoadLibrary(L"urlmon.dll"); - ASSERT_TRUE(urlmon != NULL); + ASSERT_TRUE(urlmon != nullptr); ASSERT_TRUE(::FreeLibrary(urlmon)); } @@ -95,7 +95,7 @@ class MinidumpTest: public testing::Test { EXCEPTION_RECORD ex_record = { STATUS_ACCESS_VIOLATION, // ExceptionCode 0, // ExceptionFlags - NULL, // ExceptionRecord; + nullptr, // ExceptionRecord; reinterpret_cast(static_cast(0xCAFEBABE)), // ExceptionAddress; 2, // NumberParameters; { EXCEPTION_WRITE_FAULT, reinterpret_cast(this) } @@ -112,7 +112,7 @@ class MinidumpTest: public testing::Test { ::GetCurrentThreadId(), ::GetCurrentThreadId(), &ex_ptrs, - NULL, + nullptr, static_cast(flags), TRUE); generator.GenerateDumpFile(&dump_file_); @@ -135,7 +135,7 @@ bool HasFileInfo(const std::wstring& file_path) { const wchar_t* path = file_path.c_str(); DWORD length = ::GetFileVersionInfoSize(path, &dummy); if (length == 0) - return NULL; + return nullptr; void* data = calloc(length, 1); if (!data) @@ -146,7 +146,7 @@ bool HasFileInfo(const std::wstring& file_path) { return false; } - void* translate = NULL; + void* translate = nullptr; UINT page_count; BOOL query_result = VerQueryValue( data, @@ -167,14 +167,14 @@ TEST_F(MinidumpTest, Version) { ImagehlpApiVersion(); HMODULE dbg_help = ::GetModuleHandle(L"dbghelp.dll"); - ASSERT_TRUE(dbg_help != NULL); + ASSERT_TRUE(dbg_help != nullptr); wchar_t dbg_help_file[1024] = {}; ASSERT_TRUE(::GetModuleFileName(dbg_help, dbg_help_file, sizeof(dbg_help_file) / sizeof(*dbg_help_file))); - ASSERT_TRUE(HasFileInfo(std::wstring(dbg_help_file)) != NULL); + ASSERT_TRUE(HasFileInfo(std::wstring(dbg_help_file)) != nullptr); // LOG(INFO) << "DbgHelp.dll version: " << file_info->file_version(); } diff --git a/src/common/android/testing/mkdtemp.h b/src/common/android/testing/mkdtemp.h index f05cf653d..2664e8012 100644 --- a/src/common/android/testing/mkdtemp.h +++ b/src/common/android/testing/mkdtemp.h @@ -53,9 +53,9 @@ namespace { char* breakpad_mkdtemp(char* path) { - if (path == NULL) { + if (path == nullptr) { errno = EINVAL; - return NULL; + return nullptr; } // 'path' must be terminated with six 'X' @@ -66,23 +66,23 @@ char* breakpad_mkdtemp(char* path) { if (static_cast(path_end - path) < kSuffixLen || memcmp(path_end - kSuffixLen, kSuffix, kSuffixLen) != 0) { errno = EINVAL; - return NULL; + return nullptr; } // If 'path' contains a directory separator, check that it exists to // avoid looping later. char* sep = strrchr(path, '/'); - if (sep != NULL) { + if (sep != nullptr) { struct stat st; int ret; *sep = '\0'; // temporarily zero-terminate the dirname. ret = stat(path, &st); *sep = '/'; // restore full path. if (ret < 0) - return NULL; + return nullptr; if (!S_ISDIR(st.st_mode)) { errno = ENOTDIR; - return NULL; + return nullptr; } } @@ -97,11 +97,11 @@ char* breakpad_mkdtemp(char* path) { return path; // Success if (errno != EEXIST) - return NULL; + return nullptr; } assert(errno == EEXIST); - return NULL; + return nullptr; } } // namespace diff --git a/src/common/android/testing/pthread_fixes.h b/src/common/android/testing/pthread_fixes.h index 04bf63691..f9caee938 100644 --- a/src/common/android/testing/pthread_fixes.h +++ b/src/common/android/testing/pthread_fixes.h @@ -53,8 +53,8 @@ int pthread_barrier_init(pthread_barrier_t* barrier, const void* /* barrier_attr */, unsigned count) { barrier->count = count; - pthread_mutex_init(&barrier->mutex, NULL); - pthread_cond_init(&barrier->cond, NULL); + pthread_mutex_init(&barrier->mutex, nullptr); + pthread_cond_init(&barrier->cond, nullptr); return 0; } diff --git a/src/common/byte_cursor.h b/src/common/byte_cursor.h index fd0e45ffd..8033e9db1 100644 --- a/src/common/byte_cursor.h +++ b/src/common/byte_cursor.h @@ -218,7 +218,7 @@ class ByteCursor { *pointer = here_; here_ += size; } else { - *pointer = NULL; + *pointer = nullptr; } return *this; } diff --git a/src/common/byte_cursor_unittest.cc b/src/common/byte_cursor_unittest.cc index 41180ca2e..69b31d3f8 100644 --- a/src/common/byte_cursor_unittest.cc +++ b/src/common/byte_cursor_unittest.cc @@ -733,7 +733,7 @@ TEST(Strings, PointTo) { EXPECT_EQ(data + 0, received1); EXPECT_EQ(data + 3, received2); EXPECT_EQ(data + 6, received3); - EXPECT_EQ(NULL, received4); + EXPECT_EQ(nullptr, received4); } TEST(Strings, CString) { diff --git a/src/common/dwarf/bytereader.cc b/src/common/dwarf/bytereader.cc index faa7d680a..4c6f1d183 100644 --- a/src/common/dwarf/bytereader.cc +++ b/src/common/dwarf/bytereader.cc @@ -40,7 +40,7 @@ namespace google_breakpad { ByteReader::ByteReader(enum Endianness endian) - :offset_reader_(NULL), address_reader_(NULL), endian_(endian), + :offset_reader_(nullptr), address_reader_(nullptr), endian_(endian), address_size_(0), offset_size_(0), have_section_base_(), have_text_base_(), have_data_base_(), have_function_base_() { } diff --git a/src/common/dwarf/cfi_assembler.cc b/src/common/dwarf/cfi_assembler.cc index b3e064f06..773fd250f 100644 --- a/src/common/dwarf/cfi_assembler.cc +++ b/src/common/dwarf/cfi_assembler.cc @@ -119,7 +119,7 @@ CFISection& CFISection::FinishEntry() { Align(address_size_, DW_CFA_nop); entry_length_->length = Here() - entry_length_->start; delete entry_length_; - entry_length_ = NULL; + entry_length_ = nullptr; in_fde_ = false; return *this; } diff --git a/src/common/dwarf/cfi_assembler.h b/src/common/dwarf/cfi_assembler.h index a33d5d847..c707632d4 100644 --- a/src/common/dwarf/cfi_assembler.h +++ b/src/common/dwarf/cfi_assembler.h @@ -96,7 +96,7 @@ class CFISection: public Section { bool eh_frame = false) : Section(endianness), address_size_(address_size), eh_frame_(eh_frame), pointer_encoding_(DW_EH_PE_absptr), - encoded_pointer_bases_(), entry_length_(NULL), in_fde_(false) { + encoded_pointer_bases_(), entry_length_(nullptr), in_fde_(false) { // The 'start', 'Here', and 'Mark' members of a CFISection all refer // to section offsets. start() = 0; diff --git a/src/common/dwarf/dwarf2diehandler.cc b/src/common/dwarf/dwarf2diehandler.cc index 8aea0f2ff..1c95ad20c 100644 --- a/src/common/dwarf/dwarf2diehandler.cc +++ b/src/common/dwarf/dwarf2diehandler.cc @@ -64,7 +64,7 @@ bool DIEDispatcher::StartCompilationUnit(uint64_t offset, uint8_t address_size, bool DIEDispatcher::StartDIE(uint64_t offset, enum DwarfTag tag) { // The stack entry for the parent of this DIE, if there is one. - HandlerStack* parent = die_handlers_.empty() ? NULL : &die_handlers_.top(); + HandlerStack* parent = die_handlers_.empty() ? nullptr : &die_handlers_.top(); // Does this call indicate that we're done receiving the parent's // attributes' values? If so, call its EndAttributes member function. @@ -76,7 +76,7 @@ bool DIEDispatcher::StartDIE(uint64_t offset, enum DwarfTag tag) { parent->handler_->Finish(); if (parent->handler_ != root_handler_) delete parent->handler_; - parent->handler_ = NULL; + parent->handler_ = nullptr; return false; } } @@ -90,7 +90,7 @@ bool DIEDispatcher::StartDIE(uint64_t offset, enum DwarfTag tag) { else // No parent handler means we're not interested in any of our // children. - handler = NULL; + handler = nullptr; } else { // This is the root DIE. For a non-root DIE, the parent's handler // decides whether to visit it, but the root DIE has no parent @@ -99,7 +99,7 @@ bool DIEDispatcher::StartDIE(uint64_t offset, enum DwarfTag tag) { if (root_handler_->StartRootDIE(offset, tag)) handler = root_handler_; else - handler = NULL; + handler = nullptr; } // Push a handler stack entry for this new handler. As an @@ -114,7 +114,7 @@ bool DIEDispatcher::StartDIE(uint64_t offset, enum DwarfTag tag) { die_handlers_.push(entry); } - return handler != NULL; + return handler != nullptr; } void DIEDispatcher::EndDIE(uint64_t offset) { diff --git a/src/common/dwarf/dwarf2diehandler.h b/src/common/dwarf/dwarf2diehandler.h index 02c22853e..14be55acc 100644 --- a/src/common/dwarf/dwarf2diehandler.h +++ b/src/common/dwarf/dwarf2diehandler.h @@ -245,7 +245,7 @@ class DIEHandler { // // The default definition skips all children. virtual DIEHandler* FindChildHandler(uint64_t offset, enum DwarfTag tag) { - return NULL; + return nullptr; } // When we are done processing a DIE, we call this member function. diff --git a/src/common/dwarf/dwarf2diehandler_unittest.cc b/src/common/dwarf/dwarf2diehandler_unittest.cc index afcbf6254..a52f2ab72 100644 --- a/src/common/dwarf/dwarf2diehandler_unittest.cc +++ b/src/common/dwarf/dwarf2diehandler_unittest.cc @@ -343,7 +343,7 @@ TEST(Dwarf2DIEHandler, FindAndSkipChildren) { EXPECT_CALL(mock_root_handler, FindChildHandler(0x97412be24875de9dLL, (DwarfTag) 0x505a068b)) - .WillOnce(Return((DIEHandler*) NULL)); + .WillOnce(Return((DIEHandler*) nullptr)); // Third child DIE. EXPECT_CALL(mock_root_handler, diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc index 1c920fdc5..f9cf4535b 100644 --- a/src/common/dwarf/dwarf2reader.cc +++ b/src/common/dwarf/dwarf2reader.cc @@ -81,10 +81,10 @@ CompilationUnit::CompilationUnit(const string& path, ByteReader* reader, Dwarf2Handler* handler) : path_(path), offset_from_section_start_(offset), reader_(reader), sections_(sections), handler_(handler), abbrevs_(), - string_buffer_(NULL), string_buffer_length_(0), - line_string_buffer_(NULL), line_string_buffer_length_(0), - str_offsets_buffer_(NULL), str_offsets_buffer_length_(0), - addr_buffer_(NULL), addr_buffer_length_(0), + string_buffer_(nullptr), string_buffer_length_(0), + line_string_buffer_(nullptr), line_string_buffer_length_(0), + str_offsets_buffer_(nullptr), str_offsets_buffer_length_(0), + addr_buffer_(nullptr), addr_buffer_length_(0), is_split_dwarf_(false), is_type_unit_(false), dwo_id_(0), dwo_name_(), skeleton_dwo_id_(0), addr_base_(0), str_offsets_base_(0), have_checked_for_dwp_(false), @@ -479,7 +479,8 @@ uint64_t CompilationUnit::Start() { // and the client needs the full debug info, we need to find the full // compilation unit in a .dwo or .dwp file. should_process_split_dwarf_ = - !is_split_dwarf_ && dwo_name_ != NULL && handler_->NeedSplitDebugInfo(); + !is_split_dwarf_ && dwo_name_ != nullptr && + handler_->NeedSplitDebugInfo(); return ourlength; } @@ -799,7 +800,7 @@ const uint8_t* CompilationUnit::ProcessAttribute( return start + datalen + len; } case DW_FORM_strp: { - assert(string_buffer_ != NULL); + assert(string_buffer_ != nullptr); const uint64_t offset = reader_->ReadOffset(start); assert(string_buffer_ + offset < string_buffer_ + string_buffer_length_); @@ -809,7 +810,7 @@ const uint8_t* CompilationUnit::ProcessAttribute( return start + reader_->OffsetSize(); } case DW_FORM_line_strp: { - assert(line_string_buffer_ != NULL); + assert(line_string_buffer_ != nullptr); const uint64_t offset = reader_->ReadOffset(start); assert(line_string_buffer_ + offset < @@ -890,7 +891,7 @@ const uint8_t* CompilationUnit::ProcessAttribute( return start + len; } fprintf(stderr, "Unhandled form type\n"); - return NULL; + return nullptr; } const uint8_t* CompilationUnit::ProcessDIE(uint64_t dieoffset, @@ -926,7 +927,7 @@ const uint8_t* CompilationUnit::ProcessDIE(uint64_t dieoffset, if (abbrev.tag == DW_TAG_compile_unit && is_split_dwarf_ && dwo_id_ != skeleton_dwo_id_) { - return NULL; + return nullptr; } return start; @@ -1100,7 +1101,7 @@ void CompilationUnit::ReadDebugSectionsFromDwo(ElfReader* elf_reader, size_t section_size; const char* section_data = elf_reader->GetSectionByName(dwo_name, §ion_size); - if (section_data != NULL) + if (section_data != nullptr) sections->insert(std::make_pair( base_name, std::make_pair( reinterpret_cast(section_data), @@ -1110,17 +1111,17 @@ void CompilationUnit::ReadDebugSectionsFromDwo(ElfReader* elf_reader, DwpReader::DwpReader(const ByteReader& byte_reader, ElfReader* elf_reader) : elf_reader_(elf_reader), byte_reader_(byte_reader), - cu_index_(NULL), cu_index_size_(0), string_buffer_(NULL), + cu_index_(nullptr), cu_index_size_(0), string_buffer_(nullptr), string_buffer_size_(0), version_(0), ncolumns_(0), nunits_(0), - nslots_(0), phash_(NULL), pindex_(NULL), shndx_pool_(NULL), - offset_table_(NULL), size_table_(NULL), abbrev_data_(NULL), - abbrev_size_(0), info_data_(NULL), info_size_(0), - str_offsets_data_(NULL), str_offsets_size_(0) {} + nslots_(0), phash_(nullptr), pindex_(nullptr), shndx_pool_(nullptr), + offset_table_(nullptr), size_table_(nullptr), abbrev_data_(nullptr), + abbrev_size_(0), info_data_(nullptr), info_size_(0), + str_offsets_data_(nullptr), str_offsets_size_(0) {} void DwpReader::Initialize() { cu_index_ = elf_reader_->GetSectionByName(".debug_cu_index", &cu_index_size_); - if (cu_index_ == NULL) { + if (cu_index_ == nullptr) { return; } // The .debug_str.dwo section is shared by all CUs in the file. @@ -1336,7 +1337,7 @@ LineInfo::LineInfo(const uint8_t* buffer, uint64_t buffer_length, string_buffer_length_ = string_buffer_length; line_string_buffer_length_ = line_string_buffer_length; #endif - header_.std_opcode_lengths = NULL; + header_.std_opcode_lengths = nullptr; } uint64_t LineInfo::Start() { @@ -1830,7 +1831,7 @@ void LineInfo::ReadLines() { size_t oplength; bool add_row = ProcessOneOpcode(reader_, handler_, header_, lineptr, &lsm, &oplength, (uintptr)-1, - NULL); + nullptr); if (add_row) { if (have_pending_line) handler_->AddLine(pending_address, lsm.address - pending_address, @@ -2019,7 +2020,7 @@ class CallFrameInfo::UndefinedRule: public CallFrameInfo::Rule { // dynamic_cast is allowed by the Google C++ Style Guide, if the use has // been carefully considered; cheap RTTI-like workarounds are forbidden. const UndefinedRule* our_rhs = dynamic_cast(&rhs); - return (our_rhs != NULL); + return (our_rhs != nullptr); } Rule* Copy() const { return new UndefinedRule(*this); } }; @@ -2036,7 +2037,7 @@ class CallFrameInfo::SameValueRule: public CallFrameInfo::Rule { // dynamic_cast is allowed by the Google C++ Style Guide, if the use has // been carefully considered; cheap RTTI-like workarounds are forbidden. const SameValueRule* our_rhs = dynamic_cast(&rhs); - return (our_rhs != NULL); + return (our_rhs != nullptr); } Rule* Copy() const { return new SameValueRule(*this); } }; @@ -2160,8 +2161,8 @@ class CallFrameInfo::ValExpressionRule: public CallFrameInfo::Rule { // A map from register numbers to rules. class CallFrameInfo::RuleMap { public: - RuleMap() : cfa_rule_(NULL) { } - RuleMap(const RuleMap& rhs) : cfa_rule_(NULL) { *this = rhs; } + RuleMap() : cfa_rule_(nullptr) { } + RuleMap(const RuleMap& rhs) : cfa_rule_(nullptr) { *this = rhs; } ~RuleMap() { Clear(); } RuleMap& operator=(const RuleMap& rhs); @@ -2221,7 +2222,7 @@ CallFrameInfo::Rule* CallFrameInfo::RuleMap::RegisterRule(int reg) const { if (it != registers_.end()) return it->second->Copy(); else - return NULL; + return nullptr; } void CallFrameInfo::RuleMap::SetRegisterRule(int reg, Rule* rule) { @@ -2302,7 +2303,7 @@ bool CallFrameInfo::RuleMap::HandleTransitionTo( // Remove all register rules and clear cfa_rule_. void CallFrameInfo::RuleMap::Clear() { delete cfa_rule_; - cfa_rule_ = NULL; + cfa_rule_ = nullptr; for (RuleByNumber::iterator it = registers_.begin(); it != registers_.end(); it++) delete it->second; @@ -2318,7 +2319,7 @@ class CallFrameInfo::State { State(ByteReader* reader, Handler* handler, Reporter* reporter, uint64_t address) : reader_(reader), handler_(handler), reporter_(reporter), - address_(address), entry_(NULL), cursor_(NULL) { } + address_(address), entry_(nullptr), cursor_(nullptr) { } // Interpret instructions from CIE, save the resulting rule set for // DW_CFA_restore instructions, and return true. On error, report @@ -2892,7 +2893,7 @@ bool CallFrameInfo::ReadEntryPrologue(const uint8_t* cursor, Entry* entry) { entry->offset = cursor - buffer_; entry->start = cursor; entry->kind = kUnknown; - entry->end = NULL; + entry->end = nullptr; // Read the initial length. This sets reader_'s offset size. size_t length_size; @@ -2958,7 +2959,7 @@ bool CallFrameInfo::ReadEntryPrologue(const uint8_t* cursor, Entry* entry) { // The fields specific to this kind of entry start here. entry->fields = cursor; - entry->cie = NULL; + entry->cie = nullptr; return true; } diff --git a/src/common/dwarf/elf_reader.cc b/src/common/dwarf/elf_reader.cc index 31deb9db4..7669895b9 100644 --- a/src/common/dwarf/elf_reader.cc +++ b/src/common/dwarf/elf_reader.cc @@ -195,8 +195,8 @@ class ElfSectionReader { public: ElfSectionReader(const char* cname, const string& path, int fd, const typename ElfArch::Shdr& section_header) - : contents_aligned_(NULL), - contents_(NULL), + : contents_aligned_(nullptr), + contents_(nullptr), header_(section_header) { // Back up to the beginning of the page we're interested in. const size_t additional = header_.sh_offset % getpagesize(); @@ -218,7 +218,7 @@ class ElfSectionReader { return; } - contents_aligned_ = mmap(NULL, size_aligned_, PROT_READ, MAP_SHARED, + contents_aligned_ = mmap(nullptr, size_aligned_, PROT_READ, MAP_SHARED, fd, offset_aligned); // Set where the offset really should begin. contents_ = reinterpret_cast(contents_aligned_) + @@ -232,7 +232,7 @@ class ElfSectionReader { } ~ElfSectionReader() { - if (contents_aligned_ != NULL) + if (contents_aligned_ != nullptr) munmap(contents_aligned_, size_aligned_); else delete[] contents_; @@ -274,14 +274,14 @@ class SymbolIterator { SymbolIterator(ElfReaderImpl* reader, typename ElfArch::Word section_type) : symbol_section_(reader->GetSectionByType(section_type)), - string_section_(NULL), + string_section_(nullptr), num_symbols_in_section_(0), symbol_within_section_(0) { // If this section type doesn't exist, leave // num_symbols_in_section_ as zero, so this iterator is already // done(). - if (symbol_section_ != NULL) { + if (symbol_section_ != nullptr) { num_symbols_in_section_ = symbol_section_->header().sh_size / symbol_section_->header().sh_entsize; @@ -313,7 +313,7 @@ class SymbolIterator { const char* GetSymbolName() const { int name_offset = GetSymbol()->st_name; if (name_offset == 0) - return NULL; + return nullptr; return string_section_->GetOffset(name_offset); } @@ -351,9 +351,9 @@ class ElfReaderImpl { explicit ElfReaderImpl(const string& path, int fd) : path_(path), fd_(fd), - section_headers_(NULL), - program_headers_(NULL), - opd_section_(NULL), + section_headers_(nullptr), + program_headers_(nullptr), + opd_section_(nullptr), base_for_text_(0), plts_supported_(false), plt_code_size_(0), @@ -409,17 +409,17 @@ class ElfReaderImpl { static bool IsArchElfFile(int fd, string* error) { unsigned char header[EI_NIDENT]; if (pread(fd, header, sizeof(header), 0) != sizeof(header)) { - if (error != NULL) *error = "Could not read header"; + if (error != nullptr) *error = "Could not read header"; return false; } if (memcmp(header, ELFMAG, SELFMAG) != 0) { - if (error != NULL) *error = "Missing ELF magic"; + if (error != nullptr) *error = "Missing ELF magic"; return false; } if (header[EI_CLASS] != ElfArch::kElfClass) { - if (error != NULL) *error = "Different word size"; + if (error != nullptr) *error = "Different word size"; return false; } @@ -429,7 +429,7 @@ class ElfReaderImpl { else if (header[EI_DATA] == ELFDATA2MSB) endian = __BIG_ENDIAN; if (endian != __BYTE_ORDER) { - if (error != NULL) *error = "Different byte order"; + if (error != nullptr) *error = "Different byte order"; return false; } @@ -476,7 +476,7 @@ class ElfReaderImpl { for (SymbolIterator it(this, section_type); !it.done(); it.Next()) { const char* name = it.GetSymbolName(); - if (name == NULL) + if (name == nullptr) continue; const typename ElfArch::Sym* sym = it.GetSymbol(); if (CanUseSymbol(name, sym)) { @@ -720,7 +720,7 @@ class ElfReaderImpl { return GetSection(k); } } - return NULL; + return nullptr; } // Return the name of section "shndx". Returns NULL if the section @@ -733,11 +733,11 @@ class ElfReaderImpl { // "size". Returns NULL if the section is not found. const char* GetSectionContentsByIndex(int shndx, size_t* size) { const ElfSectionReader* section = GetSection(shndx); - if (section != NULL) { + if (section != nullptr) { *size = section->section_size(); return section->contents(); } - return NULL; + return nullptr; } // Return a pointer to the first section of the given name by @@ -751,17 +751,17 @@ class ElfReaderImpl { // table, so reverse the direction of iteration. int shndx = is_dwp_ ? GetNumSections() - k - 1 : k; const char* name = GetSectionName(section_headers_[shndx].sh_name); - if (name != NULL && ElfReader::SectionNamesMatch(section_name, name)) { + if (name != nullptr && ElfReader::SectionNamesMatch(section_name, name)) { const ElfSectionReader* section = GetSection(shndx); - if (section == NULL) { - return NULL; + if (section == nullptr) { + return nullptr; } else { *size = section->section_size(); return section->contents(); } } } - return NULL; + return nullptr; } // This is like GetSectionContentsByName() but it returns a lot of extra @@ -774,10 +774,10 @@ class ElfReaderImpl { // table, so reverse the direction of iteration. int shndx = is_dwp_ ? GetNumSections() - k - 1 : k; const char* name = GetSectionName(section_headers_[shndx].sh_name); - if (name != NULL && ElfReader::SectionNamesMatch(section_name, name)) { + if (name != nullptr && ElfReader::SectionNamesMatch(section_name, name)) { const ElfSectionReader* section = GetSection(shndx); - if (section == NULL) { - return NULL; + if (section == nullptr) { + return nullptr; } else { info->type = section->header().sh_type; info->flags = section->header().sh_flags; @@ -792,7 +792,7 @@ class ElfReaderImpl { } } } - return NULL; + return nullptr; } // p_vaddr of the first PT_LOAD segment (if any), or 0 if no PT_LOAD @@ -881,10 +881,10 @@ class ElfReaderImpl { const char* GetSectionName(typename ElfArch::Word sh_name) { const ElfSectionReader* shstrtab = GetSection(GetStringTableIndex()); - if (shstrtab != NULL) { + if (shstrtab != nullptr) { return shstrtab->GetOffset(sh_name); } - return NULL; + return nullptr; } // Return an ElfSectionReader for the given section. The reader will @@ -898,7 +898,7 @@ class ElfReaderImpl { else name = GetSectionNameByIndex(num); ElfSectionReader*& reader = sections_[num]; - if (reader == NULL) + if (reader == nullptr) reader = new ElfSectionReader(name, path_, fd_, section_headers_[num]); return reader->contents() ? reader : nullptr; @@ -953,14 +953,14 @@ class ElfReaderImpl { program_headers_ = new typename ElfArch::Phdr[GetNumProgramHeaders()]; // Presize the sections array for efficiency. - sections_.resize(GetNumSections(), NULL); + sections_.resize(GetNumSections(), nullptr); return true; } // Given the "value" of a function descriptor return the address of the // function (i.e. the dereferenced value). Otherwise return "value". uint64_t AdjustPPC64FunctionDescriptorSymbolValue(uint64_t value) { - if (opd_section_ != NULL && + if (opd_section_ != nullptr && opd_info_.addr <= value && value < opd_info_.addr + opd_info_.size) { uint64_t offset = value - opd_info_.addr; @@ -1051,7 +1051,7 @@ class ElfReaderImpl { }; ElfReader::ElfReader(const string& path) - : path_(path), fd_(-1), impl32_(NULL), impl64_(NULL) { + : path_(path), fd_(-1), impl32_(nullptr), impl64_(nullptr) { // linux 2.6.XX kernel can show deleted files like this: // /var/run/nscd/dbYLJYaE (deleted) // and the kernel-supplied vdso and vsyscall mappings like this: @@ -1070,9 +1070,9 @@ ElfReader::ElfReader(const string& path) ElfReader::~ElfReader() { if (fd_ != -1) close(fd_); - if (impl32_ != NULL) + if (impl32_ != nullptr) delete impl32_; - if (impl64_ != NULL) + if (impl64_ != nullptr) delete impl64_; } @@ -1090,7 +1090,7 @@ template static bool IsElfFile(const int fd, const string& path) { if (fd < 0) return false; - if (!ElfReaderImpl::IsArchElfFile(fd, NULL)) { + if (!ElfReaderImpl::IsArchElfFile(fd, nullptr)) { // No error message here. IsElfFile gets called many times. return false; } @@ -1173,13 +1173,14 @@ uint64_t ElfReader::VaddrOfFirstLoadSegment() { } const char* ElfReader::GetSectionName(int shndx) { - if (shndx < 0 || static_cast(shndx) >= GetNumSections()) return NULL; + if (shndx < 0 || static_cast(shndx) >= GetNumSections()) + return nullptr; if (IsElf32File()) { return GetImpl32()->GetSectionNameByIndex(shndx); } else if (IsElf64File()) { return GetImpl64()->GetSectionNameByIndex(shndx); } else { - return NULL; + return nullptr; } } @@ -1199,7 +1200,7 @@ const char* ElfReader::GetSectionByIndex(int shndx, size_t* size) { } else if (IsElf64File()) { return GetImpl64()->GetSectionContentsByIndex(shndx, size); } else { - return NULL; + return nullptr; } } @@ -1210,7 +1211,7 @@ const char* ElfReader::GetSectionByName(const string& section_name, } else if (IsElf64File()) { return GetImpl64()->GetSectionContentsByName(section_name, size); } else { - return NULL; + return nullptr; } } @@ -1221,7 +1222,7 @@ const char* ElfReader::GetSectionInfoByName(const string& section_name, } else if (IsElf64File()) { return GetImpl64()->GetSectionInfoByName(section_name, info); } else { - return NULL; + return nullptr; } } @@ -1249,14 +1250,14 @@ bool ElfReader::IsDynamicSharedObject() { } ElfReaderImpl* ElfReader::GetImpl32() { - if (impl32_ == NULL) { + if (impl32_ == nullptr) { impl32_ = new ElfReaderImpl(path_, fd_); } return impl32_; } ElfReaderImpl* ElfReader::GetImpl64() { - if (impl64_ == NULL) { + if (impl64_ == nullptr) { impl64_ = new ElfReaderImpl(path_, fd_); } return impl64_; @@ -1268,11 +1269,11 @@ ElfReaderImpl* ElfReader::GetImpl64() { template static bool IsNonStrippedELFBinaryImpl(const string& path, const int fd, bool debug_only) { - if (!ElfReaderImpl::IsArchElfFile(fd, NULL)) return false; + if (!ElfReaderImpl::IsArchElfFile(fd, nullptr)) return false; ElfReaderImpl elf_reader(path, fd); return debug_only ? elf_reader.HasDebugSections() - : (elf_reader.GetSectionByType(SHT_SYMTAB) != NULL); + : (elf_reader.GetSectionByType(SHT_SYMTAB) != nullptr); } // Helper for the IsNon[Debug]StrippedELFBinary functions. diff --git a/src/common/dwarf/functioninfo.h b/src/common/dwarf/functioninfo.h index 1387c5ba4..4139564cf 100644 --- a/src/common/dwarf/functioninfo.h +++ b/src/common/dwarf/functioninfo.h @@ -124,7 +124,7 @@ class CUFunctionInfoHandler: public Dwarf2Handler { offset_to_funcinfo_(offset_to_funcinfo), address_to_funcinfo_(address_to_funcinfo), linehandler_(linehandler), sections_(sections), - reader_(reader), current_function_info_(NULL) { } + reader_(reader), current_function_info_(nullptr) { } virtual ~CUFunctionInfoHandler() { } diff --git a/src/common/dwarf_cu_to_module.cc b/src/common/dwarf_cu_to_module.cc index edd3a99bf..c58181d71 100644 --- a/src/common/dwarf_cu_to_module.cc +++ b/src/common/dwarf_cu_to_module.cc @@ -302,9 +302,9 @@ class DwarfCUToModule::GenericDIEHandler: public DIEHandler { parent_context_(parent_context), offset_(offset), declaration_(false), - specification_(NULL), + specification_(nullptr), no_specification(false), - abstract_origin_(NULL), + abstract_origin_(nullptr), forward_ref_die_offset_(0), specification_offset_(0) { } // Derived classes' ProcessAttributeUnsigned can defer to this to @@ -672,7 +672,7 @@ DIEHandler* DwarfCUToModule::InlineHandler::FindChildHandler( return new LexicalBlockHandler(cu_context_, offset, inline_nest_level_ + 1, child_inlines_); default: - return NULL; + return nullptr; } } @@ -884,7 +884,7 @@ DIEHandler* DwarfCUToModule::FuncHandler::FindChildHandler( if (handle_inline_) return new LexicalBlockHandler(cu_context_, offset, 0, child_inlines_); default: - return NULL; + return nullptr; } } @@ -1001,7 +1001,7 @@ void DwarfCUToModule::FuncHandler::Finish() { } bool DwarfCUToModule::NamedScopeHandler::EndAttributes() { - child_context_.name = ComputeQualifiedName(NULL); + child_context_.name = ComputeQualifiedName(nullptr); if (child_context_.name.empty() && no_specification) { cu_context_->reporter->UnknownSpecification(offset_, specification_offset_); } @@ -1022,7 +1022,7 @@ DIEHandler* DwarfCUToModule::NamedScopeHandler::FindChildHandler( return new NamedScopeHandler(cu_context_, &child_context_, offset, handle_inline_); default: - return NULL; + return nullptr; } } @@ -1232,7 +1232,7 @@ DIEHandler* DwarfCUToModule::FindChildHandler( return new NamedScopeHandler(cu_context_.get(), child_context_.get(), offset, handle_inline); default: - return NULL; + return nullptr; } } @@ -1394,12 +1394,12 @@ void DwarfCUToModule::AssignLinesToFunctions() { // The last line that we used any piece of. We use this only for // generating warnings. - const Module::Line* last_line_used = NULL; + const Module::Line* last_line_used = nullptr; // The last function and line we warned about --- so we can avoid // doing so more than once. - const Module::Function* last_function_cited = NULL; - const Module::Line* last_line_cited = NULL; + const Module::Function* last_function_cited = nullptr; + const Module::Line* last_line_cited = nullptr; // Prepare a sorted list of ranges with range-to-function mapping vector sorted_ranges; @@ -1425,12 +1425,12 @@ void DwarfCUToModule::AssignLinesToFunctions() { line = &*line_it; current = std::min(range->address, line->address); } else if (line_it != lines_.end()) { - range = NULL; + range = nullptr; line = &*line_it; current = line->address; } else if (range_it != sorted_ranges.end()) { range = &*range_it; - line = NULL; + line = nullptr; current = range->address; } else { return; @@ -1561,12 +1561,12 @@ void DwarfCUToModule::AssignLinesToFunctions() { && next_transition >= range_it->address && !within(*range_it, next_transition)) range_it++; - range = (range_it != sorted_ranges.end()) ? &(*range_it) : NULL; + range = (range_it != sorted_ranges.end()) ? &(*range_it) : nullptr; while (line_it != lines_.end() && next_transition >= line_it->address && !within(*line_it, next_transition)) line_it++; - line = (line_it != lines_.end()) ? &*line_it : NULL; + line = (line_it != lines_.end()) ? &*line_it : nullptr; // We must make progress. assert(next_transition > current); diff --git a/src/common/dwarf_cu_to_module_unittest.cc b/src/common/dwarf_cu_to_module_unittest.cc index 134b2c243..d073c87a0 100644 --- a/src/common/dwarf_cu_to_module_unittest.cc +++ b/src/common/dwarf_cu_to_module_unittest.cc @@ -209,7 +209,8 @@ class CUFixtureBase { // not Finish. If NAME is non-zero, use it as the DW_AT_name // attribute. DIEHandler* StartSpecifiedDIE(DIEHandler* parent, DwarfTag tag, - uint64_t specification, const char* name = NULL); + uint64_t specification, + const char* name = nullptr); // Define a function as a child of PARENT with the given name, address, and // size. If high_pc_form is DW_FORM_addr then the DW_AT_high_pc attribute @@ -410,7 +411,7 @@ DIEHandler* CUFixtureBase::StartNamedDIE(DIEHandler* parent, google_breakpad::DIEHandler* handler = parent->FindChildHandler(0x8f4c783c0467c989ULL, tag); if (!handler) - return NULL; + return nullptr; handler->ProcessAttributeString(google_breakpad::DW_AT_name, google_breakpad::DW_FORM_strp, name); @@ -418,7 +419,7 @@ DIEHandler* CUFixtureBase::StartNamedDIE(DIEHandler* parent, if (!handler->EndAttributes()) { handler->Finish(); delete handler; - return NULL; + return nullptr; } return handler; @@ -431,7 +432,7 @@ DIEHandler* CUFixtureBase::StartSpecifiedDIE(DIEHandler* parent, google_breakpad::DIEHandler* handler = parent->FindChildHandler(0x8f4c783c0467c989ULL, tag); if (!handler) - return NULL; + return nullptr; if (name) handler->ProcessAttributeString(google_breakpad::DW_AT_name, google_breakpad::DW_FORM_strp, @@ -442,7 +443,7 @@ DIEHandler* CUFixtureBase::StartSpecifiedDIE(DIEHandler* parent, if (!handler->EndAttributes()) { handler->Finish(); delete handler; - return NULL; + return nullptr; } return handler; @@ -456,7 +457,7 @@ void CUFixtureBase::DefineFunction(google_breakpad::DIEHandler* parent, google_breakpad::DIEHandler* func = parent->FindChildHandler(0xe34797c7e68590a8LL, google_breakpad::DW_TAG_subprogram); - ASSERT_TRUE(func != NULL); + ASSERT_TRUE(func != nullptr); func->ProcessAttributeString(google_breakpad::DW_AT_name, google_breakpad::DW_FORM_strp, name); @@ -488,7 +489,7 @@ void CUFixtureBase::DeclarationDIE(DIEHandler* parent, uint64_t offset, const string& name, const string& mangled_name) { google_breakpad::DIEHandler* die = parent->FindChildHandler(offset, tag); - ASSERT_TRUE(die != NULL); + ASSERT_TRUE(die != nullptr); if (!name.empty()) die->ProcessAttributeString(google_breakpad::DW_AT_name, google_breakpad::DW_FORM_strp, @@ -514,7 +515,7 @@ void CUFixtureBase::DefinitionDIE(DIEHandler* parent, Module::Address size) { google_breakpad::DIEHandler* die = parent->FindChildHandler(0x6ccfea031a9e6cc9ULL, tag); - ASSERT_TRUE(die != NULL); + ASSERT_TRUE(die != nullptr); die->ProcessAttributeReference(google_breakpad::DW_AT_specification, google_breakpad::DW_FORM_ref4, specification); @@ -543,7 +544,7 @@ void CUFixtureBase::AbstractInstanceDIE(DIEHandler* parent, DwarfForm form) { google_breakpad::DIEHandler* die = parent->FindChildHandler(offset, google_breakpad::DW_TAG_subprogram); - ASSERT_TRUE(die != NULL); + ASSERT_TRUE(die != nullptr); if (specification != 0ULL) die->ProcessAttributeReference(google_breakpad::DW_AT_specification, google_breakpad::DW_FORM_ref4, @@ -571,7 +572,7 @@ void CUFixtureBase::DefineInlineInstanceDIE(DIEHandler* parent, google_breakpad::DIEHandler* func = parent->FindChildHandler(0x11c70f94c6e87ccdLL, google_breakpad::DW_TAG_subprogram); - ASSERT_TRUE(func != NULL); + ASSERT_TRUE(func != nullptr); if (!name.empty()) { func->ProcessAttributeString(google_breakpad::DW_AT_name, google_breakpad::DW_FORM_strp, @@ -681,7 +682,7 @@ TEST_F(SimpleCU, OneFunc) { StartCU(); DefineFunction(&root_handler_, "function1", - 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, NULL); + 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, nullptr); root_handler_.Finish(); TestFunctionCount(1); @@ -697,7 +698,7 @@ TEST_F(SimpleCU, OneFuncHighPcIsLength) { StartCU(); DefineFunction6(&root_handler_, "function1", - 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, NULL, + 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, nullptr, google_breakpad::DW_FORM_udata); root_handler_.Finish(); @@ -731,7 +732,7 @@ TEST_F(SimpleCU, IrrelevantNamedScopeChildren) { StartCU(); DIEHandler* class_A_handler = StartNamedDIE(&root_handler_, google_breakpad::DW_TAG_class_type, "class_A"); - EXPECT_TRUE(class_A_handler != NULL); + EXPECT_TRUE(class_A_handler != nullptr); EXPECT_FALSE(class_A_handler ->FindChildHandler(0x02e55999b865e4e9ULL, google_breakpad::DW_TAG_lexical_block)); @@ -816,7 +817,7 @@ TEST_F(SimpleCU, UnnamedFunction) { StartCU(); DefineFunction(&root_handler_, "", - 0x72b80e41a0ac1d40ULL, 0x537174f231ee181cULL, NULL); + 0x72b80e41a0ac1d40ULL, 0x537174f231ee181cULL, nullptr); root_handler_.Finish(); TestFunctionCount(1); @@ -893,10 +894,10 @@ TEST_P(FuncLinePairing, Pairing) { StartCU(); DefineFunction(&root_handler_, "function1", s.functions[0].start, - s.functions[0].end - s.functions[0].start, NULL); + s.functions[0].end - s.functions[0].start, nullptr); DefineFunction(&root_handler_, "function2", s.functions[1].start, - s.functions[1].end - s.functions[1].start, NULL); + s.functions[1].end - s.functions[1].start, nullptr); root_handler_.Finish(); TestFunctionCount(2); @@ -940,7 +941,7 @@ TEST_F(FuncLinePairing, FuncsNoLines) { StartCU(); DefineFunction(&root_handler_, "function1", 0x127da12ffcf5c51fULL, 0x1000U, - NULL); + nullptr); root_handler_.Finish(); TestFunctionCount(1); @@ -952,8 +953,8 @@ TEST_F(FuncLinePairing, GapThenFunction) { PushLine(10, 2, "line-file-1", 263008005); StartCU(); - DefineFunction(&root_handler_, "function1", 10, 2, NULL); - DefineFunction(&root_handler_, "function2", 20, 2, NULL); + DefineFunction(&root_handler_, "function1", 10, 2, nullptr); + DefineFunction(&root_handler_, "function2", 20, 2, nullptr); root_handler_.Finish(); TestFunctionCount(2); @@ -978,10 +979,10 @@ TEST_F(FuncLinePairing, GCCAlignmentStretch) { PushLine(20, 10, "line-file", 61661044); StartCU(); - DefineFunction(&root_handler_, "function1", 10, 5, NULL); + DefineFunction(&root_handler_, "function1", 10, 5, nullptr); // five-byte gap between functions, covered by line 63351048. // This should not elicit a warning. - DefineFunction(&root_handler_, "function2", 20, 10, NULL); + DefineFunction(&root_handler_, "function2", 20, 10, nullptr); root_handler_.Finish(); TestFunctionCount(2); @@ -1002,8 +1003,10 @@ TEST_F(FuncLinePairing, LineAtEndOfAddressSpace) { EXPECT_CALL(reporter_, UncoveredLine(_)).WillOnce(Return()); StartCU(); - DefineFunction(&root_handler_, "function1", 0xfffffffffffffff0ULL, 6, NULL); - DefineFunction(&root_handler_, "function2", 0xfffffffffffffffaULL, 5, NULL); + DefineFunction(&root_handler_, "function1", 0xfffffffffffffff0ULL, 6, + nullptr); + DefineFunction(&root_handler_, "function2", 0xfffffffffffffffaULL, 5, + nullptr); root_handler_.Finish(); TestFunctionCount(2); @@ -1023,7 +1026,7 @@ TEST_F(FuncLinePairing, WarnOnceFunc) { EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return()); StartCU(); - DefineFunction(&root_handler_, "function", 10, 11, NULL); + DefineFunction(&root_handler_, "function", 10, 11, nullptr); root_handler_.Finish(); TestFunctionCount(1); @@ -1040,8 +1043,8 @@ TEST_F(FuncLinePairing, WarnOnceLine) { EXPECT_CALL(reporter_, UncoveredLine(_)).WillOnce(Return()); StartCU(); - DefineFunction(&root_handler_, "function1", 11, 1, NULL); - DefineFunction(&root_handler_, "function2", 13, 1, NULL); + DefineFunction(&root_handler_, "function1", 11, 1, nullptr); + DefineFunction(&root_handler_, "function2", 13, 1, nullptr); root_handler_.Finish(); TestFunctionCount(2); @@ -1072,9 +1075,9 @@ TEST_P(CXXQualifiedNames, TwoFunctions) { StartCU(); DIEHandler* enclosure_handler = StartNamedDIE(&root_handler_, tag, "Enclosure"); - EXPECT_TRUE(enclosure_handler != NULL); - DefineFunction(enclosure_handler, "func_B", 10, 1, NULL); - DefineFunction(enclosure_handler, "func_C", 20, 1, NULL); + EXPECT_TRUE(enclosure_handler != nullptr); + DefineFunction(enclosure_handler, "func_B", 10, 1, nullptr); + DefineFunction(enclosure_handler, "func_C", 20, 1, nullptr); enclosure_handler->Finish(); delete enclosure_handler; root_handler_.Finish(); @@ -1094,11 +1097,11 @@ TEST_P(CXXQualifiedNames, FuncInEnclosureInNamespace) { DIEHandler* namespace_handler = StartNamedDIE(&root_handler_, google_breakpad::DW_TAG_namespace, "Namespace"); - EXPECT_TRUE(namespace_handler != NULL); + EXPECT_TRUE(namespace_handler != nullptr); DIEHandler* enclosure_handler = StartNamedDIE(namespace_handler, tag, "Enclosure"); - EXPECT_TRUE(enclosure_handler != NULL); - DefineFunction(enclosure_handler, "function", 10, 1, NULL); + EXPECT_TRUE(enclosure_handler != nullptr); + DefineFunction(enclosure_handler, "function", 10, 1, nullptr); enclosure_handler->Finish(); delete enclosure_handler; namespace_handler->Finish(); @@ -1117,15 +1120,15 @@ TEST_F(CXXQualifiedNames, FunctionInClassInStructInNamespace) { DIEHandler* namespace_handler = StartNamedDIE(&root_handler_, google_breakpad::DW_TAG_namespace, "namespace_A"); - EXPECT_TRUE(namespace_handler != NULL); + EXPECT_TRUE(namespace_handler != nullptr); DIEHandler* struct_handler = StartNamedDIE(namespace_handler, google_breakpad::DW_TAG_structure_type, "struct_B"); - EXPECT_TRUE(struct_handler != NULL); + EXPECT_TRUE(struct_handler != nullptr); DIEHandler* class_handler = StartNamedDIE(struct_handler, google_breakpad::DW_TAG_class_type, "class_C"); - DefineFunction(class_handler, "function_D", 10, 1, NULL); + DefineFunction(class_handler, "function_D", 10, 1, nullptr); class_handler->Finish(); delete class_handler; struct_handler->Finish(); @@ -1151,7 +1154,7 @@ const LanguageAndQualifiedName LanguageAndQualifiedNameCases[] = { { google_breakpad::DW_LANG_C_plus_plus, "class_A::function_B" }, { google_breakpad::DW_LANG_Java, "class_A.function_B" }, { google_breakpad::DW_LANG_Cobol74, "class_A::function_B" }, - { google_breakpad::DW_LANG_Mips_Assembler, NULL } + { google_breakpad::DW_LANG_Mips_Assembler, nullptr } }; class QualifiedForLanguage @@ -1171,7 +1174,7 @@ TEST_P(QualifiedForLanguage, MemberFunction) { DIEHandler* class_handler = StartNamedDIE(&root_handler_, google_breakpad::DW_TAG_class_type, "class_A"); - DefineFunction(class_handler, "function_B", 10, 1, NULL); + DefineFunction(class_handler, "function_B", 10, 1, nullptr); class_handler->Finish(); delete class_handler; root_handler_.Finish(); @@ -1195,7 +1198,7 @@ TEST_P(QualifiedForLanguage, MemberFunctionSignedLanguage) { DIEHandler* class_handler = StartNamedDIE(&root_handler_, google_breakpad::DW_TAG_class_type, "class_A"); - DefineFunction(class_handler, "function_B", 10, 1, NULL); + DefineFunction(class_handler, "function_B", 10, 1, nullptr); class_handler->Finish(); delete class_handler; root_handler_.Finish(); @@ -1321,7 +1324,7 @@ TEST_F(Specifications, FunctionDeclarationParent) { DIEHandler* class_handler = StartNamedDIE(&root_handler_, google_breakpad::DW_TAG_class_type, "class_A"); - ASSERT_TRUE(class_handler != NULL); + ASSERT_TRUE(class_handler != nullptr); DeclarationDIE(class_handler, 0x0e0e877c8404544aULL, google_breakpad::DW_TAG_subprogram, "declaration-name", ""); class_handler->Finish(); @@ -1349,7 +1352,7 @@ TEST_F(Specifications, NamedScopeDeclarationParent) { DIEHandler* space_handler = StartNamedDIE(&root_handler_, google_breakpad::DW_TAG_namespace, "space_A"); - ASSERT_TRUE(space_handler != NULL); + ASSERT_TRUE(space_handler != nullptr); DeclarationDIE(space_handler, 0x419bb1d12f9a73a2ULL, google_breakpad::DW_TAG_class_type, "class-declaration-name", ""); @@ -1361,9 +1364,9 @@ TEST_F(Specifications, NamedScopeDeclarationParent) { DIEHandler* class_handler = StartSpecifiedDIE(&root_handler_, google_breakpad::DW_TAG_class_type, 0x419bb1d12f9a73a2ULL, "class-definition-name"); - ASSERT_TRUE(class_handler != NULL); + ASSERT_TRUE(class_handler != nullptr); DefineFunction(class_handler, "function", - 0x5d13433d0df13d00ULL, 0x48ebebe5ade2cab4ULL, NULL); + 0x5d13433d0df13d00ULL, 0x48ebebe5ade2cab4ULL, nullptr); class_handler->Finish(); delete class_handler; } @@ -1402,7 +1405,7 @@ TEST_F(Specifications, InlineFunctionInNamespace) { DIEHandler* space_handler = StartNamedDIE(&root_handler_, google_breakpad::DW_TAG_namespace, "Namespace"); - ASSERT_TRUE(space_handler != NULL); + ASSERT_TRUE(space_handler != nullptr); AbstractInstanceDIE(space_handler, 0x1e8dac5d507ed7abULL, google_breakpad::DW_INL_inlined, 0LL, "func-name"); DefineInlineInstanceDIE(space_handler, "", 0x1e8dac5d507ed7abULL, diff --git a/src/common/language.cc b/src/common/language.cc index 61693a8cd..a1d17adec 100644 --- a/src/common/language.cc +++ b/src/common/language.cc @@ -92,7 +92,7 @@ class CPPLanguage: public Language { int status; char* demangled_c = - abi::__cxa_demangle(mangled.c_str(), NULL, NULL, &status); + abi::__cxa_demangle(mangled.c_str(), nullptr, nullptr, &status); DemangleResult result; if (status == 0) { diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index 1b7d13138..f0680a959 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -150,7 +150,7 @@ class MmapWrapper { public: MmapWrapper() : is_set_(false) {} ~MmapWrapper() { - if (is_set_ && base_ != NULL) { + if (is_set_ && base_ != nullptr) { assert(size_ > 0); munmap(base_, size_); } @@ -163,7 +163,7 @@ class MmapWrapper { void release() { assert(is_set_); is_set_ = false; - base_ = NULL; + base_ = nullptr; size_ = 0; } @@ -644,7 +644,7 @@ bool LoadELF(const string& obj_file, MmapWrapper* map_wrapper, obj_file.c_str(), strerror(errno)); return false; } - void* obj_base = mmap(NULL, st.st_size, + void* obj_base = mmap(nullptr, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, obj_fd, 0); if (obj_base == MAP_FAILED) { fprintf(stderr, "Failed to mmap ELF file '%s': %s\n", @@ -1119,7 +1119,7 @@ const char* ElfArchitecture(const typename ElfClass::Ehdr* elf_header) { case EM_X86_64: return "x86_64"; case EM_RISCV: return "riscv"; case EM_NDS32: return "nds32"; - default: return NULL; + default: return nullptr; } } @@ -1209,7 +1209,7 @@ bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, Module** out_module) { typedef typename ElfClass::Ehdr Ehdr; - *out_module = NULL; + *out_module = nullptr; std::unique_ptr module; if (!InitModuleForElfClass(elf_header, obj_filename, obj_os, module_id, @@ -1233,7 +1233,7 @@ bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, // Load debuglink ELF file. fprintf(stderr, "Found debugging info in %s\n", debuglink_file.c_str()); MmapWrapper debug_map_wrapper; - Ehdr* debug_elf_header = NULL; + Ehdr* debug_elf_header = nullptr; if (!LoadELF(debuglink_file, &debug_map_wrapper, reinterpret_cast(&debug_elf_header)) || !SanitizeDebugFile(debug_elf_header, debuglink_file, @@ -1312,7 +1312,7 @@ bool WriteSymbolFileHeader(const string& load_path, const string& module_id, std::ostream& sym_stream) { MmapWrapper map_wrapper; - void* elf_header = NULL; + void* elf_header = nullptr; if (!LoadELF(load_path, &map_wrapper, &elf_header)) { fprintf(stderr, "Could not load ELF file: %s\n", obj_file.c_str()); return false; @@ -1355,7 +1355,7 @@ bool ReadSymbolData(const string& load_path, const DumpOptions& options, Module** module) { MmapWrapper map_wrapper; - void* elf_header = NULL; + void* elf_header = nullptr; if (!LoadELF(load_path, &map_wrapper, &elf_header)) return false; diff --git a/src/common/linux/elf_core_dump.cc b/src/common/linux/elf_core_dump.cc index 67257fd27..2df53bda7 100644 --- a/src/common/linux/elf_core_dump.cc +++ b/src/common/linux/elf_core_dump.cc @@ -48,7 +48,7 @@ ElfCoreDump::Note::Note() {} ElfCoreDump::Note::Note(const MemoryRange& content) : content_(content) {} bool ElfCoreDump::Note::IsValid() const { - return GetHeader() != NULL; + return GetHeader() != nullptr; } const ElfCoreDump::Nhdr* ElfCoreDump::Note::GetHeader() const { @@ -144,7 +144,7 @@ const ElfCoreDump::Phdr* ElfCoreDump::GetProgramHeader(unsigned index) const { return reinterpret_cast(content_.GetArrayElement( header->e_phoff, header->e_phentsize, index)); } - return NULL; + return nullptr; } const ElfCoreDump::Phdr* ElfCoreDump::GetFirstProgramHeaderOfType( @@ -155,7 +155,7 @@ const ElfCoreDump::Phdr* ElfCoreDump::GetFirstProgramHeaderOfType( return program; } } - return NULL; + return nullptr; } unsigned ElfCoreDump::GetProgramHeaderCount() const { diff --git a/src/common/linux/elf_core_dump_unittest.cc b/src/common/linux/elf_core_dump_unittest.cc index 25cab99f8..633b60dbd 100644 --- a/src/common/linux/elf_core_dump_unittest.cc +++ b/src/common/linux/elf_core_dump_unittest.cc @@ -55,10 +55,10 @@ using std::set; TEST(ElfCoreDumpTest, DefaultConstructor) { ElfCoreDump core; EXPECT_FALSE(core.IsValid()); - EXPECT_EQ(NULL, core.GetHeader()); + EXPECT_EQ(nullptr, core.GetHeader()); EXPECT_EQ(0U, core.GetProgramHeaderCount()); - EXPECT_EQ(NULL, core.GetProgramHeader(0)); - EXPECT_EQ(NULL, core.GetFirstProgramHeaderOfType(PT_LOAD)); + EXPECT_EQ(nullptr, core.GetProgramHeader(0)); + EXPECT_EQ(nullptr, core.GetFirstProgramHeaderOfType(PT_LOAD)); EXPECT_FALSE(core.GetFirstNote().IsValid()); } @@ -76,10 +76,10 @@ TEST(ElfCoreDumpTest, TestElfHeader) { ASSERT_TRUE(mapped_core_file.Map(core_file, 0)); core.SetContent(mapped_core_file.content()); EXPECT_FALSE(core.IsValid()); - EXPECT_EQ(NULL, core.GetHeader()); + EXPECT_EQ(nullptr, core.GetHeader()); EXPECT_EQ(0U, core.GetProgramHeaderCount()); - EXPECT_EQ(NULL, core.GetProgramHeader(0)); - EXPECT_EQ(NULL, core.GetFirstProgramHeaderOfType(PT_LOAD)); + EXPECT_EQ(nullptr, core.GetProgramHeader(0)); + EXPECT_EQ(nullptr, core.GetFirstProgramHeaderOfType(PT_LOAD)); EXPECT_FALSE(core.GetFirstNote().IsValid()); ASSERT_TRUE(WriteFile(core_file, &header, sizeof(header))); @@ -146,7 +146,7 @@ TEST(ElfCoreDumpTest, ValidCoreFile) { const unsigned kCrashThread = 1; const int kCrashSignal = SIGABRT; ASSERT_TRUE(crash_generator.CreateChildCrash(kNumOfThreads, kCrashThread, - kCrashSignal, NULL)); + kCrashSignal, nullptr)); pid_t expected_crash_thread_id = crash_generator.GetThreadId(kCrashThread); set expected_thread_ids; for (unsigned i = 0; i < kNumOfThreads; ++i) { @@ -210,13 +210,13 @@ TEST(ElfCoreDumpTest, ValidCoreFile) { switch (note.GetType()) { case NT_PRPSINFO: { - EXPECT_TRUE(description.data() != NULL); + EXPECT_TRUE(description.data() != nullptr); EXPECT_EQ(sizeof(elf_prpsinfo), description.length()); ++num_nt_prpsinfo; break; } case NT_PRSTATUS: { - EXPECT_TRUE(description.data() != NULL); + EXPECT_TRUE(description.data() != nullptr); EXPECT_EQ(sizeof(elf_prstatus), description.length()); const elf_prstatus* status = description.GetData(0); actual_thread_ids.insert(status->pr_pid); @@ -231,7 +231,7 @@ TEST(ElfCoreDumpTest, ValidCoreFile) { } #if defined(__i386__) || defined(__x86_64__) case NT_FPREGSET: { - EXPECT_TRUE(description.data() != NULL); + EXPECT_TRUE(description.data() != nullptr); EXPECT_EQ(sizeof(user_fpregs_struct), description.length()); ++num_nt_fpregset; break; @@ -239,7 +239,7 @@ TEST(ElfCoreDumpTest, ValidCoreFile) { #endif #if defined(__i386__) case NT_PRXFPREG: { - EXPECT_TRUE(description.data() != NULL); + EXPECT_TRUE(description.data() != nullptr); EXPECT_EQ(sizeof(user_fpxregs_struct), description.length()); ++num_nt_prxfpreg; break; diff --git a/src/common/linux/elf_symbols_to_module.cc b/src/common/linux/elf_symbols_to_module.cc index 70d50f891..f50eda43c 100644 --- a/src/common/linux/elf_symbols_to_module.cc +++ b/src/common/linux/elf_symbols_to_module.cc @@ -168,7 +168,7 @@ bool ELFSymbolsToModule(const uint8_t* symtab_section, #if !defined(__ANDROID__) // Android NDK doesn't provide abi::__cxa_demangle. int status = 0; char* demangled = - abi::__cxa_demangle(ext->name.c_str(), NULL, NULL, &status); + abi::__cxa_demangle(ext->name.c_str(), nullptr, nullptr, &status); if (demangled) { if (status == 0) ext->name = demangled; diff --git a/src/common/linux/elfutils-inl.h b/src/common/linux/elfutils-inl.h index 5fcc9c445..571371310 100644 --- a/src/common/linux/elfutils-inl.h +++ b/src/common/linux/elfutils-inl.h @@ -49,13 +49,13 @@ const typename ElfClass::Shdr* FindElfSectionByName( const char* section_names, const char* names_end, int nsection) { - assert(name != NULL); - assert(sections != NULL); + assert(name != nullptr); + assert(sections != nullptr); assert(nsection > 0); int name_len = my_strlen(name); if (name_len == 0) - return NULL; + return nullptr; for (int i = 0; i < nsection; ++i) { const char* section_name = section_names + sections[i].sh_name; @@ -65,7 +65,7 @@ const typename ElfClass::Shdr* FindElfSectionByName( return sections + i; } } - return NULL; + return nullptr; } } // namespace google_breakpad diff --git a/src/common/linux/elfutils.cc b/src/common/linux/elfutils.cc index 95b5db829..770aeb1dc 100644 --- a/src/common/linux/elfutils.cc +++ b/src/common/linux/elfutils.cc @@ -61,7 +61,7 @@ void FindElfClassSection(const char* elf_base, assert(elf_header->e_ident[EI_CLASS] == ElfClass::kClass); if (elf_header->e_shoff == 0) { - *section_start = NULL; + *section_start = nullptr; *section_size = 0; return; } @@ -78,7 +78,7 @@ void FindElfClassSection(const char* elf_base, sections, names, names_end, elf_header->e_shnum); - if (section != NULL && section->sh_size > 0) { + if (section != nullptr && section->sh_size > 0) { *section_start = elf_base + section->sh_offset; *section_size = section->sh_size; } @@ -135,7 +135,7 @@ bool FindElfSection(const void* elf_mapped_base, assert(section_start); assert(section_size); - *section_start = NULL; + *section_start = nullptr; *section_size = 0; if (!IsValidElf(elf_mapped_base)) @@ -148,11 +148,11 @@ bool FindElfSection(const void* elf_mapped_base, if (cls == ELFCLASS32) { FindElfClassSection(elf_base, section_name, section_type, section_start, section_size); - return *section_start != NULL; + return *section_start != nullptr; } else if (cls == ELFCLASS64) { FindElfClassSection(elf_base, section_name, section_type, section_start, section_size); - return *section_start != NULL; + return *section_start != nullptr; } return false; diff --git a/src/common/linux/google_crashdump_uploader_test.cc b/src/common/linux/google_crashdump_uploader_test.cc index e81f21d64..4e0c30e39 100644 --- a/src/common/linux/google_crashdump_uploader_test.cc +++ b/src/common/linux/google_crashdump_uploader_test.cc @@ -67,7 +67,7 @@ TEST_F(GoogleCrashdumpUploaderTest, InitFailsCausesUploadFailure) { GoogleCrashdumpUploader uploader("foobar", "1.0", "AAA-BBB", "", "", "test@test.com", "none", "/tmp/foo.dmp", "http://foo.com", "", "", std::move(m)); - ASSERT_FALSE(uploader.Upload(NULL, NULL, NULL)); + ASSERT_FALSE(uploader.Upload(nullptr, nullptr, nullptr)); } TEST_F(GoogleCrashdumpUploaderTest, TestSendRequestHappensWithValidParameters) { @@ -86,7 +86,7 @@ TEST_F(GoogleCrashdumpUploaderTest, TestSendRequestHappensWithValidParameters) { GoogleCrashdumpUploader uploader("foobar", "1.0", "AAA-BBB", "", "", "test@test.com", "none", tempfn, "http://foo.com", "", "", std::move(m)); - ASSERT_TRUE(uploader.Upload(NULL, NULL, NULL)); + ASSERT_TRUE(uploader.Upload(nullptr, nullptr, nullptr)); } @@ -97,7 +97,7 @@ TEST_F(GoogleCrashdumpUploaderTest, InvalidPathname) { GoogleCrashdumpUploader uploader("foobar", "1.0", "AAA-BBB", "", "", "test@test.com", "none", "/tmp/foo.dmp", "http://foo.com", "", "", std::move(m)); - ASSERT_FALSE(uploader.Upload(NULL, NULL, NULL)); + ASSERT_FALSE(uploader.Upload(nullptr, nullptr, nullptr)); } TEST_F(GoogleCrashdumpUploaderTest, TestRequiredParametersMustBePresent) { @@ -113,7 +113,7 @@ TEST_F(GoogleCrashdumpUploaderTest, TestRequiredParametersMustBePresent) { "http://foo.com", "", ""); - ASSERT_FALSE(uploader.Upload(NULL, NULL, NULL)); + ASSERT_FALSE(uploader.Upload(nullptr, nullptr, nullptr)); // Test with empty product version. GoogleCrashdumpUploader uploader1("product", @@ -128,7 +128,7 @@ TEST_F(GoogleCrashdumpUploaderTest, TestRequiredParametersMustBePresent) { "", ""); - ASSERT_FALSE(uploader1.Upload(NULL, NULL, NULL)); + ASSERT_FALSE(uploader1.Upload(nullptr, nullptr, nullptr)); // Test with empty client GUID. GoogleCrashdumpUploader uploader2("product", @@ -142,6 +142,6 @@ TEST_F(GoogleCrashdumpUploaderTest, TestRequiredParametersMustBePresent) { "", "", ""); - ASSERT_FALSE(uploader2.Upload(NULL, NULL, NULL)); + ASSERT_FALSE(uploader2.Upload(nullptr, nullptr, nullptr)); } } diff --git a/src/common/linux/guid_creator.cc b/src/common/linux/guid_creator.cc index 8635f9dc0..f3e576a40 100644 --- a/src/common/linux/guid_creator.cc +++ b/src/common/linux/guid_creator.cc @@ -121,7 +121,7 @@ class GUIDGenerator { // time(NULL) is a very poor seed, so lacking anything better mix an // address into it. We drop the four rightmost bits as they're likely to // be 0 on almost all architectures. - srand(time(NULL) | ((uintptr_t)&once_control >> 4)); + srand(time(nullptr) | ((uintptr_t)&once_control >> 4)); } static pthread_once_t once_control; diff --git a/src/common/linux/http_upload.cc b/src/common/linux/http_upload.cc index 0a5bdb502..e39042651 100644 --- a/src/common/linux/http_upload.cc +++ b/src/common/linux/http_upload.cc @@ -66,7 +66,7 @@ bool HTTPUpload::SendRequest(const string& url, string* response_body, long* response_code, string* error_description) { - if (response_code != NULL) + if (response_code != nullptr) *response_code = 0; if (!CheckParameters(parameters)) @@ -74,19 +74,19 @@ bool HTTPUpload::SendRequest(const string& url, // We may have been linked statically; if curl_easy_init is in the // current binary, no need to search for a dynamic version. - void* curl_lib = dlopen(NULL, RTLD_NOW); + void* curl_lib = dlopen(nullptr, RTLD_NOW); if (!CheckCurlLib(curl_lib)) { fprintf(stderr, "Failed to open curl lib from binary, use libcurl.so instead\n"); dlerror(); // Clear dlerror before attempting to open libraries. dlclose(curl_lib); - curl_lib = NULL; + curl_lib = nullptr; } if (!curl_lib) { curl_lib = dlopen("libcurl.so", RTLD_NOW); } if (!curl_lib) { - if (error_description != NULL) + if (error_description != nullptr) *error_description = dlerror(); curl_lib = dlopen("libcurl.so.4", RTLD_NOW); } @@ -105,7 +105,7 @@ bool HTTPUpload::SendRequest(const string& url, CURL* (*curl_easy_init)(void); *(void**) (&curl_easy_init) = dlsym(curl_lib, "curl_easy_init"); CURL* curl = (*curl_easy_init)(); - if (error_description != NULL) + if (error_description != nullptr) *error_description = "No Error"; if (!curl) { @@ -131,8 +131,8 @@ bool HTTPUpload::SendRequest(const string& url, if (!ca_certificate_file.empty()) (*curl_easy_setopt)(curl, CURLOPT_CAINFO, ca_certificate_file.c_str()); - struct curl_httppost* formpost = NULL; - struct curl_httppost* lastptr = NULL; + struct curl_httppost* formpost = nullptr; + struct curl_httppost* lastptr = nullptr; // Add form data. CURLFORMcode (*curl_formadd)(struct curl_httppost**, struct curl_httppost**, ...); *(void**) (&curl_formadd) = dlsym(curl_lib, "curl_formadd"); @@ -154,14 +154,14 @@ bool HTTPUpload::SendRequest(const string& url, (*curl_easy_setopt)(curl, CURLOPT_HTTPPOST, formpost); // Disable 100-continue header. - struct curl_slist* headerlist = NULL; + struct curl_slist* headerlist = nullptr; char buf[] = "Expect:"; struct curl_slist* (*curl_slist_append)(struct curl_slist*, const char*); *(void**) (&curl_slist_append) = dlsym(curl_lib, "curl_slist_append"); headerlist = (*curl_slist_append)(headerlist, buf); (*curl_easy_setopt)(curl, CURLOPT_HTTPHEADER, headerlist); - if (response_body != NULL) { + if (response_body != nullptr) { (*curl_easy_setopt)(curl, CURLOPT_WRITEFUNCTION, WriteCallback); (*curl_easy_setopt)(curl, CURLOPT_WRITEDATA, reinterpret_cast(response_body)); @@ -173,7 +173,7 @@ bool HTTPUpload::SendRequest(const string& url, CURLcode (*curl_easy_perform)(CURL*); *(void**) (&curl_easy_perform) = dlsym(curl_lib, "curl_easy_perform"); err_code = (*curl_easy_perform)(curl); - if (response_code != NULL) { + if (response_code != nullptr) { CURLcode (*curl_easy_getinfo)(CURL*, CURLINFO, ...); *(void**) (&curl_easy_getinfo) = dlsym(curl_lib, "curl_easy_getinfo"); (*curl_easy_getinfo)(curl, CURLINFO_RESPONSE_CODE, response_code); @@ -186,18 +186,18 @@ bool HTTPUpload::SendRequest(const string& url, url.c_str(), (*curl_easy_strerror)(err_code)); #endif - if (error_description != NULL) + if (error_description != nullptr) *error_description = (*curl_easy_strerror)(err_code); void (*curl_easy_cleanup)(CURL*); *(void**) (&curl_easy_cleanup) = dlsym(curl_lib, "curl_easy_cleanup"); (*curl_easy_cleanup)(curl); - if (formpost != NULL) { + if (formpost != nullptr) { void (*curl_formfree)(struct curl_httppost*); *(void**) (&curl_formfree) = dlsym(curl_lib, "curl_formfree"); (*curl_formfree)(formpost); } - if (headerlist != NULL) { + if (headerlist != nullptr) { void (*curl_slist_free_all)(struct curl_slist*); *(void**) (&curl_slist_free_all) = dlsym(curl_lib, "curl_slist_free_all"); (*curl_slist_free_all)(headerlist); diff --git a/src/common/linux/linux_libc_support.cc b/src/common/linux/linux_libc_support.cc index abcbfde8a..deb1a74b6 100644 --- a/src/common/linux/linux_libc_support.cc +++ b/src/common/linux/linux_libc_support.cc @@ -132,7 +132,7 @@ const char* my_strchr(const char* haystack, char needle) { } const char* my_strrchr(const char* haystack, char needle) { - const char* ret = NULL; + const char* ret = nullptr; while (*haystack) { if (*haystack == needle) ret = haystack; @@ -148,7 +148,7 @@ void* my_memchr(const void* src, int needle, size_t src_len) { if (*p == needle) return (void*)p; } - return NULL; + return nullptr; } // Read a hex value diff --git a/src/common/linux/linux_libc_support_unittest.cc b/src/common/linux/linux_libc_support_unittest.cc index 30dd1430c..48d6f5e29 100644 --- a/src/common/linux/linux_libc_support_unittest.cc +++ b/src/common/linux/linux_libc_support_unittest.cc @@ -38,7 +38,7 @@ typedef testing::Test LinuxLibcSupportTest; } TEST(LinuxLibcSupportTest, strlen) { - static const char* test_data[] = { "", "a", "aa", "aaa", "aabc", NULL }; + static const char* test_data[] = { "", "a", "aa", "aaa", "aabc", nullptr }; for (unsigned i = 0; ; ++i) { if (!test_data[i]) break; @@ -56,7 +56,7 @@ TEST(LinuxLibcSupportTest, strcmp) { "ab", "aa", "abc", "ab", "abc", "abc", - NULL, + nullptr, }; for (unsigned i = 0; ; ++i) { @@ -130,9 +130,9 @@ TEST(LinuxLibcSupportTest, uitos) { } TEST(LinuxLibcSupportTest, strchr) { - ASSERT_EQ(NULL, my_strchr("abc", 'd')); - ASSERT_EQ(NULL, my_strchr("", 'd')); - ASSERT_EQ(NULL, my_strchr("efghi", 'd')); + ASSERT_EQ(nullptr, my_strchr("abc", 'd')); + ASSERT_EQ(nullptr, my_strchr("", 'd')); + ASSERT_EQ(nullptr, my_strchr("efghi", 'd')); ASSERT_TRUE(my_strchr("a", 'a')); ASSERT_TRUE(my_strchr("abc", 'a')); @@ -144,9 +144,9 @@ TEST(LinuxLibcSupportTest, strchr) { } TEST(LinuxLibcSupportTest, strrchr) { - ASSERT_EQ(NULL, my_strrchr("abc", 'd')); - ASSERT_EQ(NULL, my_strrchr("", 'd')); - ASSERT_EQ(NULL, my_strrchr("efghi", 'd')); + ASSERT_EQ(nullptr, my_strrchr("abc", 'd')); + ASSERT_EQ(nullptr, my_strrchr("", 'd')); + ASSERT_EQ(nullptr, my_strrchr("efghi", 'd')); ASSERT_TRUE(my_strrchr("a", 'a')); ASSERT_TRUE(my_strrchr("abc", 'a')); @@ -158,9 +158,9 @@ TEST(LinuxLibcSupportTest, strrchr) { } TEST(LinuxLibcSupportTest, memchr) { - ASSERT_EQ(NULL, my_memchr("abc", 'd', 3)); - ASSERT_EQ(NULL, my_memchr("abcd", 'd', 3)); - ASSERT_EQ(NULL, my_memchr("a", 'a', 0)); + ASSERT_EQ(nullptr, my_memchr("abc", 'd', 3)); + ASSERT_EQ(nullptr, my_memchr("abcd", 'd', 3)); + ASSERT_EQ(nullptr, my_memchr("a", 'a', 0)); static const char abc3[] = "abcabcabc"; ASSERT_EQ(abc3, my_memchr(abc3, 'a', 3)); diff --git a/src/common/linux/memory_mapped_file.cc b/src/common/linux/memory_mapped_file.cc index a7b96eb59..5e54aca5a 100644 --- a/src/common/linux/memory_mapped_file.cc +++ b/src/common/linux/memory_mapped_file.cc @@ -95,7 +95,8 @@ bool MemoryMappedFile::Map(const char* path, size_t offset) { } size_t content_len = file_len - offset; - void* data = sys_mmap(NULL, content_len, PROT_READ, MAP_PRIVATE, fd, offset); + void* data = sys_mmap(nullptr, content_len, PROT_READ, MAP_PRIVATE, fd, + offset); sys_close(fd); if (data == MAP_FAILED) { return false; @@ -108,7 +109,7 @@ bool MemoryMappedFile::Map(const char* path, size_t offset) { void MemoryMappedFile::Unmap() { if (content_.data()) { sys_munmap(const_cast(content_.data()), content_.length()); - content_.Set(NULL, 0); + content_.Set(nullptr, 0); } } diff --git a/src/common/linux/memory_mapped_file_unittest.cc b/src/common/linux/memory_mapped_file_unittest.cc index b7a61a70e..213dca6f8 100644 --- a/src/common/linux/memory_mapped_file_unittest.cc +++ b/src/common/linux/memory_mapped_file_unittest.cc @@ -55,7 +55,7 @@ class MemoryMappedFileTest : public testing::Test { protected: void ExpectNoMappedData(const MemoryMappedFile& mapped_file) { EXPECT_TRUE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() == NULL); + EXPECT_TRUE(mapped_file.data() == nullptr); EXPECT_EQ(0U, mapped_file.size()); } }; @@ -87,7 +87,7 @@ TEST_F(MemoryMappedFileTest, MapNonexistentFile) { TEST_F(MemoryMappedFileTest, MapEmptyFile) { AutoTempDir temp_dir; string test_file = temp_dir.path() + "/empty_file"; - ASSERT_TRUE(WriteFile(test_file.c_str(), NULL, 0)); + ASSERT_TRUE(WriteFile(test_file.c_str(), nullptr, 0)); { MemoryMappedFile mapped_file(test_file.c_str(), 0); @@ -114,7 +114,7 @@ TEST_F(MemoryMappedFileTest, MapNonEmptyFile) { { MemoryMappedFile mapped_file(test_file.c_str(), 0); EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); + EXPECT_TRUE(mapped_file.data() != nullptr); EXPECT_EQ(data_size, mapped_file.size()); EXPECT_EQ(0, memcmp(data, mapped_file.data(), data_size)); } @@ -122,7 +122,7 @@ TEST_F(MemoryMappedFileTest, MapNonEmptyFile) { MemoryMappedFile mapped_file; EXPECT_TRUE(mapped_file.Map(test_file.c_str(), 0)); EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); + EXPECT_TRUE(mapped_file.data() != nullptr); EXPECT_EQ(data_size, mapped_file.size()); EXPECT_EQ(0, memcmp(data, mapped_file.data(), data_size)); } @@ -150,13 +150,13 @@ TEST_F(MemoryMappedFileTest, RemapAfterMap) { { MemoryMappedFile mapped_file(test_file1.c_str(), 0); EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); + EXPECT_TRUE(mapped_file.data() != nullptr); EXPECT_EQ(data1_size, mapped_file.size()); EXPECT_EQ(0, memcmp(data1, mapped_file.data(), data1_size)); mapped_file.Map(test_file2.c_str(), 0); EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); + EXPECT_TRUE(mapped_file.data() != nullptr); EXPECT_EQ(data2_size, mapped_file.size()); EXPECT_EQ(0, memcmp(data2, mapped_file.data(), data2_size)); } @@ -164,13 +164,13 @@ TEST_F(MemoryMappedFileTest, RemapAfterMap) { MemoryMappedFile mapped_file; EXPECT_TRUE(mapped_file.Map(test_file1.c_str(), 0)); EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); + EXPECT_TRUE(mapped_file.data() != nullptr); EXPECT_EQ(data1_size, mapped_file.size()); EXPECT_EQ(0, memcmp(data1, mapped_file.data(), data1_size)); mapped_file.Map(test_file2.c_str(), 0); EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); + EXPECT_TRUE(mapped_file.data() != nullptr); EXPECT_EQ(data2_size, mapped_file.size()); EXPECT_EQ(0, memcmp(data2, mapped_file.data(), data2_size)); } @@ -192,7 +192,7 @@ TEST_F(MemoryMappedFileTest, MapWithOffset) { { MemoryMappedFile mapped_file(test_file1.c_str(), page_size); EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); + EXPECT_TRUE(mapped_file.data() != nullptr); EXPECT_EQ(data1_size - page_size, mapped_file.size()); EXPECT_EQ( 0, @@ -202,7 +202,7 @@ TEST_F(MemoryMappedFileTest, MapWithOffset) { MemoryMappedFile mapped_file; mapped_file.Map(test_file1.c_str(), page_size); EXPECT_FALSE(mapped_file.content().IsEmpty()); - EXPECT_TRUE(mapped_file.data() != NULL); + EXPECT_TRUE(mapped_file.data() != nullptr); EXPECT_EQ(data1_size - page_size, mapped_file.size()); EXPECT_EQ( 0, diff --git a/src/common/linux/tests/crash_generator.cc b/src/common/linux/tests/crash_generator.cc index 1cad9ae26..7a7dae51d 100644 --- a/src/common/linux/tests/crash_generator.cc +++ b/src/common/linux/tests/crash_generator.cc @@ -101,7 +101,7 @@ void* thread_function(void* data) { namespace google_breakpad { CrashGenerator::CrashGenerator() - : shared_memory_(NULL), + : shared_memory_(nullptr), shared_memory_size_(0) { } @@ -154,7 +154,7 @@ bool CrashGenerator::UnmapSharedMemory() { return true; if (munmap(shared_memory_, shared_memory_size_) == 0) { - shared_memory_ = NULL; + shared_memory_ = nullptr; shared_memory_size_ = 0; return true; } @@ -312,7 +312,7 @@ void CrashGenerator::CreateThreadsInChildProcess(unsigned num_threads) { } pthread_barrier_t thread_barrier; - if (pthread_barrier_init(&thread_barrier, NULL, num_threads) != 0) { + if (pthread_barrier_init(&thread_barrier, nullptr, num_threads) != 0) { fprintf(stderr, "CrashGenerator: Failed to initialize thread barrier\n"); exit(1); } diff --git a/src/common/long_string_dictionary.cc b/src/common/long_string_dictionary.cc index 19a649e7b..537972e50 100644 --- a/src/common/long_string_dictionary.cc +++ b/src/common/long_string_dictionary.cc @@ -164,7 +164,7 @@ const string LongStringDictionary::GetValueForKey(const char* key) const { const char* segment_value = SimpleStringDictionary::GetValueForKey(segment_key); - if (segment_value != NULL) { + if (segment_value != nullptr) { found_segment = true; return_value.append(segment_value); } else { diff --git a/src/common/long_string_dictionary_unittest.cc b/src/common/long_string_dictionary_unittest.cc index f10dc0d97..86bb26bab 100644 --- a/src/common/long_string_dictionary_unittest.cc +++ b/src/common/long_string_dictionary_unittest.cc @@ -63,7 +63,7 @@ TEST(LongStringDictionary, LongStringDictionary) { EXPECT_EQ("", dict.GetValueForKey("key3")); // Remove by setting value to NULL - dict.SetKeyValue("key2", NULL); + dict.SetKeyValue("key2", nullptr); // Now make sure it's not there anymore EXPECT_EQ("", dict.GetValueForKey("key2")); diff --git a/src/common/mac/MachIPC.h b/src/common/mac/MachIPC.h index 78b97ad96..38b339f5e 100644 --- a/src/common/mac/MachIPC.h +++ b/src/common/mac/MachIPC.h @@ -164,7 +164,7 @@ class MachMessage { // The receiver of the message can retrieve the raw data this way uint8_t* GetData() { - return GetDataLength() > 0 ? GetDataPacket()->data : NULL; + return GetDataLength() > 0 ? GetDataPacket()->data : nullptr; } uint32_t GetDataLength() { diff --git a/src/common/mac/dump_syms.cc b/src/common/mac/dump_syms.cc index c8a1db195..0e2c094f4 100644 --- a/src/common/mac/dump_syms.cc +++ b/src/common/mac/dump_syms.cc @@ -109,7 +109,7 @@ vector list_directory(const string& directory) { path += '/'; } - struct dirent* entry = NULL; + struct dirent* entry = nullptr; while ((entry = readdir(dir))) { if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) { entries.push_back(path + entry->d_name); diff --git a/src/common/mac/dump_syms.h b/src/common/mac/dump_syms.h index 31d246ee4..8afd0ac5a 100644 --- a/src/common/mac/dump_syms.h +++ b/src/common/mac/dump_syms.h @@ -119,7 +119,7 @@ class DumpSymbols { *count = object_files_.size(); if (object_files_.size() > 0) return &object_files_[0]; - return NULL; + return nullptr; } // Read the selected object file's debugging information, and write out the diff --git a/src/common/mac/launch_reporter.cc b/src/common/mac/launch_reporter.cc index f6b8aed1c..3f86af873 100644 --- a/src/common/mac/launch_reporter.cc +++ b/src/common/mac/launch_reporter.cc @@ -38,7 +38,7 @@ namespace google_breakpad { void LaunchReporter(const char *reporter_executable_path, const char *config_file_path) { - const char* argv[] = { reporter_executable_path, config_file_path, NULL }; + const char* argv[] = { reporter_executable_path, config_file_path, nullptr }; // Launch the reporter pid_t pid = fork(); diff --git a/src/common/mac/macho_id.cc b/src/common/mac/macho_id.cc index bb0058ced..aba3b306e 100644 --- a/src/common/mac/macho_id.cc +++ b/src/common/mac/macho_id.cc @@ -53,7 +53,7 @@ using google_breakpad::MD5Update; using google_breakpad::MD5Final; MachoID::MachoID(const char* path) - : memory_(0), memory_size_(0), md5_context_(), update_function_(NULL) { + : memory_(0), memory_size_(0), md5_context_(), update_function_(nullptr) { snprintf(path_, sizeof(path_), "%s", path); } @@ -62,7 +62,7 @@ MachoID::MachoID(void* memory, size_t size) memory_(memory), memory_size_(size), md5_context_(), - update_function_(NULL) {} + update_function_(nullptr) {} MachoID::~MachoID() {} diff --git a/src/common/mac/macho_reader.cc b/src/common/mac/macho_reader.cc index 0324be143..0f2f7bc3f 100644 --- a/src/common/mac/macho_reader.cc +++ b/src/common/mac/macho_reader.cc @@ -368,7 +368,7 @@ bool Reader::WalkLoadCommands(Reader::LoadCommandHandler* handler) const { // out. To help us handle this special case properly, give such // segments' contents NULL starting and ending pointers. if (segment.fileoff == 0 && segment.filesize == 0) { - segment.contents.start = segment.contents.end = NULL; + segment.contents.start = segment.contents.end = nullptr; } else { segment.contents.start = buffer_.start + segment.fileoff; segment.contents.end = segment.contents.start + segment.filesize; @@ -507,16 +507,16 @@ bool Reader::WalkSegmentSections(const Segment& segment, if (section_type == S_ZEROFILL || section_type == S_THREAD_LOCAL_ZEROFILL || section_type == S_GB_ZEROFILL) { // Zero-fill sections have a size, but no contents. - section.contents.start = section.contents.end = NULL; - } else if (segment.contents.start == NULL && - segment.contents.end == NULL) { + section.contents.start = section.contents.end = nullptr; + } else if (segment.contents.start == nullptr && + segment.contents.end == nullptr) { // Mach-O files in .dSYM bundles have the contents of the loaded // segments removed, and their file offsets and file sizes zeroed // out. However, the sections within those segments still have // non-zero sizes. There's no reason to call MisplacedSectionData in // this case; the caller may just need the section's load // address. But do set the contents' limits to NULL, for safety. - section.contents.start = section.contents.end = NULL; + section.contents.start = section.contents.end = nullptr; } else { if (offset < size_t(segment.contents.start - buffer_.start) || offset > size_t(segment.contents.end - buffer_.start) || @@ -530,7 +530,7 @@ bool Reader::WalkSegmentSections(const Segment& segment, // segments partially removed. The removed sections will have zero as // their offset. MisplacedSectionData should not be called in this // case. - section.contents.start = section.contents.end = NULL; + section.contents.start = section.contents.end = nullptr; } } else { section.contents.start = buffer_.start + offset; diff --git a/src/common/mac/macho_reader.h b/src/common/mac/macho_reader.h index d3c61a06a..47134b03a 100644 --- a/src/common/mac/macho_reader.h +++ b/src/common/mac/macho_reader.h @@ -133,7 +133,7 @@ class FatReader { *count = object_files_.size(); if (object_files_.size() > 0) return &object_files_[0]; - return NULL; + return nullptr; } private: diff --git a/src/common/mac/macho_reader_unittest.cc b/src/common/mac/macho_reader_unittest.cc index 4b5ac6ca0..b0c69a8bc 100644 --- a/src/common/mac/macho_reader_unittest.cc +++ b/src/common/mac/macho_reader_unittest.cc @@ -499,7 +499,7 @@ class WithConfiguration { WithConfiguration* saved_; }; -WithConfiguration* WithConfiguration::current_ = NULL; +WithConfiguration* WithConfiguration::current_ = nullptr; // A test_assembler::Section with a size that we can cite. The start(), // Here() and Mark() member functions of a SizedSection always represent @@ -1640,7 +1640,7 @@ TEST_F(LoadCommand, ZappedSegment) { Segment actual_segment; EXPECT_TRUE(reader.FindSegment("zapped", &actual_segment)); - ByteBuffer zapped_extent(NULL, 0); + ByteBuffer zapped_extent(nullptr, 0); EXPECT_CALL(section_handler, HandleSection(MatchSection(false, "twitching", "zapped", 0x696d83cc, 0, 0x93b3bd42, @@ -1706,7 +1706,7 @@ TEST_F(LoadCommand, MapSegmentSections) { MatchSection(true, "cara cara", "thorax", 0x04d462e2)); ASSERT_TRUE(section_map.find("sixteenprecisely") != section_map.end()); - ByteBuffer sixteenprecisely_contents(NULL, 0); + ByteBuffer sixteenprecisely_contents(nullptr, 0); EXPECT_THAT(section_map["sixteenprecisely"], MatchSection(true, "sixteenprecisely", "thorax", 0x04d462e2 + 7, 12, S_ZEROFILL, diff --git a/src/common/mac/macho_walker.cc b/src/common/mac/macho_walker.cc index 4b9f56c2a..c047da998 100644 --- a/src/common/mac/macho_walker.cc +++ b/src/common/mac/macho_walker.cc @@ -53,11 +53,11 @@ namespace MacFileUtilities { MachoWalker::MachoWalker(const char* path, LoadCommandCallback callback, void* context) : file_(-1), - memory_(NULL), + memory_(nullptr), memory_size_(0), callback_(callback), callback_context_(context), - current_header_(NULL), + current_header_(nullptr), current_header_size_(0), current_header_offset_(0) { file_ = open(path, O_RDONLY); @@ -70,7 +70,7 @@ MachoWalker::MachoWalker(void* memory, size_t size, memory_size_(size), callback_(callback), callback_context_(context), - current_header_(NULL), + current_header_(nullptr), current_header_size_(0), current_header_offset_(0) { } @@ -221,7 +221,7 @@ bool MachoWalker::WalkHeaderAtOffset(off_t offset) { current_header_offset_ = offset; offset += current_header_size_; bool result = WalkHeaderCore(offset, header.ncmds, swap); - current_header_ = NULL; + current_header_ = nullptr; current_header_size_ = 0; current_header_offset_ = 0; return result; @@ -241,7 +241,7 @@ bool MachoWalker::WalkHeader64AtOffset(off_t offset) { current_header_offset_ = offset; offset += current_header_size_; bool result = WalkHeaderCore(offset, header.ncmds, swap); - current_header_ = NULL; + current_header_ = nullptr; current_header_size_ = 0; current_header_offset_ = 0; return result; diff --git a/src/common/memory_allocator.h b/src/common/memory_allocator.h index 1c99913ad..6dc943144 100644 --- a/src/common/memory_allocator.h +++ b/src/common/memory_allocator.h @@ -60,8 +60,8 @@ class PageAllocator { public: PageAllocator() : page_size_(getpagesize()), - last_(NULL), - current_page_(NULL), + last_(nullptr), + current_page_(nullptr), page_offset_(0), pages_allocated_(0) { } @@ -72,14 +72,14 @@ class PageAllocator { void* Alloc(size_t bytes) { if (!bytes) - return NULL; + return nullptr; if (current_page_ && page_size_ - page_offset_ >= bytes) { uint8_t* const ret = current_page_ + page_offset_; page_offset_ += bytes; if (page_offset_ == page_size_) { page_offset_ = 0; - current_page_ = NULL; + current_page_ = nullptr; } return ret; @@ -89,12 +89,12 @@ class PageAllocator { (bytes + sizeof(PageHeader) + page_size_ - 1) / page_size_; uint8_t* const ret = GetNPages(pages); if (!ret) - return NULL; + return nullptr; page_offset_ = (page_size_ - (page_size_ * pages - (bytes + sizeof(PageHeader)))) % page_size_; - current_page_ = page_offset_ ? ret + page_size_ * (pages - 1) : NULL; + current_page_ = page_offset_ ? ret + page_size_ * (pages - 1) : nullptr; return ret + sizeof(PageHeader); } @@ -115,10 +115,10 @@ class PageAllocator { private: uint8_t* GetNPages(size_t num_pages) { - void* a = sys_mmap(NULL, page_size_ * num_pages, PROT_READ | PROT_WRITE, + void* a = sys_mmap(nullptr, page_size_ * num_pages, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (a == MAP_FAILED) - return NULL; + return nullptr; #if defined(MEMORY_SANITIZER) // We need to indicate to MSan that memory allocated through sys_mmap is @@ -167,7 +167,7 @@ struct PageStdAllocator { using size_type = typename AllocatorTraits::size_type; explicit PageStdAllocator(PageAllocator& allocator) : allocator_(allocator), - stackdata_(NULL), + stackdata_(nullptr), stackdata_size_(0) {} diff --git a/src/common/memory_allocator_unittest.cc b/src/common/memory_allocator_unittest.cc index 8ef68913b..57a7562d7 100644 --- a/src/common/memory_allocator_unittest.cc +++ b/src/common/memory_allocator_unittest.cc @@ -50,7 +50,7 @@ TEST(PageAllocatorTest, SmallObjects) { EXPECT_EQ(0U, allocator.pages_allocated()); for (unsigned i = 1; i < 1024; ++i) { uint8_t* p = reinterpret_cast(allocator.Alloc(i)); - ASSERT_FALSE(p == NULL); + ASSERT_FALSE(p == nullptr); memset(p, 0, i); } } @@ -60,11 +60,11 @@ TEST(PageAllocatorTest, LargeObject) { EXPECT_EQ(0U, allocator.pages_allocated()); uint8_t* p = reinterpret_cast(allocator.Alloc(10000)); - ASSERT_FALSE(p == NULL); + ASSERT_FALSE(p == nullptr); EXPECT_EQ(3U, allocator.pages_allocated()); for (unsigned i = 1; i < 10; ++i) { uint8_t* p = reinterpret_cast(allocator.Alloc(i)); - ASSERT_FALSE(p == NULL); + ASSERT_FALSE(p == nullptr); memset(p, 0, i); } } diff --git a/src/common/memory_range_unittest.cc b/src/common/memory_range_unittest.cc index f081d6798..0e19daaed 100644 --- a/src/common/memory_range_unittest.cc +++ b/src/common/memory_range_unittest.cc @@ -84,11 +84,11 @@ const struct { { 0, 4, 9, kBufferPointer + 36 }, { kBufferSize - 1, 1, 0, kBufferPointer + kBufferSize - 1 }, // Invalid array elemenets - { 0, 1, kBufferSize, NULL }, - { 0, 4, 10, NULL }, - { kBufferSize - 1, 1, 1, NULL }, - { kBufferSize - 1, 2, 0, NULL }, - { kBufferSize, 1, 0, NULL }, + { 0, 1, kBufferSize, nullptr }, + { 0, 4, 10, nullptr }, + { kBufferSize - 1, 1, 1, nullptr }, + { kBufferSize - 1, 2, 0, nullptr }, + { kBufferSize, 1, 0, nullptr }, }; const size_t kNumElements = sizeof(kElements) / sizeof(kElements[0]); @@ -96,7 +96,7 @@ const size_t kNumElements = sizeof(kElements) / sizeof(kElements[0]); TEST(MemoryRangeTest, DefaultConstructor) { MemoryRange range; - EXPECT_EQ(NULL, range.data()); + EXPECT_EQ(nullptr, range.data()); EXPECT_EQ(0U, range.length()); } @@ -109,7 +109,7 @@ TEST(MemoryRangeTest, ConstructorWithDataAndLength) { TEST(MemoryRangeTest, Reset) { MemoryRange range; range.Reset(); - EXPECT_EQ(NULL, range.data()); + EXPECT_EQ(nullptr, range.data()); EXPECT_EQ(0U, range.length()); range.Set(kBuffer, kBufferSize); @@ -117,7 +117,7 @@ TEST(MemoryRangeTest, Reset) { EXPECT_EQ(kBufferSize, range.length()); range.Reset(); - EXPECT_EQ(NULL, range.data()); + EXPECT_EQ(nullptr, range.data()); EXPECT_EQ(0U, range.length()); } @@ -127,15 +127,15 @@ TEST(MemoryRangeTest, Set) { EXPECT_EQ(kBufferPointer, range.data()); EXPECT_EQ(kBufferSize, range.length()); - range.Set(NULL, 0); - EXPECT_EQ(NULL, range.data()); + range.Set(nullptr, 0); + EXPECT_EQ(nullptr, range.data()); EXPECT_EQ(0U, range.length()); } TEST(MemoryRangeTest, SubrangeOfEmptyMemoryRange) { MemoryRange range; MemoryRange subrange = range.Subrange(0, 10); - EXPECT_EQ(NULL, subrange.data()); + EXPECT_EQ(nullptr, subrange.data()); EXPECT_EQ(0U, subrange.length()); } @@ -157,8 +157,8 @@ TEST(MemoryRangeTest, SubrangeAndGetData) { EXPECT_EQ(sub_length, subrange.length()); } else { EXPECT_FALSE(range.Covers(sub_offset, sub_length)); - EXPECT_EQ(NULL, range.GetData(sub_offset, sub_length)); - EXPECT_EQ(NULL, subrange.data()); + EXPECT_EQ(nullptr, range.GetData(sub_offset, sub_length)); + EXPECT_EQ(nullptr, subrange.data()); EXPECT_EQ(0U, subrange.length()); } } diff --git a/src/common/module.cc b/src/common/module.cc index 6f81b5119..c55bb6cf9 100644 --- a/src/common/module.cc +++ b/src/common/module.cc @@ -273,7 +273,7 @@ Module::File* Module::FindFile(const char* name) { Module::File* Module::FindExistingFile(const string& name) { FileByNameMap::iterator it = files_.find(&name); - return (it == files_.end()) ? NULL : it->second; + return (it == files_.end()) ? nullptr : it->second; } void Module::GetFiles(vector* vec) { diff --git a/src/common/module_unittest.cc b/src/common/module_unittest.cc index 6b2c49a41..2a5579351 100644 --- a/src/common/module_unittest.cc +++ b/src/common/module_unittest.cc @@ -504,7 +504,7 @@ TEST(Module, ConstructUniqueFiles) { EXPECT_EQ(file1, file3); EXPECT_EQ(file2, file4); EXPECT_EQ(file1, m.FindExistingFile("foo")); - EXPECT_TRUE(m.FindExistingFile("baz") == NULL); + EXPECT_TRUE(m.FindExistingFile("baz") == nullptr); } TEST(Module, ConstructDuplicateFunctions) { diff --git a/src/common/simple_string_dictionary.h b/src/common/simple_string_dictionary.h index 166d56c8d..0e3158859 100644 --- a/src/common/simple_string_dictionary.h +++ b/src/common/simple_string_dictionary.h @@ -142,11 +142,11 @@ class NonAllocatingMap { const char* GetValueForKey(const char* key) const { assert(key); if (!key) - return NULL; + return nullptr; size_t index = GetEntryIndexForKey(key); if (index == num_entries) - return NULL; + return nullptr; return entries_[index].value; } diff --git a/src/common/simple_string_dictionary_unittest.cc b/src/common/simple_string_dictionary_unittest.cc index b4dd7fe90..caa21c5c4 100644 --- a/src/common/simple_string_dictionary_unittest.cc +++ b/src/common/simple_string_dictionary_unittest.cc @@ -86,7 +86,7 @@ TEST(NonAllocatingMapTest, SimpleStringDictionary) { EXPECT_FALSE(dict.GetValueForKey("key3")); // Remove by setting value to NULL - dict.SetKeyValue("key2", NULL); + dict.SetKeyValue("key2", nullptr); // Now make sure it's not there anymore EXPECT_FALSE(dict.GetValueForKey("key2")); @@ -326,13 +326,13 @@ TEST(NonAllocatingMapTest, ByIndex) { TEST(NonAllocatingMapTest, NullKey) { NonAllocatingMap<4, 6, 6> map; - ASSERT_DEATH(map.SetKeyValue(NULL, "hello"), ""); + ASSERT_DEATH(map.SetKeyValue(nullptr, "hello"), ""); map.SetKeyValue("hi", "there"); - ASSERT_DEATH(map.GetValueForKey(NULL), ""); + ASSERT_DEATH(map.GetValueForKey(nullptr), ""); EXPECT_STREQ("there", map.GetValueForKey("hi")); - ASSERT_DEATH(map.GetValueForKey(NULL), ""); + ASSERT_DEATH(map.GetValueForKey(nullptr), ""); map.RemoveKey("hi"); EXPECT_EQ(0u, map.GetCount()); } diff --git a/src/common/solaris/dump_symbols.cc b/src/common/solaris/dump_symbols.cc index 6077ac114..ed7653a2c 100644 --- a/src/common/solaris/dump_symbols.cc +++ b/src/common/solaris/dump_symbols.cc @@ -218,14 +218,14 @@ bool IsValidElf(const GElf_Ehdr* elf_header) { static bool FindSectionByName(Elf* elf, const char* name, int shstrndx, GElf_Shdr* shdr) { - assert(name != NULL); + assert(name != nullptr); if (strlen(name) == 0) return false; - Elf_Scn* scn = NULL; + Elf_Scn* scn = nullptr; - while ((scn = elf_nextscn(elf, scn)) != NULL) { + while ((scn = elf_nextscn(elf, scn)) != nullptr) { if (gelf_getshdr(scn, shdr) == (GElf_Shdr*)0) { fprintf(stderr, "failed to read section header: %s\n", elf_errmsg(0)); return false; @@ -398,7 +398,7 @@ bool LoadAllSymbols(const GElf_Shdr* stab_section, const GElf_Shdr* stabstr_section, GElf_Word base, struct SymbolInfo* symbols) { - if (stab_section == NULL || stabstr_section == NULL) + if (stab_section == nullptr || stabstr_section == nullptr) return false; char* stabstr = reinterpret_cast(stabstr_section->sh_offset + base); @@ -481,7 +481,7 @@ bool LoadSymbols(Elf* elf, GElf_Ehdr* elf_header, struct SymbolInfo* symbols, } bool WriteModuleInfo(int fd, GElf_Half arch, const std::string& obj_file) { - const char* arch_name = NULL; + const char* arch_name = nullptr; if (arch == EM_386) arch_name = "x86"; else if (arch == EM_X86_64) @@ -609,13 +609,13 @@ class MmapWrapper { base_(mapped_address), size_(mapped_size) { } ~MmapWrapper() { - if (base_ != NULL) { + if (base_ != nullptr) { assert(size_ > 0); munmap((char*)base_, size_); } } void release() { - base_ = NULL; + base_ = nullptr; size_ = 0; } @@ -650,16 +650,16 @@ bool DumpSymbols::WriteSymbolFile(const std::string& obj_file, int sym_fd) { struct stat st; if (fstat(obj_fd, &st) != 0 && st.st_size <= 0) return false; - void* obj_base = mmap(NULL, st.st_size, + void* obj_base = mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, obj_fd, 0); if (obj_base == MAP_FAILED) return false; MmapWrapper map_wrapper(obj_base, st.st_size); GElf_Ehdr elf_header; - Elf* elf = elf_begin(obj_fd, ELF_C_READ, NULL); + Elf* elf = elf_begin(obj_fd, ELF_C_READ, nullptr); AutoElfEnder elfEnder(elf); - if (gelf_getehdr(elf, &elf_header) == (GElf_Ehdr*)NULL) { + if (gelf_getehdr(elf, &elf_header) == (GElf_Ehdr*)nullptr) { fprintf(stderr, "failed to read elf header: %s\n", elf_errmsg(-1)); return false; } diff --git a/src/common/solaris/file_id.cc b/src/common/solaris/file_id.cc index 73b6acc22..9efb2e86d 100644 --- a/src/common/solaris/file_id.cc +++ b/src/common/solaris/file_id.cc @@ -70,7 +70,7 @@ static bool FindElfTextSection(int fd, const void* elf_base, assert(text_start); assert(text_size); - *text_start = NULL; + *text_start = nullptr; *text_size = 0; if (elf_version(EV_CURRENT) == EV_NONE) { @@ -80,10 +80,10 @@ static bool FindElfTextSection(int fd, const void* elf_base, GElf_Ehdr elf_header; lseek(fd, 0L, 0); - Elf* elf = elf_begin(fd, ELF_C_READ, NULL); + Elf* elf = elf_begin(fd, ELF_C_READ, nullptr); AutoElfEnder elfEnder(elf); - if (gelf_getehdr(elf, &elf_header) == (GElf_Ehdr*)NULL) { + if (gelf_getehdr(elf, &elf_header) == (GElf_Ehdr*)nullptr) { print_message2(2, "failed to read elf header: %s\n", elf_errmsg(-1)); return false; } @@ -97,11 +97,11 @@ static bool FindElfTextSection(int fd, const void* elf_base, } static const char kTextSectionName[] = ".text"; - const GElf_Shdr* text_section = NULL; - Elf_Scn* scn = NULL; + const GElf_Shdr* text_section = nullptr; + Elf_Scn* scn = nullptr; GElf_Shdr shdr; - while ((scn = elf_nextscn(elf, scn)) != NULL) { + while ((scn = elf_nextscn(elf, scn)) != nullptr) { if (gelf_getshdr(scn, &shdr) == (GElf_Shdr*)0) { print_message2(2, "failed to read section header: %s\n", elf_errmsg(0)); return false; @@ -121,7 +121,7 @@ static bool FindElfTextSection(int fd, const void* elf_base, } } } - if (text_section != NULL && text_section->sh_size > 0) { + if (text_section != nullptr && text_section->sh_size > 0) { *text_start = (char*)elf_base + text_section->sh_offset; *text_size = text_section->sh_size; return true; @@ -154,12 +154,12 @@ bool FileID::ElfFileIdentifier(unsigned char identifier[16]) { if (fstat(fd, &st) != 0 || st.st_size <= 0) return false; - void* base = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + void* base = mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (base == MAP_FAILED) return false; bool success = false; - const void* text_section = NULL; + const void* text_section = nullptr; int text_size = 0; if (FindElfTextSection(fd, base, &text_section, &text_size)) { diff --git a/src/common/solaris/guid_creator.cc b/src/common/solaris/guid_creator.cc index 2cfe1b7b3..e6f377e88 100644 --- a/src/common/solaris/guid_creator.cc +++ b/src/common/solaris/guid_creator.cc @@ -50,7 +50,7 @@ class GUIDGenerator { public: GUIDGenerator() { - srandom(time(NULL)); + srandom(time(nullptr)); } bool CreateGUID(GUID *guid) const { diff --git a/src/common/stabs_reader.cc b/src/common/stabs_reader.cc index e18780c9d..55f24813c 100644 --- a/src/common/stabs_reader.cc +++ b/src/common/stabs_reader.cc @@ -80,7 +80,7 @@ StabsReader::StabsReader(const uint8_t* stab, size_t stab_size, handler_(handler), string_offset_(0), next_cu_string_offset_(0), - current_source_file_(NULL) { } + current_source_file_(nullptr) { } const char* StabsReader::SymbolString() { ptrdiff_t offset = string_offset_ + iterator_->name_offset; @@ -138,7 +138,7 @@ bool StabsReader::ProcessCompilationUnit() { // There may be an N_SO entry whose name ends with a slash, // indicating the directory in which the compilation occurred. // The build directory defaults to NULL. - const char* build_directory = NULL; + const char* build_directory = nullptr; { const char* name = SymbolString(); if (name[0] && name[strlen(name) - 1] == '/') { diff --git a/src/common/stabs_reader_unittest.cc b/src/common/stabs_reader_unittest.cc index 294e8836a..fe7fb9e07 100644 --- a/src/common/stabs_reader_unittest.cc +++ b/src/common/stabs_reader_unittest.cc @@ -135,7 +135,7 @@ class StabsAssembler: public Section { string_assembler_(string_assembler), value_size_(0), entry_count_(0), - cu_header_(NULL) { } + cu_header_(nullptr) { } ~StabsAssembler() { assert(!cu_header_); } // Accessor and setter for value_size_. @@ -188,7 +188,7 @@ class StabsAssembler: public Section { cu_header_->final_entry_count = entry_count_; cu_header_->final_string_size = string_assembler_->EndCU(); delete cu_header_; - cu_header_ = NULL; + cu_header_ = nullptr; return *this; } @@ -320,7 +320,7 @@ TEST_F(Stabs, MockStabsInput) { EXPECT_CALL(mock_handler, EndCompilationUnit(0xd04b7448U)) .WillOnce(Return(true)); EXPECT_CALL(mock_handler, StartCompilationUnit(StrEq("file3.c"), - 0x11759f10U, NULL)) + 0x11759f10U, nullptr)) .WillOnce(Return(true)); EXPECT_CALL(mock_handler, EndCompilationUnit(0x11cfe4b5U)) .WillOnce(Return(true)); @@ -338,7 +338,7 @@ TEST_F(Stabs, AbruptCU) { InSequence s; EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("file2-1.c"), 0xbf10d5e4, NULL)) + StartCompilationUnit(StrEq("file2-1.c"), 0xbf10d5e4, nullptr)) .WillOnce(Return(true)); EXPECT_CALL(mock_handler, EndCompilationUnit(0)) .WillOnce(Return(true)); @@ -358,7 +358,7 @@ TEST_F(Stabs, AbruptFunction) { InSequence s; EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("file3-1.c"), 0xb83ddf10U, NULL)) + StartCompilationUnit(StrEq("file3-1.c"), 0xb83ddf10U, nullptr)) .WillOnce(Return(true)); EXPECT_CALL(mock_handler, StartFunction(StrEq("fun3_1"), 0xbbd4a145U)) .WillOnce(Return(true)); @@ -395,12 +395,12 @@ TEST_F(Stabs, NoCUEnd) { InSequence s; EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("file5-1.c"), 0x2f7493c9U, NULL)) + StartCompilationUnit(StrEq("file5-1.c"), 0x2f7493c9U, nullptr)) .WillOnce(Return(true)); EXPECT_CALL(mock_handler, EndCompilationUnit(0)) .WillOnce(Return(true)); EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("file5-2.c"), 0xf9f1d50fU, NULL)) + StartCompilationUnit(StrEq("file5-2.c"), 0xf9f1d50fU, nullptr)) .WillOnce(Return(true)); EXPECT_CALL(mock_handler, EndCompilationUnit(0)) .WillOnce(Return(true)); @@ -430,7 +430,7 @@ TEST_F(Stabs, Unitized) { { InSequence s; EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("antimony"), 0x7e259f1aU, NULL)) + StartCompilationUnit(StrEq("antimony"), 0x7e259f1aU, nullptr)) .WillOnce(Return(true)); EXPECT_CALL(mock_handler, StartFunction(Eq("arsenic"), 0x7fbcccaeU)) .WillOnce(Return(true)); @@ -439,7 +439,7 @@ TEST_F(Stabs, Unitized) { EXPECT_CALL(mock_handler, EndCompilationUnit(0x80b0014cU)) .WillOnce(Return(true)); EXPECT_CALL(mock_handler, - StartCompilationUnit(StrEq("aluminum"), 0x86756839U, NULL)) + StartCompilationUnit(StrEq("aluminum"), 0x86756839U, nullptr)) .WillOnce(Return(true)); EXPECT_CALL(mock_handler, StartFunction(Eq("selenium"), 0xa8e120b0U)) .WillOnce(Return(true)); @@ -469,7 +469,7 @@ TEST_F(Stabs, NonUnitized) { InSequence s; EXPECT_CALL(mock_handler, StartCompilationUnit(StrEq("Tanzania"), - 0x11a97352, NULL)) + 0x11a97352, nullptr)) .WillOnce(Return(true)); EXPECT_CALL(mock_handler, EndCompilationUnit(0x21a97352)) .WillOnce(Return(true)); @@ -497,7 +497,7 @@ TEST_F(Stabs, FunctionEnd) { InSequence s; EXPECT_CALL(mock_handler, StartCompilationUnit(StrEq("compilation unit"), - 0x52a830d644cd6942ULL, NULL)) + 0x52a830d644cd6942ULL, nullptr)) .WillOnce(Return(true)); EXPECT_CALL(mock_handler, StartFunction(Eq("function 1"), 0xbb5ab70ecdd23bfeULL)) diff --git a/src/common/stabs_to_module.cc b/src/common/stabs_to_module.cc index f04c987ad..05982b941 100644 --- a/src/common/stabs_to_module.cc +++ b/src/common/stabs_to_module.cc @@ -52,8 +52,9 @@ namespace google_breakpad { // Older GCC may not support it. static string Demangle(const string& mangled) { int status = 0; - char *demangled = abi::__cxa_demangle(mangled.c_str(), NULL, NULL, &status); - if (status == 0 && demangled != NULL) { + char *demangled = abi::__cxa_demangle( + mangled.c_str(), nullptr, nullptr, &status); + if (status == 0 && demangled != nullptr) { string str(demangled); free(demangled); return str; @@ -85,8 +86,8 @@ bool StabsToModule::EndCompilationUnit(uint64_t address) { assert(in_compilation_unit_); in_compilation_unit_ = false; comp_unit_base_address_ = 0; - current_source_file_ = NULL; - current_source_file_name_ = NULL; + current_source_file_ = nullptr; + current_source_file_name_ = nullptr; if (address) boundaries_.push_back(static_cast(address)); return true; @@ -115,7 +116,7 @@ bool StabsToModule::EndFunction(uint64_t address) { functions_.push_back(current_function_); else delete current_function_; - current_function_ = NULL; + current_function_ = nullptr; if (address) boundaries_.push_back(static_cast(address)); return true; diff --git a/src/common/stabs_to_module.h b/src/common/stabs_to_module.h index 99c61b0c9..e384e66f4 100644 --- a/src/common/stabs_to_module.h +++ b/src/common/stabs_to_module.h @@ -66,9 +66,9 @@ class StabsToModule: public google_breakpad::StabsHandler { module_(module), in_compilation_unit_(false), comp_unit_base_address_(0), - current_function_(NULL), - current_source_file_(NULL), - current_source_file_name_(NULL) { } + current_function_(nullptr), + current_source_file_(nullptr), + current_source_file_name_(nullptr) { } ~StabsToModule(); // The standard StabsHandler virtual member functions. diff --git a/src/common/stabs_to_module_unittest.cc b/src/common/stabs_to_module_unittest.cc index c6d40281b..3befb51c2 100644 --- a/src/common/stabs_to_module_unittest.cc +++ b/src/common/stabs_to_module_unittest.cc @@ -59,7 +59,7 @@ TEST(StabsToModule, SimpleCU) { // Now check to see what has been added to the Module. Module::File *file = m.FindExistingFile("source-file-name"); - ASSERT_TRUE(file != NULL); + ASSERT_TRUE(file != nullptr); vector functions; m.GetFunctions(&functions, functions.end()); @@ -125,7 +125,7 @@ TEST(StabsToModule, DuplicateFunctionNames) { // Now check to see what has been added to the Module. Module::File *file = m.FindExistingFile("compilation-unit"); - ASSERT_TRUE(file != NULL); + ASSERT_TRUE(file != nullptr); vector functions; m.GetFunctions(&functions, functions.end()); @@ -158,9 +158,9 @@ TEST(InferSizes, LineSize) { // Now check to see what has been added to the Module. Module::File *file1 = m.FindExistingFile("source-file-name-1"); - ASSERT_TRUE(file1 != NULL); + ASSERT_TRUE(file1 != nullptr); Module::File *file2 = m.FindExistingFile("source-file-name-2"); - ASSERT_TRUE(file2 != NULL); + ASSERT_TRUE(file2 != nullptr); vector functions; m.GetFunctions(&functions, functions.end()); @@ -205,7 +205,7 @@ TEST(FunctionNames, Mangled) { // Now check to see what has been added to the Module. Module::File *file = m.FindExistingFile("compilation-unit"); - ASSERT_TRUE(file != NULL); + ASSERT_TRUE(file != nullptr); vector functions; m.GetFunctions(&functions, functions.end()); diff --git a/src/common/test_assembler.cc b/src/common/test_assembler.cc index 6b1c1fd35..00b2fd0a1 100644 --- a/src/common/test_assembler.cc +++ b/src/common/test_assembler.cc @@ -58,7 +58,7 @@ Label::~Label() { } Label& Label::operator=(uint64_t value) { - value_->Set(NULL, value); + value_->Set(nullptr, value); return *this; } @@ -108,7 +108,7 @@ bool Label::IsKnownConstant(uint64_t* value_p) const { Binding* base; uint64_t addend; value_->Get(&base, &addend); - if (base != NULL) return false; + if (base != nullptr) return false; if (value_p) *value_p = addend; return true; } @@ -130,7 +130,7 @@ bool Label::IsKnownOffsetFrom(const Label& label, uint64_t* offset_p) const Label::Binding::Binding() : base_(this), addend_(), reference_count_(1) { } Label::Binding::Binding(uint64_t addend) - : base_(NULL), addend_(addend), reference_count_(1) { } + : base_(nullptr), addend_(addend), reference_count_(1) { } Label::Binding::~Binding() { assert(reference_count_ == 0); @@ -145,7 +145,7 @@ void Label::Binding::Set(Binding* binding, uint64_t addend) { } else if (!base_) { // We are a known constant, but BINDING may not be, so turn the // tables and try to set BINDING's value instead. - binding->Set(NULL, addend_ - addend); + binding->Set(nullptr, addend_ - addend); } else { if (binding) { // Find binding's final value. Since the final value is always either diff --git a/src/common/test_assembler.h b/src/common/test_assembler.h index 809c7b21d..4d40b50dd 100644 --- a/src/common/test_assembler.h +++ b/src/common/test_assembler.h @@ -134,7 +134,7 @@ class Label { // Return true if this label's value is known. If VALUE_P is given, // set *VALUE_P to the known value if returning true. - bool IsKnownConstant(uint64_t* value_p = NULL) const; + bool IsKnownConstant(uint64_t* value_p = nullptr) const; // Return true if the offset from LABEL to this label is known. If // OFFSET_P is given, set *OFFSET_P to the offset when returning true. @@ -154,7 +154,8 @@ class Label { // l-m // -10 // m-l // 10 // m.Value() // error: m's value is not known - bool IsKnownOffsetFrom(const Label& label, uint64_t* offset_p = NULL) const; + bool IsKnownOffsetFrom(const Label& label, + uint64_t* offset_p = nullptr) const; private: // A label's value, or if that is not yet known, how the value is diff --git a/src/common/tests/auto_tempdir.h b/src/common/tests/auto_tempdir.h index 963c2dcf4..d7b583e1a 100644 --- a/src/common/tests/auto_tempdir.h +++ b/src/common/tests/auto_tempdir.h @@ -52,7 +52,7 @@ class AutoTempDir { public: AutoTempDir() { char temp_dir[] = TEMPDIR "/breakpad.XXXXXX"; - EXPECT_TRUE(mkdtemp(temp_dir) != NULL); + EXPECT_TRUE(mkdtemp(temp_dir) != nullptr); path_.assign(temp_dir); } @@ -72,7 +72,7 @@ class AutoTempDir { return; dirent* entry; - while ((entry = readdir(dir)) != NULL) { + while ((entry = readdir(dir)) != nullptr) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; string entry_path = path + "/" + entry->d_name; diff --git a/src/common/windows/dia_util.cc b/src/common/windows/dia_util.cc index a5d984d1a..631e389d5 100644 --- a/src/common/windows/dia_util.cc +++ b/src/common/windows/dia_util.cc @@ -81,7 +81,7 @@ bool FindTable(REFIID iid, IDiaSession* session, void** table) { ULONG fetched = 0; while (SUCCEEDED(enum_tables->Next(1, &temp_table, &fetched)) && fetched == 1) { - void* temp = NULL; + void* temp = nullptr; if (SUCCEEDED(temp_table->QueryInterface(iid, &temp))) { *table = temp; return true; diff --git a/src/common/windows/http_upload.cc b/src/common/windows/http_upload.cc index c6d00bd0b..76363398b 100644 --- a/src/common/windows/http_upload.cc +++ b/src/common/windows/http_upload.cc @@ -139,7 +139,8 @@ namespace { } // compute the length of the buffer we'll need - int charcount = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, NULL, 0); + int charcount = MultiByteToWideChar( + CP_UTF8, 0, utf8.c_str(), -1, nullptr, 0); if (charcount == 0) { return wstring(); @@ -160,7 +161,7 @@ namespace { // compute the length of the buffer we'll need int charcount = WideCharToMultiByte(cp, 0, wide.c_str(), -1, - NULL, 0, NULL, NULL); + nullptr, 0, nullptr, nullptr); if (charcount == 0) { return string(); } @@ -168,7 +169,7 @@ namespace { // convert char *buf = new char[charcount]; WideCharToMultiByte(cp, 0, wide.c_str(), -1, buf, charcount, - NULL, NULL); + nullptr, nullptr); string result(buf); delete[] buf; @@ -279,7 +280,7 @@ namespace { static_cast(&content_length), &content_length_size, 0)) { has_content_length_header = true; - claimed_size = wcstol(content_length, NULL, 10); + claimed_size = wcstol(content_length, nullptr, 10); response_body.reserve(claimed_size); } else { DWORD error = ::GetLastError(); @@ -361,8 +362,8 @@ namespace { AutoInternetHandle internet(InternetOpen(kUserAgent, INTERNET_OPEN_TYPE_PRECONFIG, - NULL, // proxy name - NULL, // proxy bypass + nullptr, // proxy name + nullptr, // proxy bypass 0)); // flags if (!internet.get()) { LogError("InternetOpen", ::GetLastError()); @@ -372,8 +373,8 @@ namespace { AutoInternetHandle connection(InternetConnect(internet.get(), host, components.nPort, - NULL, // user name - NULL, // password + nullptr, // user name + nullptr, // password INTERNET_SERVICE_HTTP, 0, // flags 0)); // context @@ -387,9 +388,9 @@ namespace { AutoInternetHandle request(HttpOpenRequest(connection.get(), http_method.c_str(), path, - NULL, // version - NULL, // referer - NULL, // agent type + nullptr, // version + nullptr, // referer + nullptr, // agent type http_open_flags, 0)); // context if (!request.get()) { @@ -422,7 +423,7 @@ namespace { } } - if (!HttpSendRequest(request.get(), NULL, 0, + if (!HttpSendRequest(request.get(), nullptr, 0, const_cast(request_body.data()), static_cast(request_body.size()))) { LogError("HttpSendRequest", ::GetLastError()); @@ -439,7 +440,7 @@ namespace { return false; } - int http_response = wcstol(http_status, NULL, 10); + int http_response = wcstol(http_status, nullptr, 10); if (response_code) { *response_code = http_response; } diff --git a/src/common/windows/omap.cc b/src/common/windows/omap.cc index e707e1268..12d1a2f15 100644 --- a/src/common/windows/omap.cc +++ b/src/common/windows/omap.cc @@ -174,14 +174,14 @@ bool EndpointIndexLess(const EndpointIndex& ei1, const EndpointIndex& ei2) { bool FindAndLoadOmapTable(const wchar_t* name, IDiaSession* session, OmapTable* table) { - assert(name != NULL); - assert(session != NULL); - assert(table != NULL); + assert(name != nullptr); + assert(session != nullptr); + assert(table != nullptr); CComPtr stream; if (!FindDebugStream(name, session, &stream)) return false; - assert(stream.p != NULL); + assert(stream.p != nullptr); LONG count = 0; if (FAILED(stream->get_Count(&count))) { @@ -193,7 +193,7 @@ bool FindAndLoadOmapTable(const wchar_t* name, // Get the length of the stream in bytes. DWORD bytes_read = 0; ULONG count_read = 0; - if (FAILED(stream->Next(count, 0, &bytes_read, NULL, &count_read))) { + if (FAILED(stream->Next(count, 0, &bytes_read, nullptr, &count_read))) { fprintf(stderr, "IDiaEnumDebugStreamData::Next failed while reading " "length of stream \"%ws\"\n", name); return false; @@ -224,20 +224,20 @@ bool FindAndLoadOmapTable(const wchar_t* name, // This determines the original image length by looking through the segment // table. bool GetOriginalImageLength(IDiaSession* session, DWORD* image_length) { - assert(session != NULL); - assert(image_length != NULL); + assert(session != nullptr); + assert(image_length != nullptr); CComPtr enum_segments; if (!FindTable(session, &enum_segments)) return false; - assert(enum_segments.p != NULL); + assert(enum_segments.p != nullptr); DWORD temp_image_length = 0; CComPtr segment; ULONG fetched = 0; while (SUCCEEDED(enum_segments->Next(1, &segment, &fetched)) && fetched == 1) { - assert(segment.p != NULL); + assert(segment.p != nullptr); DWORD rva = 0; DWORD length = 0; @@ -266,7 +266,7 @@ bool GetOriginalImageLength(IDiaSession* session, DWORD* image_length) { // immediately preceding a gap. The mapped ranges must be sorted by // 'rva_original'. void FillInRemovedLengths(Mapping* mapping) { - assert(mapping != NULL); + assert(mapping != nullptr); // Find and fill gaps. We do this with two sweeps. We first sweep forward // looking for gaps. When we identify a gap we then sweep forward with a @@ -319,7 +319,7 @@ void FillInRemovedLengths(Mapping* mapping) { // Builds a unified view of the mapping between the original and transformed // image space by merging OMAPTO and OMAPFROM data. void BuildMapping(const OmapData& omap_data, Mapping* mapping) { - assert(mapping != NULL); + assert(mapping != nullptr); mapping->clear(); @@ -407,7 +407,7 @@ void BuildMapping(const OmapData& omap_data, Mapping* mapping) { } void BuildEndpointIndexMap(ImageMap* image_map) { - assert(image_map != NULL); + assert(image_map != nullptr); if (image_map->mapping.size() == 0) return; @@ -477,7 +477,7 @@ void BuildSubsequentRVAMap(const OmapData& omap_data, // Clips the given mapped range. void ClipMappedRangeOriginal(const AddressRange& clip_range, MappedRange* mapped_range) { - assert(mapped_range != NULL); + assert(mapped_range != nullptr); // The clipping range is entirely outside of the mapped range. if (clip_range.end() <= mapped_range->rva_original || @@ -547,15 +547,15 @@ int AddressRange::Compare(const AddressRange& rhs) const { bool GetOmapDataAndDisableTranslation(IDiaSession* session, OmapData* omap_data) { - assert(session != NULL); - assert(omap_data != NULL); + assert(session != nullptr); + assert(omap_data != nullptr); CComPtr address_map; if (FAILED(session->QueryInterface(&address_map))) { fprintf(stderr, "IDiaSession::QueryInterface(IDiaAddressMap) failed\n"); return false; } - assert(address_map.p != NULL); + assert(address_map.p != nullptr); BOOL omap_enabled = FALSE; if (FAILED(address_map->get_addressMapEnabled(&omap_enabled))) { @@ -597,7 +597,7 @@ bool GetOmapDataAndDisableTranslation(IDiaSession* session, } void BuildImageMap(const OmapData& omap_data, ImageMap* image_map) { - assert(image_map != NULL); + assert(image_map != nullptr); BuildMapping(omap_data, &image_map->mapping); BuildEndpointIndexMap(image_map); @@ -607,7 +607,7 @@ void BuildImageMap(const OmapData& omap_data, ImageMap* image_map) { void MapAddressRange(const ImageMap& image_map, const AddressRange& original_range, AddressRangeVector* mapped_ranges) { - assert(mapped_ranges != NULL); + assert(mapped_ranges != nullptr); const Mapping& map = image_map.mapping; diff --git a/src/common/windows/pdb_source_line_writer.cc b/src/common/windows/pdb_source_line_writer.cc index 86f01a798..7ae978c7d 100644 --- a/src/common/windows/pdb_source_line_writer.cc +++ b/src/common/windows/pdb_source_line_writer.cc @@ -401,7 +401,7 @@ void PDBSourceLineWriter::Lines::AddLine(const Line& line) { } PDBSourceLineWriter::PDBSourceLineWriter(bool handle_inline) - : output_(NULL), handle_inline_(handle_inline) {} + : output_(nullptr), handle_inline_(handle_inline) {} PDBSourceLineWriter::~PDBSourceLineWriter() { Close(); @@ -421,7 +421,7 @@ bool PDBSourceLineWriter::Open(const wstring& file, FileFormat format) { Close(); code_file_.clear(); - if (FAILED(CoInitialize(NULL))) { + if (FAILED(CoInitialize(nullptr))) { fprintf(stderr, "CoInitialize failed\n"); return false; } @@ -448,7 +448,7 @@ bool PDBSourceLineWriter::Open(const wstring& file, FileFormat format) { } break; case EXE_FILE: - for_exe_result = data_source->loadDataForExe(file_name, NULL, NULL); + for_exe_result = data_source->loadDataForExe(file_name, nullptr, nullptr); if (FAILED(for_exe_result)) { PrintOpenError(for_exe_result, "loadDataForExe", file_name); return false; @@ -458,7 +458,8 @@ bool PDBSourceLineWriter::Open(const wstring& file, FileFormat format) { case ANY_FILE: from_pdb_result = data_source->loadDataFromPdb(file_name); if (FAILED(from_pdb_result)) { - for_exe_result = data_source->loadDataForExe(file_name, NULL, NULL); + for_exe_result = data_source->loadDataForExe( + file_name, nullptr, nullptr); if (FAILED(for_exe_result)) { PrintOpenError(from_pdb_result, "loadDataFromPdb", file_name); PrintOpenError(for_exe_result, "loadDataForExe", file_name); @@ -631,7 +632,7 @@ bool PDBSourceLineWriter::PrintSourceFiles() { } CComPtr compilands; - if (FAILED(global->findChildren(SymTagCompiland, NULL, + if (FAILED(global->findChildren(SymTagCompiland, nullptr, nsNone, &compilands))) { fprintf(stderr, "findChildren failed\n"); return false; @@ -645,7 +646,7 @@ bool PDBSourceLineWriter::PrintSourceFiles() { ULONG count; while (SUCCEEDED(compilands->Next(1, &compiland, &count)) && count == 1) { CComPtr source_files; - if (FAILED(session_->findFile(compiland, NULL, nsNone, &source_files))) { + if (FAILED(session_->findFile(compiland, nullptr, nsNone, &source_files))) { return false; } CComPtr file; @@ -688,14 +689,14 @@ bool PDBSourceLineWriter::PrintFunctions() { return false; } - CComPtr symbols = NULL; + CComPtr symbols = nullptr; // Find all function symbols first. SymbolMap rva_symbol; - hr = global->findChildren(SymTagFunction, NULL, nsNone, &symbols); + hr = global->findChildren(SymTagFunction, nullptr, nsNone, &symbols); if (SUCCEEDED(hr)) { - CComPtr symbol = NULL; + CComPtr symbol = nullptr; while (SUCCEEDED(symbols->Next(1, &symbol, &count)) && count == 1) { if (SUCCEEDED(symbol->get_relativeVirtualAddress(&rva))) { @@ -714,10 +715,10 @@ bool PDBSourceLineWriter::PrintFunctions() { // Find all public symbols and record public symbols that are not also private // symbols. - hr = global->findChildren(SymTagPublicSymbol, NULL, nsNone, &symbols); + hr = global->findChildren(SymTagPublicSymbol, nullptr, nsNone, &symbols); if (SUCCEEDED(hr)) { - CComPtr symbol = NULL; + CComPtr symbol = nullptr; while (SUCCEEDED(symbols->Next(1, &symbol, &count)) && count == 1) { if (SUCCEEDED(symbol->get_relativeVirtualAddress(&rva))) { @@ -756,7 +757,7 @@ bool PDBSourceLineWriter::PrintFunctions() { // of those blocks and print out an extra FUNC line for blocks // that are not contained in their parent functions. CComPtr compilands; - if (FAILED(global->findChildren(SymTagCompiland, NULL, + if (FAILED(global->findChildren(SymTagCompiland, nullptr, nsNone, &compilands))) { fprintf(stderr, "findChildren failed on the global\n"); return false; @@ -765,7 +766,7 @@ bool PDBSourceLineWriter::PrintFunctions() { CComPtr compiland; while (SUCCEEDED(compilands->Next(1, &compiland, &count)) && count == 1) { CComPtr blocks; - if (FAILED(compiland->findChildren(SymTagBlock, NULL, + if (FAILED(compiland->findChildren(SymTagBlock, nullptr, nsNone, &blocks))) { fprintf(stderr, "findChildren failed on a compiland\n"); return false; @@ -1100,7 +1101,7 @@ bool PDBSourceLineWriter::PrintCodePublicSymbol(IDiaSymbol* symbol, if (rva == 0) break; - CComPtr next_sym = NULL; + CComPtr next_sym = nullptr; LONG displacement; if (FAILED(session_->findSymbolByRVAEx(rva, SymTagPublicSymbol, &next_sym, &displacement))) { @@ -1309,7 +1310,7 @@ int PDBSourceLineWriter::GetFunctionStackParamSize(IDiaSymbol* function) { // Gather the symbols corresponding to data. CComPtr data_children; - if (FAILED(function->findChildren(SymTagData, NULL, nsNone, + if (FAILED(function->findChildren(SymTagData, nullptr, nsNone, &data_children))) { return 0; } @@ -1435,7 +1436,7 @@ bool PDBSourceLineWriter::WriteSymbols(FILE* symbol_file) { ret = ret && PrintSourceFiles() && PrintFunctions() && PrintFrameData(); PrintInlineOrigins(); - output_ = NULL; + output_ = nullptr; return ret; } diff --git a/src/common/windows/pe_util.cc b/src/common/windows/pe_util.cc index 2d4aebe79..4af88a4ba 100644 --- a/src/common/windows/pe_util.cc +++ b/src/common/windows/pe_util.cc @@ -140,7 +140,7 @@ bool ReadModuleInfo(const wstring & pe_file, PDBModuleInfo * info) { return false; } - AutoImage img(ImageLoad((PSTR)img_file.c_str(), NULL)); + AutoImage img(ImageLoad((PSTR)img_file.c_str(), nullptr)); if (!img) { fprintf(stderr, "Failed to load %s\n", img_file.c_str()); return false; @@ -214,7 +214,7 @@ bool ReadPEInfo(const wstring & pe_file, PEModuleInfo * info) { return false; } - AutoImage img(ImageLoad((PSTR)img_file.c_str(), NULL)); + AutoImage img(ImageLoad((PSTR)img_file.c_str(), nullptr)); if (!img) { fprintf(stderr, "Failed to open PE file: %S\n", pe_file.c_str()); return false; @@ -256,7 +256,7 @@ bool PrintPEFrameData(const wstring & pe_file, FILE * out_file) return false; } - AutoImage img(ImageLoad((PSTR)img_file.c_str(), NULL)); + AutoImage img(ImageLoad((PSTR)img_file.c_str(), nullptr)); if (!img) { fprintf(stderr, "Failed to load %s\n", img_file.c_str()); return false; @@ -366,7 +366,7 @@ bool PrintPEFrameData(const wstring & pe_file, FILE * out_file) &img->LastRvaSection)); } else { - unwind_info = NULL; + unwind_info = nullptr; } } while (unwind_info); fprintf(out_file, "STACK CFI INIT %lx %lx .cfa: $rsp .ra: .cfa %lu - ^\n", diff --git a/src/common/windows/string_utils.cc b/src/common/windows/string_utils.cc index 46d530ecf..032131208 100644 --- a/src/common/windows/string_utils.cc +++ b/src/common/windows/string_utils.cc @@ -57,13 +57,14 @@ bool WindowsStringUtils::safe_mbstowcs(const string& mbs, wstring* wcs) { size_t wcs_length; #if _MSC_VER >= 1400 // MSVC 2005/8 - errno_t err; - if ((err = mbstowcs_s(&wcs_length, NULL, 0, mbs.c_str(), _TRUNCATE)) != 0) { + errno_t err = mbstowcs_s(&wcs_length, nullptr, 0, mbs.c_str(), _TRUNCATE); + if (err != 0) { return false; } assert(wcs_length > 0); #else // _MSC_VER >= 1400 - if ((wcs_length = mbstowcs(NULL, mbs.c_str(), mbs.length())) == (size_t)-1) { + wcs_length = mbstowcs(nullptr, mbs.c_str(), mbs.length()); + if (wcs_length == (size_t)-1) { return false; } @@ -75,7 +76,7 @@ bool WindowsStringUtils::safe_mbstowcs(const string& mbs, wstring* wcs) { // Now, convert. #if _MSC_VER >= 1400 // MSVC 2005/8 - if ((err = mbstowcs_s(NULL, &wcs_v[0], wcs_length, mbs.c_str(), + if ((err = mbstowcs_s(nullptr, &wcs_v[0], wcs_length, mbs.c_str(), _TRUNCATE)) != 0) { return false; } @@ -100,13 +101,14 @@ bool WindowsStringUtils::safe_wcstombs(const wstring& wcs, string* mbs) { size_t mbs_length; #if _MSC_VER >= 1400 // MSVC 2005/8 - errno_t err; - if ((err = wcstombs_s(&mbs_length, NULL, 0, wcs.c_str(), _TRUNCATE)) != 0) { + errno_t err = wcstombs_s(&mbs_length, nullptr, 0, wcs.c_str(), _TRUNCATE); + if (err != 0) { return false; } assert(mbs_length > 0); #else // _MSC_VER >= 1400 - if ((mbs_length = wcstombs(NULL, wcs.c_str(), wcs.length())) == (size_t)-1) { + mbs_length = wcstombs(nullptr, wcs.c_str(), wcs.length()); + if (mbs_length == (size_t)-1) { return false; } @@ -118,7 +120,7 @@ bool WindowsStringUtils::safe_wcstombs(const wstring& wcs, string* mbs) { // Now, convert. #if _MSC_VER >= 1400 // MSVC 2005/8 - if ((err = wcstombs_s(NULL, &mbs_v[0], mbs_length, wcs.c_str(), + if ((err = wcstombs_s(nullptr, &mbs_v[0], mbs_length, wcs.c_str(), _TRUNCATE)) != 0) { return false; } diff --git a/src/google_breakpad/processor/code_modules.h b/src/google_breakpad/processor/code_modules.h index 7538328bd..b7f726760 100644 --- a/src/google_breakpad/processor/code_modules.h +++ b/src/google_breakpad/processor/code_modules.h @@ -34,8 +34,6 @@ #ifndef GOOGLE_BREAKPAD_PROCESSOR_CODE_MODULES_H__ #define GOOGLE_BREAKPAD_PROCESSOR_CODE_MODULES_H__ -#include - #include #include "google_breakpad/common/breakpad_types.h" diff --git a/src/google_breakpad/processor/process_state.h b/src/google_breakpad/processor/process_state.h index cc0e83a5d..50f3d5889 100644 --- a/src/google_breakpad/processor/process_state.h +++ b/src/google_breakpad/processor/process_state.h @@ -91,7 +91,7 @@ enum ExploitabilityRating { class ProcessState { public: - ProcessState() : modules_(NULL), unloaded_modules_(NULL) { Clear(); } + ProcessState() : modules_(nullptr), unloaded_modules_(nullptr) { Clear(); } ~ProcessState(); // Resets the ProcessState to its default values diff --git a/src/google_breakpad/processor/stack_frame.h b/src/google_breakpad/processor/stack_frame.h index eebe06e6a..5960f89b4 100644 --- a/src/google_breakpad/processor/stack_frame.h +++ b/src/google_breakpad/processor/stack_frame.h @@ -59,7 +59,7 @@ struct StackFrame { StackFrame() : instruction(), - module(NULL), + module(nullptr), function_name(), function_base(), source_file_name(), diff --git a/src/google_breakpad/processor/stack_frame_cpu.h b/src/google_breakpad/processor/stack_frame_cpu.h index 91f1d0cb1..086a6f5a4 100644 --- a/src/google_breakpad/processor/stack_frame_cpu.h +++ b/src/google_breakpad/processor/stack_frame_cpu.h @@ -72,8 +72,8 @@ struct StackFrameX86 : public StackFrame { StackFrameX86() : context(), context_validity(CONTEXT_VALID_NONE), - windows_frame_info(NULL), - cfi_frame_info(NULL) {} + windows_frame_info(nullptr), + cfi_frame_info(nullptr) {} ~StackFrameX86(); // Overriden to return the return address as saved on the stack. diff --git a/src/processor/address_map_unittest.cc b/src/processor/address_map_unittest.cc index 2d754b602..6ea811257 100644 --- a/src/processor/address_map_unittest.cc +++ b/src/processor/address_map_unittest.cc @@ -111,7 +111,7 @@ static bool DoAddressMapTest() { ASSERT_EQ(entry->id(), 1); ASSERT_EQ(address, 10); ASSERT_TRUE(test_map.Retrieve(11, &entry, &address)); - ASSERT_TRUE(test_map.Retrieve(11, &entry, NULL)); // NULL ok here + ASSERT_TRUE(test_map.Retrieve(11, &entry, nullptr)); // nullptr ok here // Add some more elements. ASSERT_TRUE(test_map.Store(5, diff --git a/src/processor/basic_code_modules.cc b/src/processor/basic_code_modules.cc index bdfc8f3de..23008c3fa 100644 --- a/src/processor/basic_code_modules.cc +++ b/src/processor/basic_code_modules.cc @@ -83,7 +83,8 @@ BasicCodeModules::BasicCodeModules(const CodeModules* that, linked_ptr module(that->GetModuleAtIndex(i)->Copy()); uint64_t delta = 0; if (map_.RetrieveRange(module->base_address() + module->size() - 1, - &module, NULL /* base */, &delta, NULL /* size */) && + &module, nullptr /* base */, &delta, + nullptr /* size */) && delta > 0) { BPLOG(INFO) << "The range for module " << module->code_file() << " was shrunk down by " << HexString(delta) << " bytes."; @@ -109,10 +110,10 @@ unsigned int BasicCodeModules::module_count() const { const CodeModule* BasicCodeModules::GetModuleForAddress( uint64_t address) const { linked_ptr module; - if (!map_.RetrieveRange(address, &module, NULL /* base */, NULL /* delta */, - NULL /* size */)) { + if (!map_.RetrieveRange(address, &module, nullptr /* base */, + nullptr /* delta */, nullptr /* size */)) { BPLOG(INFO) << "No module at " << HexString(address); - return NULL; + return nullptr; } return module.get(); @@ -125,10 +126,10 @@ const CodeModule* BasicCodeModules::GetMainModule() const { const CodeModule* BasicCodeModules::GetModuleAtSequence( unsigned int sequence) const { linked_ptr module; - if (!map_.RetrieveRangeAtIndex(sequence, &module, NULL /* base */, - NULL /* delta */, NULL /* size */)) { + if (!map_.RetrieveRangeAtIndex(sequence, &module, nullptr /* base */, + nullptr /* delta */, nullptr /* size */)) { BPLOG(ERROR) << "RetrieveRangeAtIndex failed for sequence " << sequence; - return NULL; + return nullptr; } return module.get(); diff --git a/src/processor/basic_code_modules.h b/src/processor/basic_code_modules.h index e9d58f6b0..2eaf49ecc 100644 --- a/src/processor/basic_code_modules.h +++ b/src/processor/basic_code_modules.h @@ -40,8 +40,6 @@ #ifndef PROCESSOR_BASIC_CODE_MODULES_H__ #define PROCESSOR_BASIC_CODE_MODULES_H__ -#include - #include #include "google_breakpad/processor/code_modules.h" diff --git a/src/processor/basic_source_line_resolver.cc b/src/processor/basic_source_line_resolver.cc index 43128e7b7..20037b1a7 100644 --- a/src/processor/basic_source_line_resolver.cc +++ b/src/processor/basic_source_line_resolver.cc @@ -170,7 +170,7 @@ bool BasicSourceLineResolver::Module::LoadMapFromMemory( char* buffer; buffer = strtok_r(memory_buffer, "\r\n", &save_ptr); - while (buffer != NULL) { + while (buffer != nullptr) { ++line_number; if (strncmp(buffer, "FILE ", 5) == 0) { @@ -237,7 +237,7 @@ bool BasicSourceLineResolver::Module::LoadMapFromMemory( if (num_errors > kMaxErrorsBeforeBailing) { break; } - buffer = strtok_r(NULL, "\r\n", &save_ptr); + buffer = strtok_r(nullptr, "\r\n", &save_ptr); } is_corrupt_ = num_errors > 0; return true; @@ -318,7 +318,7 @@ void BasicSourceLineResolver::Module::LookupAddress( MemAddr function_size; MemAddr public_address; if (functions_.RetrieveNearestRange(address, &func, &function_base, - NULL /* delta */, &function_size) && + nullptr /* delta */, &function_size) && address >= function_base && address - function_base < function_size) { frame->function_name = func->name; frame->function_base = frame->module->base_address() + function_base; @@ -326,8 +326,8 @@ void BasicSourceLineResolver::Module::LookupAddress( linked_ptr line; MemAddr line_base; - if (func->lines.RetrieveRange(address, &line, &line_base, NULL /* delta */, - NULL /* size */)) { + if (func->lines.RetrieveRange(address, &line, &line_base, + nullptr /* delta */, nullptr /* size */)) { FileMap::const_iterator it = files_.find(line->source_file_id); if (it != files_.end()) { frame->source_file_name = files_.find(line->source_file_id)->second; @@ -379,7 +379,7 @@ WindowsFrameInfo* BasicSourceLineResolver::Module::FindWindowsFrameInfo( linked_ptr function; MemAddr function_base, function_size; if (functions_.RetrieveNearestRange(address, &function, &function_base, - NULL /* delta */, &function_size) && + nullptr /* delta */, &function_size) && address >= function_base && address - function_base < function_size) { result->parameter_size = function->parameter_size; result->valid |= WindowsFrameInfo::VALID_PARAMETER_SIZE; @@ -395,7 +395,7 @@ WindowsFrameInfo* BasicSourceLineResolver::Module::FindWindowsFrameInfo( result->parameter_size = public_symbol->parameter_size; } - return NULL; + return nullptr; } CFIFrameInfo* BasicSourceLineResolver::Module::FindCFIFrameInfo( @@ -409,15 +409,15 @@ CFIFrameInfo* BasicSourceLineResolver::Module::FindCFIFrameInfo( // forward from the initial rule's starting address to frame's // instruction address, applying delta rules. if (!cfi_initial_rules_.RetrieveRange(address, &initial_rules, &initial_base, - NULL /* delta */, &initial_size)) { - return NULL; + nullptr /* delta */, &initial_size)) { + return nullptr; } // Create a frame info structure, and populate it with the rules from // the STACK CFI INIT record. std::unique_ptr rules(new CFIFrameInfo()); if (!ParseCFIRuleSet(initial_rules, rules.get())) - return NULL; + return nullptr; // Find the first delta rule that falls within the initial rule's range. map::const_iterator delta = @@ -488,7 +488,7 @@ BasicSourceLineResolver::Module::ParseFunction(char* function_line) { &size, &stack_param_size, &name)) { return new Function(name, address, size, stack_param_size, is_multiple); } - return NULL; + return nullptr; } BasicSourceLineResolver::Line* BasicSourceLineResolver::Module::ParseLine( @@ -502,7 +502,7 @@ BasicSourceLineResolver::Line* BasicSourceLineResolver::Module::ParseLine( &source_file)) { return new Line(address, size, source_file, line_number); } - return NULL; + return nullptr; } bool BasicSourceLineResolver::Module::ParsePublicSymbol(char* public_line) { @@ -553,7 +553,7 @@ bool BasicSourceLineResolver::Module::ParseStackInfo(char* stack_info_line) { type, rva, code_size)); - if (stack_frame_info == NULL) + if (stack_frame_info == nullptr) return false; // TODO(mmentovai): I wanted to use StoreRange's return value as this @@ -598,26 +598,26 @@ bool BasicSourceLineResolver::Module::ParseCFIFrameInfo( if (strcmp(init_or_address, "INIT") == 0) { // This record has the form "STACK INIT
". - char* address_field = strtok_r(NULL, " \r\n", &cursor); + char* address_field = strtok_r(nullptr, " \r\n", &cursor); if (!address_field) return false; - char* size_field = strtok_r(NULL, " \r\n", &cursor); + char* size_field = strtok_r(nullptr, " \r\n", &cursor); if (!size_field) return false; - char* initial_rules = strtok_r(NULL, "\r\n", &cursor); + char* initial_rules = strtok_r(nullptr, "\r\n", &cursor); if (!initial_rules) return false; - MemAddr address = strtoul(address_field, NULL, 16); - MemAddr size = strtoul(size_field, NULL, 16); + MemAddr address = strtoul(address_field, nullptr, 16); + MemAddr size = strtoul(size_field, nullptr, 16); cfi_initial_rules_.StoreRange(address, size, initial_rules); return true; } // This record has the form "STACK
". char* address_field = init_or_address; - char* delta_rules = strtok_r(NULL, "\r\n", &cursor); + char* delta_rules = strtok_r(nullptr, "\r\n", &cursor); if (!delta_rules) return false; - MemAddr address = strtoul(address_field, NULL, 16); + MemAddr address = strtoul(address_field, nullptr, 16); cfi_delta_rules_[address] = delta_rules; return true; } @@ -921,7 +921,8 @@ bool SymbolParseHelper::ParsePublicSymbol(char* public_line, bool* is_multiple, // static bool SymbolParseHelper::IsValidAfterNumber(char* after_number) { - if (after_number != NULL && strchr(kWhitespace, *after_number) != NULL) { + if (after_number != nullptr && + strchr(kWhitespace, *after_number) != nullptr) { return true; } return false; diff --git a/src/processor/basic_source_line_resolver_unittest.cc b/src/processor/basic_source_line_resolver_unittest.cc index 8e51d24d1..9cfd915ed 100644 --- a/src/processor/basic_source_line_resolver_unittest.cc +++ b/src/processor/basic_source_line_resolver_unittest.cc @@ -159,7 +159,7 @@ static bool VerifyEmpty(const StackFrame& frame) { static void ClearSourceLineInfo(StackFrame* frame) { frame->function_name.clear(); - frame->module = NULL; + frame->module = nullptr; frame->source_file_name.clear(); frame->source_line = 0; } @@ -189,7 +189,7 @@ TEST_F(TestBasicSourceLineResolver, TestLoadAndResolve) std::unique_ptr windows_frame_info; std::unique_ptr cfi_frame_info; frame.instruction = 0x1000; - frame.module = NULL; + frame.module = nullptr; resolver.FillSourceLineInfo(&frame, nullptr); ASSERT_FALSE(frame.module); ASSERT_TRUE(frame.function_name.empty()); diff --git a/src/processor/cfi_frame_info.cc b/src/processor/cfi_frame_info.cc index 2094e0941..77e30eee3 100644 --- a/src/processor/cfi_frame_info.cc +++ b/src/processor/cfi_frame_info.cc @@ -161,7 +161,7 @@ bool CFIRuleParser::Parse(const string& rule_set) { expression_ += ' '; expression_ += token; } - token = strtok_r(NULL, token_breaks, &cursor); + token = strtok_r(nullptr, token_breaks, &cursor); } } diff --git a/src/processor/cfi_frame_info_unittest.cc b/src/processor/cfi_frame_info_unittest.cc index 0cf4562d3..dcbd7721b 100644 --- a/src/processor/cfi_frame_info_unittest.cc +++ b/src/processor/cfi_frame_info_unittest.cc @@ -485,11 +485,11 @@ struct SimpleCFIWalkerFixture { SimpleCFIWalkerFixture::CFIWalker::RegisterSet SimpleCFIWalkerFixture::register_map[7] = { - { "r0", NULL, true, R0_VALID, &RawContext::r0 }, - { "r1", NULL, true, R1_VALID, &RawContext::r1 }, - { "r2", NULL, false, R2_VALID, &RawContext::r2 }, - { "r3", NULL, false, R3_VALID, &RawContext::r3 }, - { "r4", NULL, true, R4_VALID, &RawContext::r4 }, + { "r0", nullptr, true, R0_VALID, &RawContext::r0 }, + { "r1", nullptr, true, R1_VALID, &RawContext::r1 }, + { "r2", nullptr, false, R2_VALID, &RawContext::r2 }, + { "r3", nullptr, false, R3_VALID, &RawContext::r3 }, + { "r4", nullptr, true, R4_VALID, &RawContext::r4 }, { "sp", ".cfa", true, SP_VALID, &RawContext::sp }, { "pc", ".ra", true, PC_VALID, &RawContext::pc }, }; diff --git a/src/processor/contained_range_map-inl.h b/src/processor/contained_range_map-inl.h index e085dcb45..301c62128 100644 --- a/src/processor/contained_range_map-inl.h +++ b/src/processor/contained_range_map-inl.h @@ -126,7 +126,7 @@ bool ContainedRangeMap::StoreRange( // Optimization: if the iterators are equal, no child ranges would be // moved. Create the new child range with a NULL map to conserve space // in leaf nodes, of which there will be many. - AddressToRangeMap* child_map = NULL; + AddressToRangeMap* child_map = nullptr; if (iterator_base != iterator_high) { // The children of this range that are contained by the new range must @@ -203,7 +203,7 @@ void ContainedRangeMap::Clear() { delete child->second; delete map_; - map_ = NULL; + map_ = nullptr; } } diff --git a/src/processor/contained_range_map.h b/src/processor/contained_range_map.h index 24a3bb41e..3f5a4959a 100644 --- a/src/processor/contained_range_map.h +++ b/src/processor/contained_range_map.h @@ -76,7 +76,10 @@ class ContainedRangeMap { // and no entry, and as such is only suitable for the root node of a // ContainedRangeMap tree. explicit ContainedRangeMap(bool allow_equal_range = false) - : base_(), entry_(), map_(NULL), allow_equal_range_(allow_equal_range) {} + : base_(), + entry_(), + map_(nullptr), + allow_equal_range_(allow_equal_range) {} ~ContainedRangeMap(); diff --git a/src/processor/disassembler_x86.cc b/src/processor/disassembler_x86.cc index 741cec7fd..a772cffd9 100644 --- a/src/processor/disassembler_x86.cc +++ b/src/processor/disassembler_x86.cc @@ -56,7 +56,7 @@ DisassemblerX86::DisassemblerX86(const uint8_t* bytecode, pushed_bad_value_(false), end_of_block_(false), flags_(0) { - libdis::x86_init(libdis::opt_none, NULL, NULL); + libdis::x86_init(libdis::opt_none, nullptr, nullptr); } DisassemblerX86::~DisassemblerX86() { diff --git a/src/processor/disassembler_x86.h b/src/processor/disassembler_x86.h index 493f7f2e7..8f95ed0c7 100644 --- a/src/processor/disassembler_x86.h +++ b/src/processor/disassembler_x86.h @@ -36,7 +36,6 @@ #ifndef GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_ #define GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_ -#include #include #include "google_breakpad/common/breakpad_types.h" @@ -79,7 +78,7 @@ class DisassemblerX86 { // Returns the current instruction as defined in libdis.h, // or NULL if the current instruction is not valid. const libdis::x86_insn_t* currentInstruction() { - return instr_valid_ ? ¤t_instr_ : NULL; + return instr_valid_ ? ¤t_instr_ : nullptr; } // Returns the type of the current instruction as defined in libdis.h. diff --git a/src/processor/disassembler_x86_unittest.cc b/src/processor/disassembler_x86_unittest.cc index 18525b825..95ae65dc1 100644 --- a/src/processor/disassembler_x86_unittest.cc +++ b/src/processor/disassembler_x86_unittest.cc @@ -94,7 +94,7 @@ TEST(DisassemblerX86Test, SimpleReturnInstruction) { EXPECT_EQ(libdis::insn_return, instruction->type); EXPECT_EQ(0U, dis.NextInstruction()); EXPECT_FALSE(dis.currentInstructionValid()); - EXPECT_EQ(NULL, dis.currentInstruction()); + EXPECT_EQ(nullptr, dis.currentInstruction()); } TEST(DisassemblerX86Test, SimpleInvalidInstruction) { diff --git a/src/processor/dump_context.cc b/src/processor/dump_context.cc index ab97930f9..372fee5ee 100644 --- a/src/processor/dump_context.cc +++ b/src/processor/dump_context.cc @@ -73,7 +73,7 @@ uint32_t DumpContext::GetContextFlags() const { const MDRawContextX86* DumpContext::GetContextX86() const { if (GetContextCPU() != MD_CONTEXT_X86) { BPLOG(ERROR) << "DumpContext cannot get x86 context"; - return NULL; + return nullptr; } return context_.x86; @@ -82,7 +82,7 @@ const MDRawContextX86* DumpContext::GetContextX86() const { const MDRawContextPPC* DumpContext::GetContextPPC() const { if (GetContextCPU() != MD_CONTEXT_PPC) { BPLOG(ERROR) << "DumpContext cannot get ppc context"; - return NULL; + return nullptr; } return context_.ppc; @@ -91,7 +91,7 @@ const MDRawContextPPC* DumpContext::GetContextPPC() const { const MDRawContextPPC64* DumpContext::GetContextPPC64() const { if (GetContextCPU() != MD_CONTEXT_PPC64) { BPLOG(ERROR) << "DumpContext cannot get ppc64 context"; - return NULL; + return nullptr; } return context_.ppc64; @@ -100,7 +100,7 @@ const MDRawContextPPC64* DumpContext::GetContextPPC64() const { const MDRawContextAMD64* DumpContext::GetContextAMD64() const { if (GetContextCPU() != MD_CONTEXT_AMD64) { BPLOG(ERROR) << "DumpContext cannot get amd64 context"; - return NULL; + return nullptr; } return context_.amd64; @@ -109,7 +109,7 @@ const MDRawContextAMD64* DumpContext::GetContextAMD64() const { const MDRawContextSPARC* DumpContext::GetContextSPARC() const { if (GetContextCPU() != MD_CONTEXT_SPARC) { BPLOG(ERROR) << "DumpContext cannot get sparc context"; - return NULL; + return nullptr; } return context_.ctx_sparc; @@ -118,7 +118,7 @@ const MDRawContextSPARC* DumpContext::GetContextSPARC() const { const MDRawContextARM* DumpContext::GetContextARM() const { if (GetContextCPU() != MD_CONTEXT_ARM) { BPLOG(ERROR) << "DumpContext cannot get arm context"; - return NULL; + return nullptr; } return context_.arm; @@ -127,7 +127,7 @@ const MDRawContextARM* DumpContext::GetContextARM() const { const MDRawContextARM64* DumpContext::GetContextARM64() const { if (GetContextCPU() != MD_CONTEXT_ARM64) { BPLOG(ERROR) << "DumpContext cannot get arm64 context"; - return NULL; + return nullptr; } return context_.arm64; @@ -137,7 +137,7 @@ const MDRawContextMIPS* DumpContext::GetContextMIPS() const { if ((GetContextCPU() != MD_CONTEXT_MIPS) && (GetContextCPU() != MD_CONTEXT_MIPS64)) { BPLOG(ERROR) << "DumpContext cannot get MIPS context"; - return NULL; + return nullptr; } return context_.ctx_mips; @@ -146,7 +146,7 @@ const MDRawContextMIPS* DumpContext::GetContextMIPS() const { const MDRawContextRISCV* DumpContext::GetContextRISCV() const { if (GetContextCPU() != MD_CONTEXT_RISCV) { BPLOG(ERROR) << "DumpContext cannot get RISCV context"; - return NULL; + return nullptr; } return context_.riscv; @@ -155,7 +155,7 @@ const MDRawContextRISCV* DumpContext::GetContextRISCV() const { const MDRawContextRISCV64* DumpContext::GetContextRISCV64() const { if (GetContextCPU() != MD_CONTEXT_RISCV64) { BPLOG(ERROR) << "DumpContext cannot get RISCV64 context"; - return NULL; + return nullptr; } return context_.riscv64; @@ -356,7 +356,7 @@ void DumpContext::FreeContext() { } context_flags_ = 0; - context_.base = NULL; + context_.base = nullptr; } void DumpContext::Print() { diff --git a/src/processor/exploitability.cc b/src/processor/exploitability.cc index 79c7b088d..5e1639c1e 100644 --- a/src/processor/exploitability.cc +++ b/src/processor/exploitability.cc @@ -67,15 +67,15 @@ Exploitability *Exploitability::ExploitabilityForPlatform( Minidump *dump, ProcessState *process_state, bool enable_objdump) { - Exploitability *platform_exploitability = NULL; + Exploitability *platform_exploitability = nullptr; MinidumpSystemInfo *minidump_system_info = dump->GetSystemInfo(); if (!minidump_system_info) - return NULL; + return nullptr; const MDRawSystemInfo *raw_system_info = minidump_system_info->system_info(); if (!raw_system_info) - return NULL; + return nullptr; switch (raw_system_info->platform_id) { case MD_OS_WIN32_NT: @@ -97,7 +97,7 @@ Exploitability *Exploitability::ExploitabilityForPlatform( case MD_OS_PS3: case MD_OS_FUCHSIA: default: { - platform_exploitability = NULL; + platform_exploitability = nullptr; break; } } diff --git a/src/processor/exploitability_linux.cc b/src/processor/exploitability_linux.cc index 76e78f45b..c8a5ca59c 100644 --- a/src/processor/exploitability_linux.cc +++ b/src/processor/exploitability_linux.cc @@ -104,12 +104,12 @@ ExploitabilityRating ExploitabilityLinux::CheckPlatformExploitability() { // Getting exception data. (It should exist for all minidumps.) MinidumpException* exception = dump_->GetException(); - if (exception == NULL) { + if (exception == nullptr) { BPLOG(INFO) << "No exception record."; return EXPLOITABILITY_ERR_PROCESSING; } const MDRawExceptionStream* raw_exception_stream = exception->exception(); - if (raw_exception_stream == NULL) { + if (raw_exception_stream == nullptr) { BPLOG(INFO) << "No raw exception stream."; return EXPLOITABILITY_ERR_PROCESSING; } @@ -125,7 +125,7 @@ ExploitabilityRating ExploitabilityLinux::CheckPlatformExploitability() { uint64_t stack_ptr = 0; const MinidumpContext* context = exception->GetContext(); - if (context == NULL) { + if (context == nullptr) { BPLOG(INFO) << "No exception context."; return EXPLOITABILITY_ERR_PROCESSING; } @@ -170,7 +170,7 @@ bool ExploitabilityLinux::EndedOnIllegalWrite(uint64_t instruction_ptr) { MinidumpMemoryList* memory_list = dump_->GetMemoryList(); MinidumpMemoryRegion* memory_region = memory_list ? - memory_list->GetMemoryRegionForAddress(instruction_ptr) : NULL; + memory_list->GetMemoryRegionForAddress(instruction_ptr) : nullptr; if (!memory_region) { BPLOG(INFO) << "No memory region around instruction pointer."; return false; @@ -273,7 +273,7 @@ bool ExploitabilityLinux::InstructionPointerInCode(uint64_t instruction_ptr) { MinidumpLinuxMapsList* linux_maps_list = dump_->GetLinuxMapsList(); const MinidumpLinuxMaps* linux_maps = linux_maps_list ? - linux_maps_list->GetLinuxMapsForAddress(instruction_ptr) : NULL; + linux_maps_list->GetLinuxMapsForAddress(instruction_ptr) : nullptr; return linux_maps ? linux_maps->IsExecutable() : false; } diff --git a/src/processor/exploitability_unittest.cc b/src/processor/exploitability_unittest.cc index 09e4690d5..aa7514ae2 100644 --- a/src/processor/exploitability_unittest.cc +++ b/src/processor/exploitability_unittest.cc @@ -51,7 +51,7 @@ namespace google_breakpad { class ExploitabilityLinuxTestMinidumpContext : public MinidumpContext { public: explicit ExploitabilityLinuxTestMinidumpContext( - const MDRawContextAMD64& context) : MinidumpContext(NULL) { + const MDRawContextAMD64& context) : MinidumpContext(nullptr) { valid_ = true; SetContextAMD64(new MDRawContextAMD64(context)); SetContextFlags(MD_CONTEXT_AMD64); diff --git a/src/processor/fast_source_line_resolver.cc b/src/processor/fast_source_line_resolver.cc index 763ad8873..99fca9c76 100644 --- a/src/processor/fast_source_line_resolver.cc +++ b/src/processor/fast_source_line_resolver.cc @@ -98,7 +98,7 @@ void FastSourceLineResolver::Module::LookupAddress( std::unique_ptr line(new Line); const Line* line_ptr = 0; MemAddr line_base; - if (func->lines.RetrieveRange(address, line_ptr, &line_base, NULL)) { + if (func->lines.RetrieveRange(address, line_ptr, &line_base, nullptr)) { line->CopyFrom(line_ptr); FileMap::iterator it = files_.find(line->source_file_id); if (it != files_.end()) { @@ -326,14 +326,14 @@ WindowsFrameInfo* FastSourceLineResolver::Module::FindWindowsFrameInfo( result->parameter_size = public_symbol->parameter_size; } - return NULL; + return nullptr; } CFIFrameInfo* FastSourceLineResolver::Module::FindCFIFrameInfo( const StackFrame* frame) const { MemAddr address = frame->instruction - frame->module->base_address(); MemAddr initial_base, initial_size; - const char* initial_rules = NULL; + const char* initial_rules = nullptr; // Find the initial rule whose range covers this address. That // provides an initial set of register recovery rules. Then, walk @@ -341,14 +341,14 @@ CFIFrameInfo* FastSourceLineResolver::Module::FindCFIFrameInfo( // instruction address, applying delta rules. if (!cfi_initial_rules_.RetrieveRange(address, initial_rules, &initial_base, &initial_size)) { - return NULL; + return nullptr; } // Create a frame info structure, and populate it with the rules from // the STACK CFI INIT record. std::unique_ptr rules(new CFIFrameInfo()); if (!ParseCFIRuleSet(initial_rules, rules.get())) - return NULL; + return nullptr; // Find the first delta rule that falls within the initial rule's range. StaticMap::iterator delta = diff --git a/src/processor/fast_source_line_resolver_unittest.cc b/src/processor/fast_source_line_resolver_unittest.cc index df2536571..4baee92f1 100644 --- a/src/processor/fast_source_line_resolver_unittest.cc +++ b/src/processor/fast_source_line_resolver_unittest.cc @@ -170,7 +170,7 @@ static bool VerifyEmpty(const StackFrame& frame) { static void ClearSourceLineInfo(StackFrame* frame) { frame->function_name.clear(); - frame->module = NULL; + frame->module = nullptr; frame->source_file_name.clear(); frame->source_line = 0; } @@ -218,7 +218,7 @@ TEST_F(TestFastSourceLineResolver, TestLoadAndResolve) { std::unique_ptr windows_frame_info; std::unique_ptr cfi_frame_info; frame.instruction = 0x1000; - frame.module = NULL; + frame.module = nullptr; fast_resolver.FillSourceLineInfo(&frame, nullptr); ASSERT_FALSE(frame.module); ASSERT_TRUE(frame.function_name.empty()); diff --git a/src/processor/linked_ptr.h b/src/processor/linked_ptr.h index 5de49ee90..c67e36b25 100644 --- a/src/processor/linked_ptr.h +++ b/src/processor/linked_ptr.h @@ -97,7 +97,7 @@ class linked_ptr { // Take over ownership of a raw pointer. This should happen as soon as // possible after the object is created. - explicit linked_ptr(T* ptr = NULL) { capture(ptr); } + explicit linked_ptr(T* ptr = nullptr) { capture(ptr); } ~linked_ptr() { depart(); } // Copy an existing linked_ptr<>, adding ourselves to the list of references. @@ -120,7 +120,7 @@ class linked_ptr { } // Smart pointer members. - void reset(T* ptr = NULL) { depart(); capture(ptr); } + void reset(T* ptr = nullptr) { depart(); capture(ptr); } T* get() const { return value_; } T* operator->() const { return value_; } T& operator*() const { return *value_; } @@ -129,7 +129,7 @@ class linked_ptr { T* release() { link_.depart(); T* v = value_; - value_ = NULL; + value_ = nullptr; return v; } diff --git a/src/processor/map_serializers-inl.h b/src/processor/map_serializers-inl.h index 5dfb0a752..e86ffe382 100644 --- a/src/processor/map_serializers-inl.h +++ b/src/processor/map_serializers-inl.h @@ -70,7 +70,7 @@ char* StdMapSerializer::Write(const std::map& m, char* dest) const { if (!dest) { BPLOG(ERROR) << "StdMapSerializer failed: write to NULL address."; - return NULL; + return nullptr; } char* start_address = dest; @@ -105,7 +105,7 @@ char* StdMapSerializer::Serialize( if (!serialized_data) { BPLOG(INFO) << "StdMapSerializer memory allocation failed."; if (size) *size = 0; - return NULL; + return nullptr; } // Write serialized data into memory. Write(m, serialized_data); @@ -138,7 +138,7 @@ char* RangeMapSerializer::Write( const RangeMap& m, char* dest) const { if (!dest) { BPLOG(ERROR) << "RangeMapSerializer failed: write to NULL address."; - return NULL; + return nullptr; } char* start_address = dest; @@ -174,7 +174,7 @@ char* RangeMapSerializer::Serialize( if (!serialized_data) { BPLOG(INFO) << "RangeMapSerializer memory allocation failed."; if (size) *size = 0; - return NULL; + return nullptr; } // Write serialized data into memory. @@ -212,7 +212,7 @@ char* ContainedRangeMapSerializer::Write( const ContainedRangeMap* m, char* dest) const { if (!dest) { BPLOG(ERROR) << "StdMapSerializer failed: write to NULL address."; - return NULL; + return nullptr; } dest = addr_serializer_.Write(m->base_, dest); dest = SimpleSerializer::Write(entry_serializer_.SizeOf(m->entry_), @@ -221,7 +221,7 @@ char* ContainedRangeMapSerializer::Write( // Write map<: char* map_address = dest; - if (m->map_ == NULL) { + if (m->map_ == nullptr) { dest = SimpleSerializer::Write(0, dest); } else { dest = SimpleSerializer::Write(m->map_->size(), dest); @@ -253,7 +253,7 @@ char* ContainedRangeMapSerializer::Serialize( if (!serialized_data) { BPLOG(INFO) << "ContainedRangeMapSerializer memory allocation failed."; if (size) *size = 0; - return NULL; + return nullptr; } Write(m, serialized_data); if (size) *size = size_to_alloc; diff --git a/src/processor/map_serializers_unittest.cc b/src/processor/map_serializers_unittest.cc index c5228d647..2a421ef73 100644 --- a/src/processor/map_serializers_unittest.cc +++ b/src/processor/map_serializers_unittest.cc @@ -58,7 +58,7 @@ class TestStdMapSerializer : public ::testing::Test { protected: void SetUp() { serialized_size_ = 0; - serialized_data_ = NULL; + serialized_data_ = nullptr; } void TearDown() { diff --git a/src/processor/microdump_processor.cc b/src/processor/microdump_processor.cc index 5493b1c8f..a38f199e2 100644 --- a/src/processor/microdump_processor.cc +++ b/src/processor/microdump_processor.cc @@ -71,7 +71,7 @@ ProcessResult MicrodumpProcessor::Process(Microdump *microdump, microdump->GetContext(), microdump->GetMemory(), process_state->modules_, - /* unloaded_modules= */ NULL, + /* unloaded_modules= */ nullptr, frame_symbolizer_)); std::unique_ptr stack(new CallStack()); diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 5d937c9ca..7fdd966de 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -279,14 +279,14 @@ string* UTF16ToUTF8(const vector& in, bool swap) { if (in_word >= 0xdc00 && in_word <= 0xdcff) { BPLOG(ERROR) << "UTF16ToUTF8 found low surrogate " << HexString(in_word) << " without high"; - return NULL; + return nullptr; } else if (in_word >= 0xd800 && in_word <= 0xdbff) { // High surrogate. unichar = (in_word - 0xd7c0) << 10; if (++iterator == in.end()) { BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " << HexString(in_word) << " at end of string"; - return NULL; + return nullptr; } uint32_t high_word = in_word; in_word = *iterator; @@ -294,7 +294,7 @@ string* UTF16ToUTF8(const vector& in, bool swap) { BPLOG(ERROR) << "UTF16ToUTF8 found high surrogate " << HexString(high_word) << " without low " << HexString(in_word); - return NULL; + return nullptr; } unichar |= in_word & 0x03ff; } else { @@ -322,7 +322,7 @@ string* UTF16ToUTF8(const vector& in, bool swap) { } else { BPLOG(ERROR) << "UTF16ToUTF8 cannot represent high value " << HexString(unichar) << " in UTF-8"; - return NULL; + return nullptr; } } @@ -1497,8 +1497,8 @@ uint32_t MinidumpMemoryRegion::max_bytes_ = 64 * 1024 * 1024; // 64MB MinidumpMemoryRegion::MinidumpMemoryRegion(Minidump* minidump) : MinidumpObject(minidump), - descriptor_(NULL), - memory_(NULL) { + descriptor_(nullptr), + memory_(nullptr) { hexdump_width_ = minidump_ ? minidump_->HexdumpMode() : 0; hexdump_ = hexdump_width_ != 0; } @@ -1521,25 +1521,25 @@ void MinidumpMemoryRegion::SetDescriptor(MDMemoryDescriptor* descriptor) { const uint8_t* MinidumpMemoryRegion::GetMemory() const { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpMemoryRegion for GetMemory"; - return NULL; + return nullptr; } if (!memory_) { if (descriptor_->memory.data_size == 0) { BPLOG(ERROR) << "MinidumpMemoryRegion is empty"; - return NULL; + return nullptr; } if (!minidump_->SeekSet(descriptor_->memory.rva)) { BPLOG(ERROR) << "MinidumpMemoryRegion could not seek to memory region"; - return NULL; + return nullptr; } if (descriptor_->memory.data_size > max_bytes_) { BPLOG(ERROR) << "MinidumpMemoryRegion size " << descriptor_->memory.data_size << " exceeds maximum " << max_bytes_; - return NULL; + return nullptr; } std::unique_ptr< vector > memory( @@ -1547,7 +1547,7 @@ const uint8_t* MinidumpMemoryRegion::GetMemory() const { if (!minidump_->ReadBytes(&(*memory)[0], descriptor_->memory.data_size)) { BPLOG(ERROR) << "MinidumpMemoryRegion could not read memory region"; - return NULL; + return nullptr; } memory_ = memory.release(); @@ -1579,7 +1579,7 @@ uint32_t MinidumpMemoryRegion::GetSize() const { void MinidumpMemoryRegion::FreeMemory() { delete memory_; - memory_ = NULL; + memory_ = nullptr; } @@ -1738,8 +1738,8 @@ void MinidumpMemoryRegion::SetPrintMode(bool hexdump, MinidumpThread::MinidumpThread(Minidump* minidump) : MinidumpObject(minidump), thread_(), - memory_(NULL), - context_(NULL) { + memory_(nullptr), + context_(nullptr) { } @@ -1752,9 +1752,9 @@ MinidumpThread::~MinidumpThread() { bool MinidumpThread::Read() { // Invalidate cached data. delete memory_; - memory_ = NULL; + memory_ = nullptr; delete context_; - context_ = NULL; + context_ = nullptr; valid_ = false; @@ -1804,7 +1804,7 @@ uint64_t MinidumpThread::GetStartOfStackMemoryRange() const { MinidumpMemoryRegion* MinidumpThread::GetMemory() { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpThread for GetMemory"; - return NULL; + return nullptr; } return memory_; @@ -1814,20 +1814,20 @@ MinidumpMemoryRegion* MinidumpThread::GetMemory() { MinidumpContext* MinidumpThread::GetContext() { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpThread for GetContext"; - return NULL; + return nullptr; } if (!context_) { if (!minidump_->SeekSet(thread_.thread_context.rva)) { BPLOG(ERROR) << "MinidumpThread cannot seek to context"; - return NULL; + return nullptr; } std::unique_ptr context(new MinidumpContext(minidump_)); if (!context->Read(thread_.thread_context.data_size)) { BPLOG(ERROR) << "MinidumpThread cannot read context"; - return NULL; + return nullptr; } context_ = context.release(); @@ -1906,7 +1906,7 @@ uint32_t MinidumpThreadList::max_threads_ = 4096; MinidumpThreadList::MinidumpThreadList(Minidump* minidump) : MinidumpStream(minidump), id_to_thread_map_(), - threads_(NULL), + threads_(nullptr), thread_count_(0) { } @@ -1920,7 +1920,7 @@ bool MinidumpThreadList::Read(uint32_t expected_size) { // Invalidate cached data. id_to_thread_map_.clear(); delete threads_; - threads_ = NULL; + threads_ = nullptr; thread_count_ = 0; valid_ = false; @@ -2018,13 +2018,13 @@ MinidumpThread* MinidumpThreadList::GetThreadAtIndex(unsigned int index) const { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpThreadList for GetThreadAtIndex"; - return NULL; + return nullptr; } if (index >= thread_count_) { BPLOG(ERROR) << "MinidumpThreadList index out of range: " << index << "/" << thread_count_; - return NULL; + return nullptr; } return &(*threads_)[index]; @@ -2065,7 +2065,7 @@ MinidumpThreadName::MinidumpThreadName(Minidump* minidump) : MinidumpObject(minidump), thread_name_valid_(false), thread_name_(), - name_(NULL) {} + name_(nullptr) {} MinidumpThreadName::~MinidumpThreadName() { delete name_; @@ -2074,7 +2074,7 @@ MinidumpThreadName::~MinidumpThreadName() { bool MinidumpThreadName::Read() { // Invalidate cached data. delete name_; - name_ = NULL; + name_ = nullptr; valid_ = false; @@ -2161,7 +2161,7 @@ void MinidumpThreadName::Print() { // MinidumpThreadNameList::MinidumpThreadNameList(Minidump* minidump) - : MinidumpStream(minidump), thread_names_(NULL), thread_name_count_(0) {} + : MinidumpStream(minidump), thread_names_(nullptr), thread_name_count_(0) {} MinidumpThreadNameList::~MinidumpThreadNameList() { delete thread_names_; @@ -2170,7 +2170,7 @@ MinidumpThreadNameList::~MinidumpThreadNameList() { bool MinidumpThreadNameList::Read(uint32_t expected_size) { // Invalidate cached data. delete thread_names_; - thread_names_ = NULL; + thread_names_ = nullptr; thread_name_count_ = 0; valid_ = false; @@ -2251,13 +2251,13 @@ MinidumpThreadName* MinidumpThreadNameList::GetThreadNameAtIndex( unsigned int index) const { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpThreadNameList for GetThreadNameAtIndex"; - return NULL; + return nullptr; } if (index >= thread_name_count_) { BPLOG(ERROR) << "MinidumpThreadNameList index out of range: " << index << "/" << thread_name_count_; - return NULL; + return nullptr; } return &(*thread_names_)[index]; @@ -2295,10 +2295,10 @@ MinidumpModule::MinidumpModule(Minidump* minidump) module_valid_(false), has_debug_info_(false), module_(), - name_(NULL), - cv_record_(NULL), + name_(nullptr), + cv_record_(nullptr), cv_record_signature_(MD_CVINFOUNKNOWN_SIGNATURE), - misc_record_(NULL) { + misc_record_(nullptr) { } @@ -2312,12 +2312,12 @@ MinidumpModule::~MinidumpModule() { bool MinidumpModule::Read() { // Invalidate cached data. delete name_; - name_ = NULL; + name_ = nullptr; delete cv_record_; - cv_record_ = NULL; + cv_record_ = nullptr; cv_record_signature_ = MD_CVINFOUNKNOWN_SIGNATURE; delete misc_record_; - misc_record_ = NULL; + misc_record_ = nullptr; module_valid_ = false; has_debug_info_ = false; @@ -2386,13 +2386,13 @@ bool MinidumpModule::ReadAuxiliaryData() { // CodeView and miscellaneous debug records are only required if the // module indicates that they exist. - if (module_.cv_record.data_size && !GetCVRecord(NULL)) { + if (module_.cv_record.data_size && !GetCVRecord(nullptr)) { BPLOG(ERROR) << "MinidumpModule has no CodeView record, " "but one was expected"; return false; } - if (module_.misc_record.data_size && !GetMiscRecord(NULL)) { + if (module_.misc_record.data_size && !GetMiscRecord(nullptr)) { BPLOG(ERROR) << "MinidumpModule has no miscellaneous debug record, " "but one was expected"; return false; @@ -2726,26 +2726,26 @@ void MinidumpModule::SetShrinkDownDelta(uint64_t shrink_down_delta) { const uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) { if (!module_valid_) { BPLOG(ERROR) << "Invalid MinidumpModule for GetCVRecord"; - return NULL; + return nullptr; } if (!cv_record_) { // This just guards against 0-sized CodeView records; more specific checks // are used when the signature is checked against various structure types. if (module_.cv_record.data_size == 0) { - return NULL; + return nullptr; } if (!minidump_->SeekSet(module_.cv_record.rva)) { BPLOG(ERROR) << "MinidumpModule could not seek to CodeView record"; - return NULL; + return nullptr; } if (module_.cv_record.data_size > max_cv_bytes_) { BPLOG(ERROR) << "MinidumpModule CodeView record size " << module_.cv_record.data_size << " exceeds maximum " << max_cv_bytes_; - return NULL; + return nullptr; } // Allocating something that will be accessed as MDCVInfoPDB70 or @@ -2760,7 +2760,7 @@ const uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) { if (!minidump_->ReadBytes(&(*cv_record)[0], module_.cv_record.data_size)) { BPLOG(ERROR) << "MinidumpModule could not read CodeView record"; - return NULL; + return nullptr; } uint32_t signature = MD_CVINFOUNKNOWN_SIGNATURE; @@ -2779,7 +2779,7 @@ const uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) { BPLOG(ERROR) << "MinidumpModule CodeView7 record size mismatch, " << MDCVInfoPDB70_minsize << " > " << module_.cv_record.data_size; - return NULL; + return nullptr; } if (minidump_->swap()) { @@ -2797,7 +2797,7 @@ const uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) { if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') { BPLOG(ERROR) << "MinidumpModule CodeView7 record string is not " "0-terminated"; - return NULL; + return nullptr; } } else if (signature == MD_CVINFOPDB20_SIGNATURE) { // Now that the structure type is known, recheck the size, @@ -2806,7 +2806,7 @@ const uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) { BPLOG(ERROR) << "MinidumpModule CodeView2 record size mismatch, " << MDCVInfoPDB20_minsize << " > " << module_.cv_record.data_size; - return NULL; + return nullptr; } if (minidump_->swap()) { MDCVInfoPDB20* cv_record_20 = @@ -2824,7 +2824,7 @@ const uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) { if ((*cv_record)[module_.cv_record.data_size - 1] != '\0') { BPLOG(ERROR) << "MindumpModule CodeView2 record string is not " "0-terminated"; - return NULL; + return nullptr; } } else if (signature == MD_CVINFOELF_SIGNATURE) { // Now that the structure type is known, recheck the size. @@ -2832,7 +2832,7 @@ const uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) { BPLOG(ERROR) << "MinidumpModule CodeViewELF record size mismatch, " << MDCVInfoELF_minsize << " > " << module_.cv_record.data_size; - return NULL; + return nullptr; } if (minidump_->swap()) { MDCVInfoELF* cv_record_elf = @@ -2863,32 +2863,32 @@ const uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) { const MDImageDebugMisc* MinidumpModule::GetMiscRecord(uint32_t* size) { if (!module_valid_) { BPLOG(ERROR) << "Invalid MinidumpModule for GetMiscRecord"; - return NULL; + return nullptr; } if (!misc_record_) { if (module_.misc_record.data_size == 0) { - return NULL; + return nullptr; } if (MDImageDebugMisc_minsize > module_.misc_record.data_size) { BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record " "size mismatch, " << MDImageDebugMisc_minsize << " > " << module_.misc_record.data_size; - return NULL; + return nullptr; } if (!minidump_->SeekSet(module_.misc_record.rva)) { BPLOG(ERROR) << "MinidumpModule could not seek to miscellaneous " "debugging record"; - return NULL; + return nullptr; } if (module_.misc_record.data_size > max_misc_bytes_) { BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record size " << module_.misc_record.data_size << " exceeds maximum " << max_misc_bytes_; - return NULL; + return nullptr; } // Allocating something that will be accessed as MDImageDebugMisc but @@ -2905,7 +2905,7 @@ const MDImageDebugMisc* MinidumpModule::GetMiscRecord(uint32_t* size) { if (!minidump_->ReadBytes(misc_record, module_.misc_record.data_size)) { BPLOG(ERROR) << "MinidumpModule could not read miscellaneous debugging " "record"; - return NULL; + return nullptr; } if (minidump_->swap()) { @@ -2928,7 +2928,7 @@ const MDImageDebugMisc* MinidumpModule::GetMiscRecord(uint32_t* size) { BPLOG(ERROR) << "MinidumpModule miscellaneous debugging record data " "size mismatch, " << module_.misc_record.data_size << " != " << misc_record->length; - return NULL; + return nullptr; } // Store the vector type because that's how storage was allocated, but @@ -3056,7 +3056,7 @@ void MinidumpModule::Print() { printf(" (cv_record) = (null)\n"); } - const MDImageDebugMisc* misc_record = GetMiscRecord(NULL); + const MDImageDebugMisc* misc_record = GetMiscRecord(nullptr); if (misc_record) { printf(" (misc_record).data_type = 0x%x\n", misc_record->data_type); @@ -3100,7 +3100,7 @@ uint32_t MinidumpModuleList::max_modules_ = 2048; MinidumpModuleList::MinidumpModuleList(Minidump* minidump) : MinidumpStream(minidump), range_map_(new RangeMap()), - modules_(NULL), + modules_(nullptr), module_count_(0) { MDOSPlatform platform; if (minidump_->GetPlatform(&platform) && @@ -3120,7 +3120,7 @@ bool MinidumpModuleList::Read(uint32_t expected_size) { // Invalidate cached data. range_map_->Clear(); delete modules_; - modules_ = NULL; + modules_ = nullptr; module_count_ = 0; valid_ = false; @@ -3300,15 +3300,15 @@ const MinidumpModule* MinidumpModuleList::GetModuleForAddress( uint64_t address) const { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleForAddress"; - return NULL; + return nullptr; } unsigned int module_index; - if (!range_map_->RetrieveRange(address, &module_index, NULL /* base */, - NULL /* delta */, NULL /* size */)) { + if (!range_map_->RetrieveRange(address, &module_index, nullptr /* base */, + nullptr /* delta */, nullptr /* size */)) { BPLOG(INFO) << "MinidumpModuleList has no module at " << HexString(address); - return NULL; + return nullptr; } return GetModuleAtIndex(module_index); @@ -3318,7 +3318,7 @@ const MinidumpModule* MinidumpModuleList::GetModuleForAddress( const MinidumpModule* MinidumpModuleList::GetMainModule() const { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpModuleList for GetMainModule"; - return NULL; + return nullptr; } // The main code module is the first one present in a minidump file's @@ -3331,21 +3331,21 @@ const MinidumpModule* MinidumpModuleList::GetModuleAtSequence( unsigned int sequence) const { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleAtSequence"; - return NULL; + return nullptr; } if (sequence >= module_count_) { BPLOG(ERROR) << "MinidumpModuleList sequence out of range: " << sequence << "/" << module_count_; - return NULL; + return nullptr; } unsigned int module_index; if (!range_map_->RetrieveRangeAtIndex(sequence, &module_index, - NULL /* base */, NULL /* delta */, - NULL /* size */)) { + nullptr /* base */, nullptr /* delta */, + nullptr /* size */)) { BPLOG(ERROR) << "MinidumpModuleList has no module at sequence " << sequence; - return NULL; + return nullptr; } return GetModuleAtIndex(module_index); @@ -3356,13 +3356,13 @@ const MinidumpModule* MinidumpModuleList::GetModuleAtIndex( unsigned int index) const { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpModuleList for GetModuleAtIndex"; - return NULL; + return nullptr; } if (index >= module_count_) { BPLOG(ERROR) << "MinidumpModuleList index out of range: " << index << "/" << module_count_; - return NULL; + return nullptr; } return &(*modules_)[index]; @@ -3409,8 +3409,8 @@ uint32_t MinidumpMemoryList::max_regions_ = 4096; MinidumpMemoryList::MinidumpMemoryList(Minidump* minidump) : MinidumpStream(minidump), range_map_(new RangeMap()), - descriptors_(NULL), - regions_(NULL), + descriptors_(nullptr), + regions_(nullptr), region_count_(0) { } @@ -3425,9 +3425,9 @@ MinidumpMemoryList::~MinidumpMemoryList() { bool MinidumpMemoryList::Read(uint32_t expected_size) { // Invalidate cached data. delete descriptors_; - descriptors_ = NULL; + descriptors_ = nullptr; delete regions_; - regions_ = NULL; + regions_ = nullptr; range_map_->Clear(); region_count_ = 0; @@ -3541,13 +3541,13 @@ MinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionAtIndex( unsigned int index) { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionAtIndex"; - return NULL; + return nullptr; } if (index >= region_count_) { BPLOG(ERROR) << "MinidumpMemoryList index out of range: " << index << "/" << region_count_; - return NULL; + return nullptr; } return &(*regions_)[index]; @@ -3558,15 +3558,15 @@ MinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionForAddress( uint64_t address) { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpMemoryList for GetMemoryRegionForAddress"; - return NULL; + return nullptr; } unsigned int region_index; - if (!range_map_->RetrieveRange(address, ®ion_index, NULL /* base */, - NULL /* delta */, NULL /* size */)) { + if (!range_map_->RetrieveRange(address, ®ion_index, nullptr /* base */, + nullptr /* delta */, nullptr /* size */)) { BPLOG(INFO) << "MinidumpMemoryList has no memory region at " << HexString(address); - return NULL; + return nullptr; } return GetMemoryRegionAtIndex(region_index); @@ -3613,7 +3613,7 @@ void MinidumpMemoryList::Print() { MinidumpException::MinidumpException(Minidump* minidump) : MinidumpStream(minidump), exception_(), - context_(NULL) { + context_(nullptr) { } @@ -3625,7 +3625,7 @@ MinidumpException::~MinidumpException() { bool MinidumpException::Read(uint32_t expected_size) { // Invalidate cached data. delete context_; - context_ = NULL; + context_ = nullptr; valid_ = false; @@ -3683,13 +3683,13 @@ bool MinidumpException::GetThreadID(uint32_t* thread_id) const { MinidumpContext* MinidumpException::GetContext() { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpException for GetContext"; - return NULL; + return nullptr; } if (!context_) { if (!minidump_->SeekSet(exception_.thread_context.rva)) { BPLOG(ERROR) << "MinidumpException cannot seek to context"; - return NULL; + return nullptr; } std::unique_ptr context(new MinidumpContext(minidump_)); @@ -3698,7 +3698,7 @@ MinidumpContext* MinidumpException::GetContext() { // (which must be possible if we got this far.) if (!context->Read(exception_.thread_context.data_size)) { BPLOG(INFO) << "MinidumpException cannot read context"; - return NULL; + return nullptr; } context_ = context.release(); @@ -3829,8 +3829,8 @@ void MinidumpAssertion::Print() { MinidumpSystemInfo::MinidumpSystemInfo(Minidump* minidump) : MinidumpStream(minidump), system_info_(), - csd_version_(NULL), - cpu_vendor_(NULL) { + csd_version_(nullptr), + cpu_vendor_(nullptr) { } @@ -3843,9 +3843,9 @@ MinidumpSystemInfo::~MinidumpSystemInfo() { bool MinidumpSystemInfo::Read(uint32_t expected_size) { // Invalidate cached data. delete csd_version_; - csd_version_ = NULL; + csd_version_ = nullptr; delete cpu_vendor_; - cpu_vendor_ = NULL; + cpu_vendor_ = nullptr; valid_ = false; @@ -4008,7 +4008,7 @@ string MinidumpSystemInfo::GetCPU() { const string* MinidumpSystemInfo::GetCSDVersion() { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCSDVersion"; - return NULL; + return nullptr; } if (!csd_version_) @@ -4024,7 +4024,7 @@ const string* MinidumpSystemInfo::GetCSDVersion() { const string* MinidumpSystemInfo::GetCPUVendor() { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpSystemInfo for GetCPUVendor"; - return NULL; + return nullptr; } // CPU vendor information can only be determined from x86 minidumps. @@ -4133,7 +4133,7 @@ MinidumpUnloadedModule::MinidumpUnloadedModule(Minidump* minidump) : MinidumpObject(minidump), module_valid_(false), unloaded_module_(), - name_(NULL) { + name_(nullptr) { } @@ -4315,7 +4315,7 @@ uint32_t MinidumpUnloadedModuleList::max_modules_ = 2048; MinidumpUnloadedModuleList::MinidumpUnloadedModuleList(Minidump* minidump) : MinidumpStream(minidump), range_map_(new RangeMap()), - unloaded_modules_(NULL), + unloaded_modules_(nullptr), module_count_(0) { range_map_->SetMergeStrategy(MergeRangeStrategy::kTruncateLower); } @@ -4329,7 +4329,7 @@ MinidumpUnloadedModuleList::~MinidumpUnloadedModuleList() { bool MinidumpUnloadedModuleList::Read(uint32_t expected_size) { range_map_->Clear(); delete unloaded_modules_; - unloaded_modules_ = NULL; + unloaded_modules_ = nullptr; module_count_ = 0; valid_ = false; @@ -4432,15 +4432,15 @@ const MinidumpUnloadedModule* MinidumpUnloadedModuleList::GetModuleForAddress( if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpUnloadedModuleList for GetModuleForAddress"; - return NULL; + return nullptr; } unsigned int module_index; - if (!range_map_->RetrieveRange(address, &module_index, NULL /* base */, - NULL /* delta */, NULL /* size */)) { + if (!range_map_->RetrieveRange(address, &module_index, nullptr /* base */, + nullptr /* delta */, nullptr /* size */)) { BPLOG(INFO) << "MinidumpUnloadedModuleList has no module at " << HexString(address); - return NULL; + return nullptr; } return GetModuleAtIndex(module_index); @@ -4448,7 +4448,7 @@ const MinidumpUnloadedModule* MinidumpUnloadedModuleList::GetModuleForAddress( const MinidumpUnloadedModule* MinidumpUnloadedModuleList::GetMainModule() const { - return NULL; + return nullptr; } const MinidumpUnloadedModule* @@ -4456,22 +4456,22 @@ MinidumpUnloadedModuleList::GetModuleAtSequence(unsigned int sequence) const { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpUnloadedModuleList for GetModuleAtSequence"; - return NULL; + return nullptr; } if (sequence >= module_count_) { BPLOG(ERROR) << "MinidumpUnloadedModuleList sequence out of range: " << sequence << "/" << module_count_; - return NULL; + return nullptr; } unsigned int module_index; if (!range_map_->RetrieveRangeAtIndex(sequence, &module_index, - NULL /* base */, NULL /* delta */, - NULL /* size */)) { + nullptr /* base */, nullptr /* delta */, + nullptr /* size */)) { BPLOG(ERROR) << "MinidumpUnloadedModuleList has no module at sequence " << sequence; - return NULL; + return nullptr; } return GetModuleAtIndex(module_index); @@ -4482,13 +4482,13 @@ MinidumpUnloadedModuleList::GetModuleAtIndex( unsigned int index) const { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpUnloadedModuleList for GetModuleAtIndex"; - return NULL; + return nullptr; } if (index >= module_count_) { BPLOG(ERROR) << "MinidumpUnloadedModuleList index out of range: " << index << "/" << module_count_; - return NULL; + return nullptr; } return &(*unloaded_modules_)[index]; @@ -4970,7 +4970,7 @@ void MinidumpMemoryInfo::Print() { MinidumpMemoryInfoList::MinidumpMemoryInfoList(Minidump* minidump) : MinidumpStream(minidump), range_map_(new RangeMap()), - infos_(NULL), + infos_(nullptr), info_count_(0) { } @@ -4984,7 +4984,7 @@ MinidumpMemoryInfoList::~MinidumpMemoryInfoList() { bool MinidumpMemoryInfoList::Read(uint32_t expected_size) { // Invalidate cached data. delete infos_; - infos_ = NULL; + infos_ = nullptr; range_map_->Clear(); info_count_ = 0; @@ -5096,13 +5096,13 @@ const MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoAtIndex( unsigned int index) const { if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for GetMemoryInfoAtIndex"; - return NULL; + return nullptr; } if (index >= info_count_) { BPLOG(ERROR) << "MinidumpMemoryInfoList index out of range: " << index << "/" << info_count_; - return NULL; + return nullptr; } return &(*infos_)[index]; @@ -5114,15 +5114,15 @@ const MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoForAddress( if (!valid_) { BPLOG(ERROR) << "Invalid MinidumpMemoryInfoList for" " GetMemoryInfoForAddress"; - return NULL; + return nullptr; } unsigned int info_index; - if (!range_map_->RetrieveRange(address, &info_index, NULL /* base */, - NULL /* delta */, NULL /* size */)) { + if (!range_map_->RetrieveRange(address, &info_index, nullptr /* base */, + nullptr /* delta */, nullptr /* size */)) { BPLOG(INFO) << "MinidumpMemoryInfoList has no memory info at " << HexString(address); - return NULL; + return nullptr; } return GetMemoryInfoAtIndex(info_index); @@ -5170,7 +5170,7 @@ void MinidumpLinuxMaps::Print() const { MinidumpLinuxMapsList::MinidumpLinuxMapsList(Minidump* minidump) : MinidumpStream(minidump), - maps_(NULL), + maps_(nullptr), maps_count_(0) { } @@ -5185,9 +5185,9 @@ MinidumpLinuxMapsList::~MinidumpLinuxMapsList() { const MinidumpLinuxMaps* MinidumpLinuxMapsList::GetLinuxMapsForAddress( uint64_t address) const { - if (!valid_ || (maps_ == NULL)) { + if (!valid_ || (maps_ == nullptr)) { BPLOG(ERROR) << "Invalid MinidumpLinuxMapsList for GetLinuxMapsForAddress"; - return NULL; + return nullptr; } // Search every memory mapping. @@ -5202,23 +5202,23 @@ const MinidumpLinuxMaps* MinidumpLinuxMapsList::GetLinuxMapsForAddress( // No mapping encloses the memory address. BPLOG(ERROR) << "MinidumpLinuxMapsList has no mapping at " << HexString(address); - return NULL; + return nullptr; } const MinidumpLinuxMaps* MinidumpLinuxMapsList::GetLinuxMapsAtIndex( unsigned int index) const { - if (!valid_ || (maps_ == NULL)) { + if (!valid_ || (maps_ == nullptr)) { BPLOG(ERROR) << "Invalid MinidumpLinuxMapsList for GetLinuxMapsAtIndex"; - return NULL; + return nullptr; } // Index out of bounds. - if (index >= maps_count_ || (maps_ == NULL)) { + if (index >= maps_count_ || (maps_ == nullptr)) { BPLOG(ERROR) << "MinidumpLinuxMapsList index of out range: " << index << "/" << maps_count_; - return NULL; + return nullptr; } return (*maps_)[index]; } @@ -5231,7 +5231,7 @@ bool MinidumpLinuxMapsList::Read(uint32_t expected_size) { } delete maps_; } - maps_ = NULL; + maps_ = nullptr; maps_count_ = 0; valid_ = false; @@ -5283,7 +5283,7 @@ bool MinidumpLinuxMapsList::Read(uint32_t expected_size) { } void MinidumpLinuxMapsList::Print() const { - if (!valid_ || (maps_ == NULL)) { + if (!valid_ || (maps_ == nullptr)) { BPLOG(ERROR) << "MinidumpLinuxMapsList cannot print valid data"; return; } @@ -5558,10 +5558,10 @@ unsigned int Minidump::max_string_length_ = 1024; Minidump::Minidump(const string& path, bool hexdump, unsigned int hexdump_width) : header_(), - directory_(NULL), + directory_(nullptr), stream_map_(new MinidumpStreamMap()), path_(path), - stream_(NULL), + stream_(nullptr), swap_(false), is_big_endian_(false), valid_(false), @@ -5571,7 +5571,7 @@ Minidump::Minidump(const string& path, bool hexdump, unsigned int hexdump_width) Minidump::Minidump(istream& stream) : header_(), - directory_(NULL), + directory_(nullptr), stream_map_(new MinidumpStreamMap()), path_(), stream_(&stream), @@ -5595,7 +5595,7 @@ Minidump::~Minidump() { bool Minidump::Open() { - if (stream_ != NULL) { + if (stream_ != nullptr) { BPLOG(INFO) << "Minidump reopening minidump " << path_; // The file is already open. Seek to the beginning, which is the position @@ -5629,9 +5629,9 @@ bool Minidump::GetContextCPUFlagsFromSystemInfo(uint32_t* context_cpu_flags) { } const MDRawSystemInfo* system_info = - GetSystemInfo() ? GetSystemInfo()->system_info() : NULL; + GetSystemInfo() ? GetSystemInfo()->system_info() : nullptr; - if (system_info != NULL) { + if (system_info != nullptr) { switch (system_info->processor_architecture) { case MD_CPU_ARCHITECTURE_X86: *context_cpu_flags = MD_CONTEXT_X86; @@ -5704,7 +5704,7 @@ bool Minidump::GetContextCPUFlagsFromSystemInfo(uint32_t* context_cpu_flags) { bool Minidump::Read() { // Invalidate cached data. delete directory_; - directory_ = NULL; + directory_ = nullptr; stream_map_->clear(); valid_ = false; @@ -5920,7 +5920,7 @@ bool Minidump::GetPlatform(MDOSPlatform* platform) { return false; } const MDRawSystemInfo* system_info = - GetSystemInfo() ? GetSystemInfo()->system_info() : NULL; + GetSystemInfo() ? GetSystemInfo()->system_info() : nullptr; // Restore position and return if (!SeekSet(saved_position)) { @@ -6070,13 +6070,13 @@ const MDRawDirectory* Minidump::GetDirectoryEntryAtIndex(unsigned int index) const { if (!valid_) { BPLOG(ERROR) << "Invalid Minidump for GetDirectoryEntryAtIndex"; - return NULL; + return nullptr; } if (index >= header_.stream_count) { BPLOG(ERROR) << "Minidump stream directory index out of range: " << index << "/" << header_.stream_count; - return NULL; + return nullptr; } return &(*directory_)[index]; @@ -6151,18 +6151,18 @@ off_t Minidump::Tell() { string* Minidump::ReadString(off_t offset) { if (!valid_) { BPLOG(ERROR) << "Invalid Minidump for ReadString"; - return NULL; + return nullptr; } if (!SeekSet(offset)) { BPLOG(ERROR) << "ReadString could not seek to string at offset " << offset; - return NULL; + return nullptr; } uint32_t bytes; if (!ReadBytes(&bytes, sizeof(bytes))) { BPLOG(ERROR) << "ReadString could not read string size at offset " << offset; - return NULL; + return nullptr; } if (swap_) Swap(&bytes); @@ -6170,7 +6170,7 @@ string* Minidump::ReadString(off_t offset) { if (bytes % 2 != 0) { BPLOG(ERROR) << "ReadString found odd-sized " << bytes << "-byte string at offset " << offset; - return NULL; + return nullptr; } unsigned int utf16_words = bytes / 2; @@ -6178,7 +6178,7 @@ string* Minidump::ReadString(off_t offset) { BPLOG(ERROR) << "ReadString string length " << utf16_words << " exceeds maximum " << max_string_length_ << " at offset " << offset; - return NULL; + return nullptr; } vector string_utf16(utf16_words); @@ -6187,7 +6187,7 @@ string* Minidump::ReadString(off_t offset) { if (!ReadBytes(&string_utf16[0], bytes)) { BPLOG(ERROR) << "ReadString could not read " << bytes << "-byte string at offset " << offset; - return NULL; + return nullptr; } } @@ -6464,18 +6464,18 @@ T* Minidump::GetStream(T** stream) { BPLOG_IF(ERROR, !stream) << "Minidump::GetStream type " << stream_type << " requires |stream|"; assert(stream); - *stream = NULL; + *stream = nullptr; if (!valid_) { BPLOG(ERROR) << "Invalid Minidump for GetStream type " << stream_type; - return NULL; + return nullptr; } MinidumpStreamMap::iterator iterator = stream_map_->find(stream_type); if (iterator == stream_map_->end()) { // This stream type didn't exist in the directory. BPLOG(INFO) << "GetStream: type " << stream_type << " not present"; - return NULL; + return nullptr; } // Get a pointer so that the stored stream field can be altered. @@ -6491,14 +6491,14 @@ T* Minidump::GetStream(T** stream) { uint32_t stream_length; if (!SeekToStreamType(stream_type, &stream_length)) { BPLOG(ERROR) << "GetStream could not seek to stream type " << stream_type; - return NULL; + return nullptr; } std::unique_ptr new_stream(new T(this)); if (!new_stream->Read(stream_length)) { BPLOG(ERROR) << "GetStream could not read stream type " << stream_type; - return NULL; + return nullptr; } *stream = new_stream.release(); diff --git a/src/processor/minidump_dump.cc b/src/processor/minidump_dump.cc index e39d54884..914d6b765 100644 --- a/src/processor/minidump_dump.cc +++ b/src/processor/minidump_dump.cc @@ -97,7 +97,7 @@ static void DumpRawStream(Minidump *minidump, printf("%.*s", int_remaining, &contents[current_offset]); char *next_null = reinterpret_cast( memchr(&contents[current_offset], 0, remaining)); - if (next_null == NULL) + if (next_null == nullptr) break; printf("\\0\n"); size_t null_offset = next_null - &contents[0]; diff --git a/src/processor/minidump_processor.cc b/src/processor/minidump_processor.cc index 006787243..463b09793 100644 --- a/src/processor/minidump_processor.cc +++ b/src/processor/minidump_processor.cc @@ -200,15 +200,15 @@ ProcessResult MinidumpProcessor::Process( } BPLOG(INFO) << "Minidump " << dump->path() << " has " << - (has_cpu_info ? "" : "no ") << "CPU info, " << - (has_os_info ? "" : "no ") << "OS info, " << - (breakpad_info != NULL ? "" : "no ") << "Breakpad info, " << - (exception != NULL ? "" : "no ") << "exception, " << - (module_list != NULL ? "" : "no ") << "module list, " << - (threads != NULL ? "" : "no ") << "thread list, " << - (has_dump_thread ? "" : "no ") << "dump thread, " << - (has_requesting_thread ? "" : "no ") << "requesting thread, and " << - (has_process_create_time ? "" : "no ") << "process create time"; + (has_cpu_info ? "" : "no ") << "CPU info, " << + (has_os_info ? "" : "no ") << "OS info, " << + (breakpad_info != nullptr ? "" : "no ") << "Breakpad info, " << + (exception != nullptr ? "" : "no ") << "exception, " << + (module_list != nullptr ? "" : "no ") << "module list, " << + (threads != nullptr ? "" : "no ") << "thread list, " << + (has_dump_thread ? "" : "no ") << "dump thread, " << + (has_requesting_thread ? "" : "no ") << "requesting thread, and " << + (has_process_create_time ? "" : "no ") << "process create time"; bool interrupted = false; bool found_requesting_thread = false; @@ -397,7 +397,7 @@ ProcessResult MinidumpProcessor::Process( Exploitability::ExploitabilityForPlatform( dump, process_state, enable_objdump_for_exploitability_)); // The engine will be null if the platform is not supported - if (exploitability != NULL) { + if (exploitability != nullptr) { process_state->exploitability_ = exploitability->CheckExploitability(); } else { process_state->exploitability_ = EXPLOITABILITY_ERR_NOENGINE; @@ -428,7 +428,7 @@ static const MDRawSystemInfo* GetSystemInfo(Minidump* dump, MinidumpSystemInfo** system_info) { MinidumpSystemInfo* minidump_system_info = dump->GetSystemInfo(); if (!minidump_system_info) - return NULL; + return nullptr; if (system_info) *system_info = minidump_system_info; @@ -461,7 +461,7 @@ static uint64_t GetAddressForArchitecture(const MDCPUArchitecture architecture, // cpu_info: address of target string, cpu info text will be appended to it. static void GetARMCpuInfo(const MDRawSystemInfo* raw_info, string* cpu_info) { - assert(raw_info != NULL && cpu_info != NULL); + assert(raw_info != nullptr && cpu_info != nullptr); // Write ARM architecture version. char cpu_string[32]; @@ -531,7 +531,7 @@ static void GetARMCpuInfo(const MDRawSystemInfo* raw_info, uint32_t cpuid = raw_info->cpu.arm_cpu_info.cpuid; if (cpuid != 0) { // Extract vendor name from CPUID - const char* vendor = NULL; + const char* vendor = nullptr; uint32_t vendor_id = (cpuid >> 24) & 0xff; for (size_t i = 0; i < sizeof(vendors)/sizeof(vendors[0]); ++i) { if (vendors[i].id == vendor_id) { @@ -549,7 +549,7 @@ static void GetARMCpuInfo(const MDRawSystemInfo* raw_info, // Extract part name from CPUID uint32_t part_id = (cpuid & 0xff00fff0); - const char* part = NULL; + const char* part = nullptr; for (size_t i = 0; i < sizeof(parts)/sizeof(parts[0]); ++i) { if (parts[i].id == part_id) { part = parts[i].name; @@ -557,7 +557,7 @@ static void GetARMCpuInfo(const MDRawSystemInfo* raw_info, } } cpu_info->append(" "); - if (part != NULL) { + if (part != nullptr) { cpu_info->append(part); } else { snprintf(cpu_string, sizeof(cpu_string), "part(0x%x)", part_id); @@ -810,13 +810,13 @@ static bool IsCanonicalAddress(uint64_t address) { static void CalculateFaultAddressFromInstruction(Minidump* dump, uint64_t* address) { MinidumpException* exception = dump->GetException(); - if (exception == NULL) { + if (exception == nullptr) { BPLOG(INFO) << "Failed to get exception."; return; } MinidumpContext* context = exception->GetContext(); - if (context == NULL) { + if (context == nullptr) { BPLOG(INFO) << "Failed to get exception context."; return; } @@ -831,7 +831,7 @@ static void CalculateFaultAddressFromInstruction(Minidump* dump, MinidumpMemoryList* memory_list = dump->GetMemoryList(); MinidumpMemoryRegion* memory_region = memory_list ? - memory_list->GetMemoryRegionForAddress(instruction_ptr) : NULL; + memory_list->GetMemoryRegionForAddress(instruction_ptr) : nullptr; if (!memory_region) { BPLOG(INFO) << "No memory region around instruction pointer."; return; @@ -896,7 +896,7 @@ string MinidumpProcessor::GetCrashReason(Minidump* dump, uint64_t* address, flags_string); string reason = reason_string; - const MDRawSystemInfo* raw_system_info = GetSystemInfo(dump, NULL); + const MDRawSystemInfo* raw_system_info = GetSystemInfo(dump, nullptr); if (!raw_system_info) return reason; diff --git a/src/processor/minidump_processor_unittest.cc b/src/processor/minidump_processor_unittest.cc index caef4f2b7..c95cdd9df 100644 --- a/src/processor/minidump_processor_unittest.cc +++ b/src/processor/minidump_processor_unittest.cc @@ -79,12 +79,12 @@ class MockMinidump : public Minidump { class MockMinidumpUnloadedModule : public MinidumpUnloadedModule { public: - MockMinidumpUnloadedModule() : MinidumpUnloadedModule(NULL) {} + MockMinidumpUnloadedModule() : MinidumpUnloadedModule(nullptr) {} }; class MockMinidumpUnloadedModuleList : public MinidumpUnloadedModuleList { public: - MockMinidumpUnloadedModuleList() : MinidumpUnloadedModuleList(NULL) {} + MockMinidumpUnloadedModuleList() : MinidumpUnloadedModuleList(nullptr) {} ~MockMinidumpUnloadedModuleList() {} MOCK_CONST_METHOD0(Copy, CodeModules*()); @@ -94,7 +94,7 @@ class MockMinidumpUnloadedModuleList : public MinidumpUnloadedModuleList { class MockMinidumpThreadList : public MinidumpThreadList { public: - MockMinidumpThreadList() : MinidumpThreadList(NULL) {} + MockMinidumpThreadList() : MinidumpThreadList(nullptr) {} MOCK_CONST_METHOD0(thread_count, unsigned int()); MOCK_CONST_METHOD1(GetThreadAtIndex, MinidumpThread*(unsigned int)); @@ -102,14 +102,14 @@ class MockMinidumpThreadList : public MinidumpThreadList { class MockMinidumpMemoryList : public MinidumpMemoryList { public: - MockMinidumpMemoryList() : MinidumpMemoryList(NULL) {} + MockMinidumpMemoryList() : MinidumpMemoryList(nullptr) {} MOCK_METHOD1(GetMemoryRegionForAddress, MinidumpMemoryRegion*(uint64_t)); }; class MockMinidumpThread : public MinidumpThread { public: - MockMinidumpThread() : MinidumpThread(NULL) {} + MockMinidumpThread() : MinidumpThread(nullptr) {} MOCK_CONST_METHOD1(GetThreadID, bool(uint32_t*)); MOCK_METHOD0(GetContext, MinidumpContext*()); @@ -122,7 +122,7 @@ class MockMinidumpThread : public MinidumpThread { class MockMinidumpMemoryRegion : public MinidumpMemoryRegion { public: MockMinidumpMemoryRegion(uint64_t base, const string& contents) : - MinidumpMemoryRegion(NULL) { + MinidumpMemoryRegion(nullptr) { region_.Init(base, contents); } @@ -150,7 +150,7 @@ class MockMinidumpMemoryRegion : public MinidumpMemoryRegion { class TestMinidumpMiscInfo : public MinidumpMiscInfo { public: explicit TestMinidumpMiscInfo(const MDRawMiscInfo& misc_info) : - MinidumpMiscInfo(NULL) { + MinidumpMiscInfo(nullptr) { valid_ = true; misc_info_ = misc_info; } @@ -295,7 +295,7 @@ SymbolSupplier::SymbolResult TestSymbolSupplier::GetCStringSymbolData( if (s == FOUND) { *symbol_data_size = symbol_data_string.size() + 1; *symbol_data = new char[*symbol_data_size]; - if (*symbol_data == NULL) { + if (*symbol_data == nullptr) { BPLOG(ERROR) << "Memory allocation failed for module: " << module->code_file() << " size: " << *symbol_data_size; return INTERRUPT; @@ -321,7 +321,7 @@ void TestSymbolSupplier::FreeSymbolData(const CodeModule* module) { class TestMinidumpSystemInfo : public MinidumpSystemInfo { public: explicit TestMinidumpSystemInfo(MDRawSystemInfo info) : - MinidumpSystemInfo(NULL) { + MinidumpSystemInfo(nullptr) { valid_ = true; system_info_ = info; csd_version_ = new string(""); @@ -333,7 +333,7 @@ class TestMinidumpSystemInfo : public MinidumpSystemInfo { class TestMinidumpContext : public MinidumpContext { public: explicit TestMinidumpContext(const MDRawContextX86& context) : - MinidumpContext(NULL) { + MinidumpContext(nullptr) { valid_ = true; SetContextX86(new MDRawContextX86(context)); SetContextFlags(MD_CONTEXT_X86); @@ -415,7 +415,7 @@ TEST_F(MinidumpProcessorTest, TestUnloadedModules) { EXPECT_CALL(*unloaded_module_list_copy, GetModuleForAddress(kExpectedEIP)). WillOnce(Return(&unloaded_module)); - MinidumpProcessor processor(reinterpret_cast(NULL), NULL); + MinidumpProcessor processor(static_cast(nullptr), nullptr); ProcessState state; EXPECT_EQ(processor.Process(&dump, &state), google_breakpad::PROCESS_OK); @@ -443,16 +443,16 @@ TEST_F(MinidumpProcessorTest, TestCorruptMinidumps) { MDRawHeader fakeHeader; fakeHeader.time_date_stamp = 0; EXPECT_CALL(dump, header()). - WillOnce(Return(reinterpret_cast(NULL))). + WillOnce(Return(static_cast(nullptr))). WillRepeatedly(Return(&fakeHeader)); EXPECT_EQ(processor.Process(&dump, &state), google_breakpad::PROCESS_ERROR_NO_MINIDUMP_HEADER); EXPECT_CALL(dump, GetThreadList()). - WillOnce(Return(reinterpret_cast(NULL))); + WillOnce(Return(static_cast(nullptr))); EXPECT_CALL(dump, GetSystemInfo()). - WillRepeatedly(Return(reinterpret_cast(NULL))); + WillRepeatedly(Return(static_cast(nullptr))); EXPECT_EQ(processor.Process(&dump, &state), google_breakpad::PROCESS_ERROR_NO_THREAD_LIST); @@ -616,13 +616,13 @@ TEST_F(MinidumpProcessorTest, TestThreadMissingMemory) { WillRepeatedly(DoAll(SetArgumentPointee<0>(1), Return(true))); EXPECT_CALL(no_memory_thread, GetMemory()). - WillRepeatedly(Return(reinterpret_cast(NULL))); + WillRepeatedly(Return(static_cast(nullptr))); const uint64_t kTestStartOfMemoryRange = 0x1234; EXPECT_CALL(no_memory_thread, GetStartOfStackMemoryRange()). WillRepeatedly(Return(kTestStartOfMemoryRange)); EXPECT_CALL(memory_list, GetMemoryRegionForAddress(kTestStartOfMemoryRange)). - WillRepeatedly(Return(reinterpret_cast(NULL))); + WillRepeatedly(Return(static_cast(nullptr))); MDRawContextX86 no_memory_thread_raw_context; memset(&no_memory_thread_raw_context, 0, @@ -639,7 +639,7 @@ TEST_F(MinidumpProcessorTest, TestThreadMissingMemory) { EXPECT_CALL(thread_list, GetThreadAtIndex(0)). WillOnce(Return(&no_memory_thread)); - MinidumpProcessor processor(reinterpret_cast(NULL), NULL); + MinidumpProcessor processor(static_cast(nullptr), nullptr); ProcessState state; EXPECT_EQ(processor.Process(&dump, &state), google_breakpad::PROCESS_OK); @@ -675,7 +675,7 @@ TEST_F(MinidumpProcessorTest, GetProcessCreateTime) { EXPECT_CALL(dump, GetThreadList()).WillOnce(Return(&thread_list)); EXPECT_CALL(thread_list, thread_count()).WillRepeatedly(Return(0)); - MinidumpProcessor processor(reinterpret_cast(NULL), NULL); + MinidumpProcessor processor(static_cast(nullptr), nullptr); ProcessState state; EXPECT_EQ(google_breakpad::PROCESS_OK, processor.Process(&dump, &state)); @@ -716,7 +716,7 @@ TEST_F(MinidumpProcessorTest, TestThreadMissingContext) { WillRepeatedly(DoAll(SetArgumentPointee<0>(1), Return(true))); EXPECT_CALL(no_context_thread, GetContext()). - WillRepeatedly(Return(reinterpret_cast(NULL))); + WillRepeatedly(Return(static_cast(nullptr))); // The memory contents don't really matter here, since it won't be used. MockMinidumpMemoryRegion no_context_thread_memory(0x1234, "xxx"); @@ -732,7 +732,7 @@ TEST_F(MinidumpProcessorTest, TestThreadMissingContext) { EXPECT_CALL(thread_list, GetThreadAtIndex(0)). WillOnce(Return(&no_context_thread)); - MinidumpProcessor processor(reinterpret_cast(NULL), NULL); + MinidumpProcessor processor(static_cast(nullptr), nullptr); ProcessState state; EXPECT_EQ(processor.Process(&dump, &state), google_breakpad::PROCESS_OK); diff --git a/src/processor/minidump_unittest.cc b/src/processor/minidump_unittest.cc index c34ccd4d8..e91ff26a7 100644 --- a/src/processor/minidump_unittest.cc +++ b/src/processor/minidump_unittest.cc @@ -96,13 +96,13 @@ TEST_F(MinidumpTest, TestMinidumpFromFile) { ASSERT_EQ(minidump.path(), minidump_file_); ASSERT_TRUE(minidump.Read()); const MDRawHeader* header = minidump.header(); - ASSERT_NE(header, (MDRawHeader*)NULL); + ASSERT_NE(header, (MDRawHeader*)nullptr); ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE)); MinidumpModuleList* md_module_list = minidump.GetModuleList(); - ASSERT_TRUE(md_module_list != NULL); + ASSERT_TRUE(md_module_list != nullptr); const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0); - ASSERT_TRUE(md_module != NULL); + ASSERT_TRUE(md_module != nullptr); ASSERT_EQ("c:\\test_app.exe", md_module->code_file()); ASSERT_EQ("c:\\test_app.pdb", md_module->debug_file()); ASSERT_EQ("45D35F6C2d000", md_module->code_identifier()); @@ -130,7 +130,7 @@ TEST_F(MinidumpTest, TestMinidumpFromStream) { ASSERT_EQ(minidump.path(), ""); ASSERT_TRUE(minidump.Read()); const MDRawHeader* header = minidump.header(); - ASSERT_NE(header, (MDRawHeader*)NULL); + ASSERT_NE(header, (MDRawHeader*)nullptr); ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE)); //TODO: add more checks here } @@ -145,7 +145,7 @@ TEST_F(MinidumpTest, TestMinidumpWithCrashpadAnnotations) { ASSERT_TRUE(minidump.Read()); MinidumpCrashpadInfo* crashpad_info = minidump.GetCrashpadInfo(); - ASSERT_TRUE(crashpad_info != NULL); + ASSERT_TRUE(crashpad_info != nullptr); const std::vector>* annotation_objects_list = @@ -208,7 +208,7 @@ TEST(Dump, OneStream) { ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(0); - ASSERT_TRUE(dir != NULL); + ASSERT_TRUE(dir != nullptr); EXPECT_EQ(0xfbb7fa2bU, dir->stream_type); uint32_t stream_length; @@ -244,11 +244,11 @@ TEST(Dump, OneMemory) { ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(0); - ASSERT_TRUE(dir != NULL); + ASSERT_TRUE(dir != nullptr); EXPECT_EQ((uint32_t) MD_MEMORY_LIST_STREAM, dir->stream_type); MinidumpMemoryList* memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(memory_list != NULL); + ASSERT_TRUE(memory_list != nullptr); ASSERT_EQ(1U, memory_list->region_count()); MinidumpMemoryRegion* region1 = memory_list->GetMemoryRegionAtIndex(0); @@ -298,7 +298,7 @@ TEST(Dump, OneThread) { ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); MinidumpMemoryList* md_memory_list = minidump.GetMemoryList(); - ASSERT_TRUE(md_memory_list != NULL); + ASSERT_TRUE(md_memory_list != nullptr); ASSERT_EQ(1U, md_memory_list->region_count()); MinidumpMemoryRegion* md_region = md_memory_list->GetMemoryRegionAtIndex(0); @@ -308,23 +308,23 @@ TEST(Dump, OneThread) { ASSERT_TRUE(memcmp("stack for thread", region_bytes, 16) == 0); MinidumpThreadList* thread_list = minidump.GetThreadList(); - ASSERT_TRUE(thread_list != NULL); + ASSERT_TRUE(thread_list != nullptr); ASSERT_EQ(1U, thread_list->thread_count()); MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0); - ASSERT_TRUE(md_thread != NULL); + ASSERT_TRUE(md_thread != nullptr); uint32_t thread_id; ASSERT_TRUE(md_thread->GetThreadID(&thread_id)); ASSERT_EQ(0xa898f11bU, thread_id); MinidumpMemoryRegion* md_stack = md_thread->GetMemory(); - ASSERT_TRUE(md_stack != NULL); + ASSERT_TRUE(md_stack != nullptr); ASSERT_EQ(0x2326a0faU, md_stack->GetBase()); ASSERT_EQ(16U, md_stack->GetSize()); const uint8_t* md_stack_bytes = md_stack->GetMemory(); ASSERT_TRUE(memcmp("stack for thread", md_stack_bytes, 16) == 0); MinidumpContext* md_context = md_thread->GetContext(); - ASSERT_TRUE(md_context != NULL); + ASSERT_TRUE(md_context != nullptr); ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU()); uint64_t eip; @@ -332,7 +332,7 @@ TEST(Dump, OneThread) { EXPECT_EQ(kExpectedEIP, eip); const MDRawContextX86* md_raw_context = md_context->GetContextX86(); - ASSERT_TRUE(md_raw_context != NULL); + ASSERT_TRUE(md_raw_context != nullptr); ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL), (md_raw_context->context_flags & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL))); @@ -378,21 +378,21 @@ TEST(Dump, ThreadMissingMemory) { // This should succeed even though the thread has no stack memory. MinidumpThreadList* thread_list = minidump.GetThreadList(); - ASSERT_TRUE(thread_list != NULL); + ASSERT_TRUE(thread_list != nullptr); ASSERT_EQ(1U, thread_list->thread_count()); MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0); - ASSERT_TRUE(md_thread != NULL); + ASSERT_TRUE(md_thread != nullptr); uint32_t thread_id; ASSERT_TRUE(md_thread->GetThreadID(&thread_id)); ASSERT_EQ(0xa898f11bU, thread_id); MinidumpContext* md_context = md_thread->GetContext(); - ASSERT_NE(reinterpret_cast(NULL), md_context); + ASSERT_NE(static_cast(nullptr), md_context); MinidumpMemoryRegion* md_stack = md_thread->GetMemory(); - ASSERT_EQ(reinterpret_cast(NULL), md_stack); + ASSERT_EQ(static_cast(nullptr), md_stack); } TEST(Dump, ThreadMissingContext) { @@ -421,20 +421,20 @@ TEST(Dump, ThreadMissingContext) { // This should succeed even though the thread has no stack memory. MinidumpThreadList* thread_list = minidump.GetThreadList(); - ASSERT_TRUE(thread_list != NULL); + ASSERT_TRUE(thread_list != nullptr); ASSERT_EQ(1U, thread_list->thread_count()); MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0); - ASSERT_TRUE(md_thread != NULL); + ASSERT_TRUE(md_thread != nullptr); uint32_t thread_id; ASSERT_TRUE(md_thread->GetThreadID(&thread_id)); ASSERT_EQ(0xa898f11bU, thread_id); MinidumpMemoryRegion* md_stack = md_thread->GetMemory(); - ASSERT_NE(reinterpret_cast(NULL), md_stack); + ASSERT_NE(static_cast(nullptr), md_stack); MinidumpContext* md_context = md_thread->GetContext(); - ASSERT_EQ(reinterpret_cast(NULL), md_context); + ASSERT_EQ(static_cast(nullptr), md_context); } TEST(Dump, OneUnloadedModule) { @@ -466,17 +466,17 @@ TEST(Dump, OneUnloadedModule) { ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(1); - ASSERT_TRUE(dir != NULL); + ASSERT_TRUE(dir != nullptr); EXPECT_EQ((uint32_t) MD_UNLOADED_MODULE_LIST_STREAM, dir->stream_type); MinidumpUnloadedModuleList* md_unloaded_module_list = minidump.GetUnloadedModuleList(); - ASSERT_TRUE(md_unloaded_module_list != NULL); + ASSERT_TRUE(md_unloaded_module_list != nullptr); ASSERT_EQ(1U, md_unloaded_module_list->module_count()); const MinidumpUnloadedModule* md_unloaded_module = md_unloaded_module_list->GetModuleAtIndex(0); - ASSERT_TRUE(md_unloaded_module != NULL); + ASSERT_TRUE(md_unloaded_module != nullptr); ASSERT_EQ(0xa90206ca83eb2852ULL, md_unloaded_module->base_address()); ASSERT_EQ(0xada542bd, md_unloaded_module->size()); ASSERT_EQ("unloaded module", md_unloaded_module->code_file()); @@ -487,7 +487,7 @@ TEST(Dump, OneUnloadedModule) { const MDRawUnloadedModule* md_raw_unloaded_module = md_unloaded_module->module(); - ASSERT_TRUE(md_raw_unloaded_module != NULL); + ASSERT_TRUE(md_raw_unloaded_module != nullptr); ASSERT_EQ(0xb1054d2aU, md_raw_unloaded_module->time_date_stamp); ASSERT_EQ(0x34571371U, md_raw_unloaded_module->checksum); } @@ -547,15 +547,15 @@ TEST(Dump, OneModule) { ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(1); - ASSERT_TRUE(dir != NULL); + ASSERT_TRUE(dir != nullptr); EXPECT_EQ((uint32_t) MD_MODULE_LIST_STREAM, dir->stream_type); MinidumpModuleList* md_module_list = minidump.GetModuleList(); - ASSERT_TRUE(md_module_list != NULL); + ASSERT_TRUE(md_module_list != nullptr); ASSERT_EQ(1U, md_module_list->module_count()); const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0); - ASSERT_TRUE(md_module != NULL); + ASSERT_TRUE(md_module != nullptr); ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address()); ASSERT_EQ(0xada542bd, md_module->size()); ASSERT_EQ("single module", md_module->code_file()); @@ -565,7 +565,7 @@ TEST(Dump, OneModule) { ASSERT_EQ("ABCD1234F00DBEEF01020304050607081", md_module->debug_identifier()); const MDRawModule* md_raw_module = md_module->module(); - ASSERT_TRUE(md_raw_module != NULL); + ASSERT_TRUE(md_raw_module != nullptr); ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp); ASSERT_EQ(0x34571371U, md_raw_module->checksum); ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info, @@ -629,11 +629,11 @@ TEST(Dump, OneModuleCVELF) { ASSERT_TRUE(minidump.Read()); MinidumpModuleList* md_module_list = minidump.GetModuleList(); - ASSERT_TRUE(md_module_list != NULL); + ASSERT_TRUE(md_module_list != nullptr); ASSERT_EQ(1U, md_module_list->module_count()); const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0); - ASSERT_TRUE(md_module != NULL); + ASSERT_TRUE(md_module != nullptr); ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address()); ASSERT_EQ(0xada542bd, md_module->size()); ASSERT_EQ("elf module", md_module->code_file()); @@ -647,7 +647,7 @@ TEST(Dump, OneModuleCVELF) { ASSERT_EQ("B4CDA95F53101BDF86FAB733B4DF37380", md_module->debug_identifier()); const MDRawModule* md_raw_module = md_module->module(); - ASSERT_TRUE(md_raw_module != NULL); + ASSERT_TRUE(md_raw_module != nullptr); ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp); ASSERT_EQ(0x34571371U, md_raw_module->checksum); ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info, @@ -711,11 +711,11 @@ TEST(Dump, CVELFShort) { ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); MinidumpModuleList* md_module_list = minidump.GetModuleList(); - ASSERT_TRUE(md_module_list != NULL); + ASSERT_TRUE(md_module_list != nullptr); ASSERT_EQ(1U, md_module_list->module_count()); const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0); - ASSERT_TRUE(md_module != NULL); + ASSERT_TRUE(md_module != nullptr); // just the build_id, directly ASSERT_EQ("5fa9cdb4", md_module->code_identifier()); // build_id expanded to GUID length and treated as such, with zero @@ -783,11 +783,11 @@ TEST(Dump, CVELFLong) { ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); MinidumpModuleList* md_module_list = minidump.GetModuleList(); - ASSERT_TRUE(md_module_list != NULL); + ASSERT_TRUE(md_module_list != nullptr); ASSERT_EQ(1U, md_module_list->module_count()); const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0); - ASSERT_TRUE(md_module != NULL); + ASSERT_TRUE(md_module != nullptr); // just the build_id, directly ASSERT_EQ( "5fa9cdb41053df1b86fab733b4df3738cea34a870102030405060708090a0b0c0d0e0f", @@ -814,11 +814,11 @@ TEST(Dump, OneSystemInfo) { ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(0); - ASSERT_TRUE(dir != NULL); + ASSERT_TRUE(dir != nullptr); EXPECT_EQ((uint32_t) MD_SYSTEM_INFO_STREAM, dir->stream_type); MinidumpSystemInfo* md_system_info = minidump.GetSystemInfo(); - ASSERT_TRUE(md_system_info != NULL); + ASSERT_TRUE(md_system_info != nullptr); ASSERT_EQ("windows", md_system_info->GetOS()); ASSERT_EQ("x86", md_system_info->GetCPU()); ASSERT_EQ("Petulant Pierogi", *md_system_info->GetCSDVersion()); @@ -953,7 +953,7 @@ TEST(Dump, BigDump) { // Check the threads. MinidumpThreadList* thread_list = minidump.GetThreadList(); - ASSERT_TRUE(thread_list != NULL); + ASSERT_TRUE(thread_list != nullptr); ASSERT_EQ(5U, thread_list->thread_count()); uint32_t thread_id; ASSERT_TRUE(thread_list->GetThreadAtIndex(0)->GetThreadID(&thread_id)); @@ -998,7 +998,7 @@ TEST(Dump, BigDump) { // Check the modules. MinidumpModuleList* md_module_list = minidump.GetModuleList(); - ASSERT_TRUE(md_module_list != NULL); + ASSERT_TRUE(md_module_list != nullptr); ASSERT_EQ(3U, md_module_list->module_count()); EXPECT_EQ(0xeb77da57b5d4cbdaULL, md_module_list->GetModuleAtIndex(0)->base_address()); @@ -1010,7 +1010,7 @@ TEST(Dump, BigDump) { // Check unloaded modules MinidumpUnloadedModuleList* md_unloaded_module_list = minidump.GetUnloadedModuleList(); - ASSERT_TRUE(md_unloaded_module_list != NULL); + ASSERT_TRUE(md_unloaded_module_list != nullptr); ASSERT_EQ(3U, md_unloaded_module_list->module_count()); EXPECT_EQ(umodule1_base, md_unloaded_module_list->GetModuleAtIndex(0)->base_address()); @@ -1027,7 +1027,7 @@ TEST(Dump, BigDump) { umodule = md_unloaded_module_list->GetModuleAtSequence(0); EXPECT_EQ(umodule1_base, umodule->base_address()); - EXPECT_EQ(NULL, md_unloaded_module_list->GetMainModule()); + EXPECT_EQ(nullptr, md_unloaded_module_list->GetMainModule()); } @@ -1066,11 +1066,11 @@ TEST(Dump, OneMemoryInfo) { ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(0); - ASSERT_TRUE(dir != NULL); + ASSERT_TRUE(dir != nullptr); EXPECT_EQ((uint32_t) MD_MEMORY_INFO_LIST_STREAM, dir->stream_type); MinidumpMemoryInfoList* info_list = minidump.GetMemoryInfoList(); - ASSERT_TRUE(info_list != NULL); + ASSERT_TRUE(info_list != nullptr); ASSERT_EQ(1U, info_list->info_count()); const MinidumpMemoryInfo* info1 = info_list->GetMemoryInfoAtIndex(0); @@ -1124,24 +1124,24 @@ TEST(Dump, OneExceptionX86) { ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); MinidumpException* md_exception = minidump.GetException(); - ASSERT_TRUE(md_exception != NULL); + ASSERT_TRUE(md_exception != nullptr); uint32_t thread_id; ASSERT_TRUE(md_exception->GetThreadID(&thread_id)); ASSERT_EQ(0x1234abcdU, thread_id); const MDRawExceptionStream* raw_exception = md_exception->exception(); - ASSERT_TRUE(raw_exception != NULL); + ASSERT_TRUE(raw_exception != nullptr); EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code); EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags); EXPECT_EQ(0x0919a9b9c9d9e9f9ULL, raw_exception->exception_record.exception_address); MinidumpContext* md_context = md_exception->GetContext(); - ASSERT_TRUE(md_context != NULL); + ASSERT_TRUE(md_context != nullptr); ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU()); const MDRawContextX86* md_raw_context = md_context->GetContextX86(); - ASSERT_TRUE(md_raw_context != NULL); + ASSERT_TRUE(md_raw_context != nullptr); ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL), (md_raw_context->context_flags & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL))); @@ -1198,24 +1198,24 @@ TEST(Dump, OneExceptionX86XState) { ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); MinidumpException* md_exception = minidump.GetException(); - ASSERT_TRUE(md_exception != NULL); + ASSERT_TRUE(md_exception != nullptr); uint32_t thread_id; ASSERT_TRUE(md_exception->GetThreadID(&thread_id)); ASSERT_EQ(0x1234abcdU, thread_id); const MDRawExceptionStream* raw_exception = md_exception->exception(); - ASSERT_TRUE(raw_exception != NULL); + ASSERT_TRUE(raw_exception != nullptr); EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code); EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags); EXPECT_EQ(0x0919a9b9c9d9e9f9ULL, raw_exception->exception_record.exception_address); MinidumpContext* md_context = md_exception->GetContext(); - ASSERT_TRUE(md_context != NULL); + ASSERT_TRUE(md_context != nullptr); ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU()); const MDRawContextX86* md_raw_context = md_context->GetContextX86(); - ASSERT_TRUE(md_raw_context != NULL); + ASSERT_TRUE(md_raw_context != nullptr); ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL), (md_raw_context->context_flags & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL))); @@ -1283,25 +1283,25 @@ TEST(Dump, OneExceptionX86NoCPUFlags) { ASSERT_EQ(2U, minidump.GetDirectoryEntryCount()); MinidumpException* md_exception = minidump.GetException(); - ASSERT_TRUE(md_exception != NULL); + ASSERT_TRUE(md_exception != nullptr); uint32_t thread_id; ASSERT_TRUE(md_exception->GetThreadID(&thread_id)); ASSERT_EQ(0x1234abcdU, thread_id); const MDRawExceptionStream* raw_exception = md_exception->exception(); - ASSERT_TRUE(raw_exception != NULL); + ASSERT_TRUE(raw_exception != nullptr); EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code); EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags); EXPECT_EQ(0x0919a9b9c9d9e9f9ULL, raw_exception->exception_record.exception_address); MinidumpContext* md_context = md_exception->GetContext(); - ASSERT_TRUE(md_context != NULL); + ASSERT_TRUE(md_context != nullptr); ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU()); const MDRawContextX86* md_raw_context = md_context->GetContextX86(); - ASSERT_TRUE(md_raw_context != NULL); + ASSERT_TRUE(md_raw_context != nullptr); // Even though the CPU flags were missing from the context_flags, the // GetContext call above is expected to load the missing CPU flags from the @@ -1365,14 +1365,14 @@ TEST(Dump, OneExceptionX86NoCPUFlagsNoSystemInfo) { ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); MinidumpException* md_exception = minidump.GetException(); - ASSERT_TRUE(md_exception != NULL); + ASSERT_TRUE(md_exception != nullptr); uint32_t thread_id; ASSERT_TRUE(md_exception->GetThreadID(&thread_id)); ASSERT_EQ(0x1234abcdU, thread_id); const MDRawExceptionStream* raw_exception = md_exception->exception(); - ASSERT_TRUE(raw_exception != NULL); + ASSERT_TRUE(raw_exception != nullptr); EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code); EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags); EXPECT_EQ(0x0919a9b9c9d9e9f9ULL, @@ -1382,7 +1382,7 @@ TEST(Dump, OneExceptionX86NoCPUFlagsNoSystemInfo) { // don't have CPU type information and at the same time the minidump lacks // system info stream so it is impossible to deduce the CPU type. MinidumpContext* md_context = md_exception->GetContext(); - ASSERT_EQ(NULL, md_context); + ASSERT_EQ(nullptr, md_context); } TEST(Dump, OneExceptionARM) { @@ -1428,24 +1428,24 @@ TEST(Dump, OneExceptionARM) { ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); MinidumpException* md_exception = minidump.GetException(); - ASSERT_TRUE(md_exception != NULL); + ASSERT_TRUE(md_exception != nullptr); uint32_t thread_id; ASSERT_TRUE(md_exception->GetThreadID(&thread_id)); ASSERT_EQ(0x1234abcdU, thread_id); const MDRawExceptionStream* raw_exception = md_exception->exception(); - ASSERT_TRUE(raw_exception != NULL); + ASSERT_TRUE(raw_exception != nullptr); EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code); EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags); EXPECT_EQ(0x0919a9b9c9d9e9f9ULL, raw_exception->exception_record.exception_address); MinidumpContext* md_context = md_exception->GetContext(); - ASSERT_TRUE(md_context != NULL); + ASSERT_TRUE(md_context != nullptr); ASSERT_EQ((uint32_t) MD_CONTEXT_ARM, md_context->GetContextCPU()); const MDRawContextARM* md_raw_context = md_context->GetContextARM(); - ASSERT_TRUE(md_raw_context != NULL); + ASSERT_TRUE(md_raw_context != nullptr); ASSERT_EQ((uint32_t) MD_CONTEXT_ARM_INTEGER, (md_raw_context->context_flags & MD_CONTEXT_ARM_INTEGER)); @@ -1512,24 +1512,24 @@ TEST(Dump, OneExceptionARMOldFlags) { ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); MinidumpException* md_exception = minidump.GetException(); - ASSERT_TRUE(md_exception != NULL); + ASSERT_TRUE(md_exception != nullptr); uint32_t thread_id; ASSERT_TRUE(md_exception->GetThreadID(&thread_id)); ASSERT_EQ(0x1234abcdU, thread_id); const MDRawExceptionStream* raw_exception = md_exception->exception(); - ASSERT_TRUE(raw_exception != NULL); + ASSERT_TRUE(raw_exception != nullptr); EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code); EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags); EXPECT_EQ(0x0919a9b9c9d9e9f9ULL, raw_exception->exception_record.exception_address); MinidumpContext* md_context = md_exception->GetContext(); - ASSERT_TRUE(md_context != NULL); + ASSERT_TRUE(md_context != nullptr); ASSERT_EQ((uint32_t) MD_CONTEXT_ARM, md_context->GetContextCPU()); const MDRawContextARM* md_raw_context = md_context->GetContextARM(); - ASSERT_TRUE(md_raw_context != NULL); + ASSERT_TRUE(md_raw_context != nullptr); ASSERT_EQ((uint32_t) MD_CONTEXT_ARM_INTEGER, (md_raw_context->context_flags & MD_CONTEXT_ARM_INTEGER)); @@ -1611,24 +1611,24 @@ TEST(Dump, OneExceptionMIPS) { ASSERT_EQ(1U, minidump.GetDirectoryEntryCount()); MinidumpException* md_exception = minidump.GetException(); - ASSERT_TRUE(md_exception != NULL); + ASSERT_TRUE(md_exception != nullptr); uint32_t thread_id; ASSERT_TRUE(md_exception->GetThreadID(&thread_id)); ASSERT_EQ(0x1234abcdU, thread_id); const MDRawExceptionStream* raw_exception = md_exception->exception(); - ASSERT_TRUE(raw_exception != NULL); + ASSERT_TRUE(raw_exception != nullptr); EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code); EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags); EXPECT_EQ(0x0919a9b9U, raw_exception->exception_record.exception_address); MinidumpContext* md_context = md_exception->GetContext(); - ASSERT_TRUE(md_context != NULL); + ASSERT_TRUE(md_context != nullptr); ASSERT_EQ((uint32_t) MD_CONTEXT_MIPS, md_context->GetContextCPU()); const MDRawContextMIPS* md_raw_context = md_context->GetContextMIPS(); - ASSERT_TRUE(md_raw_context != NULL); + ASSERT_TRUE(md_raw_context != nullptr); ASSERT_EQ((uint32_t) MD_CONTEXT_MIPS_INTEGER, (md_raw_context->context_flags & MD_CONTEXT_MIPS_INTEGER)); EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]); diff --git a/src/processor/module_serializer.cc b/src/processor/module_serializer.cc index 7000c8f94..ba374ce97 100644 --- a/src/processor/module_serializer.cc +++ b/src/processor/module_serializer.cc @@ -134,7 +134,7 @@ char* ModuleSerializer::Serialize(const BasicSourceLineResolver::Module& module, BPLOG(ERROR) << "ModuleSerializer: memory allocation failed, " << "size to alloc: " << size_to_alloc; if (size) *size = 0; - return NULL; + return nullptr; } // Write serialized data to allocated memory chunk. @@ -222,9 +222,9 @@ char* ModuleSerializer::SerializeSymbolFileData(const string& symbol_data, memcpy(buffer.get(), symbol_data.c_str(), symbol_data.size()); buffer.get()[symbol_data.size()] = '\0'; if (!module->LoadMapFromMemory(buffer.get(), symbol_data.size() + 1)) { - return NULL; + return nullptr; } - buffer.reset(NULL); + buffer.reset(nullptr); return Serialize(*module, size); } diff --git a/src/processor/postfix_evaluator-inl.h b/src/processor/postfix_evaluator-inl.h index abdf259ef..61e044e81 100644 --- a/src/processor/postfix_evaluator-inl.h +++ b/src/processor/postfix_evaluator-inl.h @@ -175,7 +175,7 @@ bool PostfixEvaluator::EvaluateToken( // The identifier must name a variable, not a constant. Variables // begin with '$'. string identifier; - if (PopValueOrIdentifier(NULL, &identifier) != POP_RESULT_IDENTIFIER) { + if (PopValueOrIdentifier(nullptr, &identifier) != POP_RESULT_IDENTIFIER) { BPLOG(ERROR) << "PopValueOrIdentifier returned a value, but an " "identifier is needed to assign " << HexString(value) << ": " << expression; @@ -254,7 +254,7 @@ bool PostfixEvaluator::EvaluateForValue(const string& expression, // Ensure that the stack is cleared before returning. AutoStackClearer clearer(&stack_); - if (!EvaluateInternal(expression, NULL)) + if (!EvaluateInternal(expression, nullptr)) return false; // A successful execution should leave exactly one value on the stack. diff --git a/src/processor/postfix_evaluator_unittest.cc b/src/processor/postfix_evaluator_unittest.cc index d3c524092..969ed0ca4 100644 --- a/src/processor/postfix_evaluator_unittest.cc +++ b/src/processor/postfix_evaluator_unittest.cc @@ -225,7 +225,7 @@ static bool RunTests() { FakeMemoryRegion fake_memory; PostfixEvaluator postfix_evaluator = - PostfixEvaluator(NULL, &fake_memory); + PostfixEvaluator(nullptr, &fake_memory); for (unsigned int evaluate_test_set_index = 0; evaluate_test_set_index < evaluate_test_set_count; diff --git a/src/processor/process_state.cc b/src/processor/process_state.cc index 54459c653..03121cb67 100644 --- a/src/processor/process_state.cc +++ b/src/processor/process_state.cc @@ -68,9 +68,9 @@ void ProcessState::Clear() { modules_without_symbols_.clear(); modules_with_corrupt_symbols_.clear(); delete modules_; - modules_ = NULL; + modules_ = nullptr; delete unloaded_modules_; - unloaded_modules_ = NULL; + unloaded_modules_ = nullptr; } } // namespace google_breakpad diff --git a/src/processor/range_map_unittest.cc b/src/processor/range_map_unittest.cc index a15969a57..a4634cc0e 100644 --- a/src/processor/range_map_unittest.cc +++ b/src/processor/range_map_unittest.cc @@ -279,14 +279,15 @@ static bool RetrieveTest(TestMap* range_map, const RangeTest* range_test) { // false if the test fails. static bool RetrieveIndexTest(TestMap* range_map, int set) { linked_ptr object; - CountedObject* last_object = NULL; + CountedObject* last_object = nullptr; AddressType last_base = 0; int object_count = range_map->GetCount(); for (int object_index = 0; object_index < object_count; ++object_index) { AddressType base; if (!range_map->RetrieveRangeAtIndex(object_index, &object, &base, - NULL /* delta */, NULL /* size */)) { + nullptr /* delta */, + nullptr /* size */)) { fprintf(stderr, "FAILED: RetrieveRangeAtIndex set %d index %d, " "expected success, observed failure\n", set, object_index); @@ -295,7 +296,7 @@ static bool RetrieveIndexTest(TestMap* range_map, int set) { if (!object.get()) { fprintf(stderr, "FAILED: RetrieveRangeAtIndex set %d index %d, " - "expected object, observed NULL\n", + "expected object, observed nullptr\n", set, object_index); return false; } @@ -326,8 +327,9 @@ static bool RetrieveIndexTest(TestMap* range_map, int set) { // Make sure that RetrieveRangeAtIndex doesn't allow lookups at indices that // are too high. - if (range_map->RetrieveRangeAtIndex(object_count, &object, NULL /* base */, - NULL /* delta */, NULL /* size */)) { + if (range_map->RetrieveRangeAtIndex(object_count, &object, nullptr /* base */, + nullptr /* delta */, + nullptr /* size */)) { fprintf(stderr, "FAILED: RetrieveRangeAtIndex set %d index %d (too large), " "expected failure, observed success\n", set, object_count); @@ -357,7 +359,8 @@ static bool RetrieveAtIndexTest2() { for (int object_index = 0; object_index < object_count; ++object_index) { AddressType base; if (!range_map->RetrieveRangeAtIndex(object_index, &object, &base, - NULL /* delta */, NULL /* size */)) { + nullptr /* delta */, + nullptr /* size */)) { fprintf(stderr, "FAILED: RetrieveAtIndexTest2 index %d, " "expected success, observed failure\n", object_index); return false; diff --git a/src/processor/simple_serializer-inl.h b/src/processor/simple_serializer-inl.h index 30d0533bd..d3c89b368 100644 --- a/src/processor/simple_serializer-inl.h +++ b/src/processor/simple_serializer-inl.h @@ -193,7 +193,7 @@ class SimpleSerializer< linked_ptr > { typedef BasicSourceLineResolver::Line Line; public: static size_t SizeOf(const linked_ptr& lineptr) { - if (lineptr.get() == NULL) return 0; + if (lineptr.get() == nullptr) return 0; return SimpleSerializer::SizeOf(*(lineptr.get())); } static char* Write(const linked_ptr& lineptr, char* dest) { @@ -209,7 +209,7 @@ class SimpleSerializer> { public: static size_t SizeOf(const linked_ptr& origin_ptr) { - if (origin_ptr.get() == NULL) + if (origin_ptr.get() == nullptr) return 0; return SimpleSerializer::SizeOf(*(origin_ptr.get())); } @@ -238,7 +238,7 @@ class SimpleSerializer> { public: static size_t SizeOf(const linked_ptr& inline_ptr) { - if (inline_ptr.get() == NULL) + if (inline_ptr.get() == nullptr) return 0; return SimpleSerializer::SizeOf(*(inline_ptr.get())); } @@ -343,7 +343,7 @@ class SimpleSerializer< linked_ptr > { typedef BasicSourceLineResolver::PublicSymbol PublicSymbol; public: static size_t SizeOf(const linked_ptr& pubsymbol) { - if (pubsymbol.get() == NULL) return 0; + if (pubsymbol.get() == nullptr) return 0; return SimpleSerializer::SizeOf(*(pubsymbol.get())); } static char* Write(const linked_ptr& pubsymbol, char* dest) { @@ -357,7 +357,7 @@ template<> class SimpleSerializer< linked_ptr > { public: static size_t SizeOf(const linked_ptr& wfi) { - if (wfi.get() == NULL) return 0; + if (wfi.get() == nullptr) return 0; return SimpleSerializer::SizeOf(*(wfi.get())); } static char* Write(const linked_ptr& wfi, char* dest) { diff --git a/src/processor/simple_symbol_supplier.cc b/src/processor/simple_symbol_supplier.cc index 0de34c949..f134d10f0 100644 --- a/src/processor/simple_symbol_supplier.cc +++ b/src/processor/simple_symbol_supplier.cc @@ -114,7 +114,7 @@ SymbolSupplier::SymbolResult SimpleSymbolSupplier::GetCStringSymbolData( if (s == FOUND) { *symbol_data_size = symbol_data_string.size() + 1; *symbol_data = new char[*symbol_data_size]; - if (*symbol_data == NULL) { + if (*symbol_data == nullptr) { BPLOG(ERROR) << "Memory allocation for size " << *symbol_data_size << " failed"; return INTERRUPT; diff --git a/src/processor/source_line_resolver_base.cc b/src/processor/source_line_resolver_base.cc index 351157cea..817ac8a01 100644 --- a/src/processor/source_line_resolver_base.cc +++ b/src/processor/source_line_resolver_base.cc @@ -70,11 +70,11 @@ SourceLineResolverBase::~SourceLineResolverBase() { } // Delete the map of modules. delete modules_; - modules_ = NULL; + modules_ = nullptr; // Delete the set of corrupt modules. delete corrupt_modules_; - corrupt_modules_ = NULL; + corrupt_modules_ = nullptr; MemoryMap::iterator iter = memory_buffers_->begin(); for (; iter != memory_buffers_->end(); ++iter) { @@ -82,16 +82,16 @@ SourceLineResolverBase::~SourceLineResolverBase() { } // Delete the map of memory buffers. delete memory_buffers_; - memory_buffers_ = NULL; + memory_buffers_ = nullptr; delete module_factory_; - module_factory_ = NULL; + module_factory_ = nullptr; } bool SourceLineResolverBase::ReadSymbolFile(const string& map_file, char** symbol_data, size_t* symbol_data_size) { - if (symbol_data == NULL || symbol_data_size == NULL) { + if (symbol_data == nullptr || symbol_data_size == nullptr) { BPLOG(ERROR) << "Could not Read file into Null memory pointer"; return false; } @@ -113,7 +113,7 @@ bool SourceLineResolverBase::ReadSymbolFile(const string& map_file, *symbol_data_size = file_size + 1; *symbol_data = new char[file_size + 1]; - if (*symbol_data == NULL) { + if (*symbol_data == nullptr) { BPLOG(ERROR) << "Could not allocate memory for " << map_file; return false; } @@ -127,7 +127,7 @@ bool SourceLineResolverBase::ReadSymbolFile(const string& map_file, BPLOG(ERROR) << "Could not open " << map_file << ", error " << error_code << ": " << error_string; delete [] (*symbol_data); - *symbol_data = NULL; + *symbol_data = nullptr; return false; } @@ -143,7 +143,7 @@ bool SourceLineResolverBase::ReadSymbolFile(const string& map_file, BPLOG(ERROR) << "Could not slurp " << map_file << ", error " << error_code << ": " << error_string; delete [] (*symbol_data); - *symbol_data = NULL; + *symbol_data = nullptr; return false; } @@ -153,7 +153,7 @@ bool SourceLineResolverBase::ReadSymbolFile(const string& map_file, bool SourceLineResolverBase::LoadModule(const CodeModule* module, const string& map_file) { - if (module == NULL) + if (module == nullptr) return false; // Make sure we don't already have a module with the given name. @@ -193,7 +193,7 @@ bool SourceLineResolverBase::LoadModuleUsingMapBuffer( BPLOG(INFO) << "SourceLineResolverBase::LoadModuleUsingMapBuffer(module = " << module->code_file() << ", map_buffer.size() = " << map_buffer.size() << ")"; - if (module == NULL) + if (module == nullptr) return false; // Make sure we don't already have a module with the given name. @@ -205,7 +205,7 @@ bool SourceLineResolverBase::LoadModuleUsingMapBuffer( size_t memory_buffer_size = map_buffer.size() + 1; char* memory_buffer = new char[memory_buffer_size]; - if (memory_buffer == NULL) { + if (memory_buffer == nullptr) { BPLOG(ERROR) << "Could not allocate memory for " << module->code_file(); return false; } @@ -321,7 +321,7 @@ WindowsFrameInfo* SourceLineResolverBase::FindWindowsFrameInfo( return it->second->FindWindowsFrameInfo(frame); } } - return NULL; + return nullptr; } CFIFrameInfo* SourceLineResolverBase::FindCFIFrameInfo( @@ -332,7 +332,7 @@ CFIFrameInfo* SourceLineResolverBase::FindCFIFrameInfo( return it->second->FindCFIFrameInfo(frame); } } - return NULL; + return nullptr; } bool SourceLineResolverBase::CompareString::operator()( diff --git a/src/processor/stack_frame_symbolizer.cc b/src/processor/stack_frame_symbolizer.cc index fd54fef5f..f54653c26 100644 --- a/src/processor/stack_frame_symbolizer.cc +++ b/src/processor/stack_frame_symbolizer.cc @@ -63,7 +63,7 @@ StackFrameSymbolizer::SymbolizerResult StackFrameSymbolizer::FillSourceLineInfo( std::deque>* inlined_frames) { assert(frame); - const CodeModule* module = NULL; + const CodeModule* module = nullptr; if (modules) { module = modules->GetModuleForAddress(frame->instruction); } @@ -95,7 +95,7 @@ StackFrameSymbolizer::SymbolizerResult StackFrameSymbolizer::FillSourceLineInfo( // Start fetching symbol from supplier. string symbol_file; - char* symbol_data = NULL; + char* symbol_data = nullptr; size_t symbol_data_size; SymbolSupplier::SymbolResult symbol_result = supplier_->GetCStringSymbolData( module, system_info, &symbol_file, &symbol_data, &symbol_data_size); @@ -137,12 +137,12 @@ StackFrameSymbolizer::SymbolizerResult StackFrameSymbolizer::FillSourceLineInfo( WindowsFrameInfo* StackFrameSymbolizer::FindWindowsFrameInfo( const StackFrame* frame) { - return resolver_ ? resolver_->FindWindowsFrameInfo(frame) : NULL; + return resolver_ ? resolver_->FindWindowsFrameInfo(frame) : nullptr; } CFIFrameInfo* StackFrameSymbolizer::FindCFIFrameInfo( const StackFrame* frame) { - return resolver_ ? resolver_->FindCFIFrameInfo(frame) : NULL; + return resolver_ ? resolver_->FindCFIFrameInfo(frame) : nullptr; } } // namespace google_breakpad diff --git a/src/processor/stackwalk_common.cc b/src/processor/stackwalk_common.cc index 688b27823..809836151 100644 --- a/src/processor/stackwalk_common.cc +++ b/src/processor/stackwalk_common.cc @@ -1112,7 +1112,7 @@ static void PrintModulesMachineReadable(const CodeModules* modules) { kOutputSeparator, base_address, kOutputSeparator, base_address + module->size() - 1, kOutputSeparator, - main_module != NULL && base_address == main_address ? 1 : 0); + main_module != nullptr && base_address == main_address ? 1 : 0); } } diff --git a/src/processor/stackwalker.cc b/src/processor/stackwalker.cc index 6a33a326b..e84845ec0 100644 --- a/src/processor/stackwalker.cc +++ b/src/processor/stackwalker.cc @@ -83,7 +83,7 @@ Stackwalker::Stackwalker(const SystemInfo* system_info, : system_info_(system_info), memory_(memory), modules_(modules), - unloaded_modules_(NULL), + unloaded_modules_(nullptr), frame_symbolizer_(frame_symbolizer) { assert(frame_symbolizer_); } @@ -215,10 +215,10 @@ Stackwalker* Stackwalker::StackwalkerForCPU( StackFrameSymbolizer* frame_symbolizer) { if (!context) { BPLOG(ERROR) << "Can't choose a stackwalker implementation without context"; - return NULL; + return nullptr; } - Stackwalker* cpu_stackwalker = NULL; + Stackwalker* cpu_stackwalker = nullptr; uint32_t cpu = context->GetContextCPU(); switch (cpu) { diff --git a/src/processor/stackwalker_address_list.cc b/src/processor/stackwalker_address_list.cc index ca9f5cf9b..a4951ebc1 100644 --- a/src/processor/stackwalker_address_list.cc +++ b/src/processor/stackwalker_address_list.cc @@ -54,7 +54,7 @@ StackwalkerAddressList::StackwalkerAddressList( size_t frame_count, const CodeModules* modules, StackFrameSymbolizer* frame_symbolizer) - : Stackwalker(NULL, NULL, modules, frame_symbolizer), + : Stackwalker(nullptr, nullptr, modules, frame_symbolizer), frames_(frames), frame_count_(frame_count), next_frame_index_(0) { @@ -64,7 +64,7 @@ StackwalkerAddressList::StackwalkerAddressList( StackFrame* StackwalkerAddressList::GetContextFrame() { if (frame_count_ == 0) - return NULL; + return nullptr; StackFrame* frame = new StackFrame(); frame->instruction = frames_[0]; @@ -79,7 +79,7 @@ StackFrame* StackwalkerAddressList::GetCallerFrame(const CallStack*, bool stack_scan_allowed) { // There are no more frames to fetch. if (next_frame_index_ >= frame_count_) - return NULL; + return nullptr; // All frames have the highest level of trust because they were // explicitly provided. diff --git a/src/processor/stackwalker_address_list_unittest.cc b/src/processor/stackwalker_address_list_unittest.cc index bbd033511..1da0b17b2 100644 --- a/src/processor/stackwalker_address_list_unittest.cc +++ b/src/processor/stackwalker_address_list_unittest.cc @@ -101,7 +101,7 @@ class StackwalkerAddressListTest : public testing::Test { void SetModuleSymbols(MockCodeModule* module, const string& info) { size_t buffer_size; char* buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size); - EXPECT_CALL(supplier, GetCStringSymbolData(module, NULL, _, _, _)) + EXPECT_CALL(supplier, GetCStringSymbolData(module, nullptr, _, _, _)) .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer), SetArgumentPointee<4>(buffer_size), Return(MockSymbolSupplier::FOUND))); diff --git a/src/processor/stackwalker_amd64.cc b/src/processor/stackwalker_amd64.cc index 0870a8b5f..5a397fce5 100644 --- a/src/processor/stackwalker_amd64.cc +++ b/src/processor/stackwalker_amd64.cc @@ -59,37 +59,37 @@ StackwalkerAMD64::cfi_register_map_[] = { // flags here really means that the walker should assume they're // unchanged if the CFI doesn't mention them --- clearly wrong for $rip // and $rsp. - { "$rax", NULL, false, + { "$rax", nullptr, false, StackFrameAMD64::CONTEXT_VALID_RAX, &MDRawContextAMD64::rax }, - { "$rdx", NULL, false, + { "$rdx", nullptr, false, StackFrameAMD64::CONTEXT_VALID_RDX, &MDRawContextAMD64::rdx }, - { "$rcx", NULL, false, + { "$rcx", nullptr, false, StackFrameAMD64::CONTEXT_VALID_RCX, &MDRawContextAMD64::rcx }, - { "$rbx", NULL, true, + { "$rbx", nullptr, true, StackFrameAMD64::CONTEXT_VALID_RBX, &MDRawContextAMD64::rbx }, - { "$rsi", NULL, false, + { "$rsi", nullptr, false, StackFrameAMD64::CONTEXT_VALID_RSI, &MDRawContextAMD64::rsi }, - { "$rdi", NULL, false, + { "$rdi", nullptr, false, StackFrameAMD64::CONTEXT_VALID_RDI, &MDRawContextAMD64::rdi }, - { "$rbp", NULL, true, + { "$rbp", nullptr, true, StackFrameAMD64::CONTEXT_VALID_RBP, &MDRawContextAMD64::rbp }, { "$rsp", ".cfa", false, StackFrameAMD64::CONTEXT_VALID_RSP, &MDRawContextAMD64::rsp }, - { "$r8", NULL, false, + { "$r8", nullptr, false, StackFrameAMD64::CONTEXT_VALID_R8, &MDRawContextAMD64::r8 }, - { "$r9", NULL, false, + { "$r9", nullptr, false, StackFrameAMD64::CONTEXT_VALID_R9, &MDRawContextAMD64::r9 }, - { "$r10", NULL, false, + { "$r10", nullptr, false, StackFrameAMD64::CONTEXT_VALID_R10, &MDRawContextAMD64::r10 }, - { "$r11", NULL, false, + { "$r11", nullptr, false, StackFrameAMD64::CONTEXT_VALID_R11, &MDRawContextAMD64::r11 }, - { "$r12", NULL, true, + { "$r12", nullptr, true, StackFrameAMD64::CONTEXT_VALID_R12, &MDRawContextAMD64::r12 }, - { "$r13", NULL, true, + { "$r13", nullptr, true, StackFrameAMD64::CONTEXT_VALID_R13, &MDRawContextAMD64::r13 }, - { "$r14", NULL, true, + { "$r14", nullptr, true, StackFrameAMD64::CONTEXT_VALID_R14, &MDRawContextAMD64::r14 }, - { "$r15", NULL, true, + { "$r15", nullptr, true, StackFrameAMD64::CONTEXT_VALID_R15, &MDRawContextAMD64::r15 }, { "$rip", ".ra", false, StackFrameAMD64::CONTEXT_VALID_RIP, &MDRawContextAMD64::rip }, @@ -114,7 +114,7 @@ uint64_t StackFrameAMD64::ReturnAddress() const { StackFrame* StackwalkerAMD64::GetContextFrame() { if (!context_) { BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; + return nullptr; } StackFrameAMD64* frame = new StackFrameAMD64(); @@ -139,16 +139,16 @@ StackFrameAMD64* StackwalkerAMD64::GetCallerByCFIFrameInfo( .FindCallerRegisters(*memory_, *cfi_frame_info, last_frame->context, last_frame->context_validity, &frame->context, &frame->context_validity)) - return NULL; + return nullptr; // Make sure we recovered all the essentials. static const int essentials = (StackFrameAMD64::CONTEXT_VALID_RIP | StackFrameAMD64::CONTEXT_VALID_RSP); if ((frame->context_validity & essentials) != essentials) - return NULL; + return nullptr; if (!frame->context.rip || !frame->context.rsp) { - return NULL; + return nullptr; } frame->trust = StackFrame::FRAME_TRUST_CFI; @@ -184,7 +184,7 @@ StackFrameAMD64* StackwalkerAMD64::GetCallerByFramePointerRecovery( // If rbp is not 8-byte aligned it can't be a frame pointer. if (last_rbp % 8 != 0) { - return NULL; + return nullptr; } uint64_t caller_rip, caller_rbp; @@ -195,18 +195,18 @@ StackFrameAMD64* StackwalkerAMD64::GetCallerByFramePointerRecovery( // If the recovered rip is not a canonical address it can't be // the return address, so rbp must not have been a frame pointer. if (is_non_canonical(caller_rip)) { - return NULL; + return nullptr; } // Check that rbp is within the right frame if (caller_rsp <= last_rbp || caller_rbp < caller_rsp) { - return NULL; + return nullptr; } // Sanity check that resulting rbp is still inside stack memory. uint64_t unused; if (!memory_->GetMemoryAtAddress(caller_rbp, &unused)) { - return NULL; + return nullptr; } StackFrameAMD64* frame = new StackFrameAMD64(); @@ -221,7 +221,7 @@ StackFrameAMD64* StackwalkerAMD64::GetCallerByFramePointerRecovery( return frame; } - return NULL; + return nullptr; } StackFrameAMD64* StackwalkerAMD64::GetCallerBySimulatingReturn( @@ -235,7 +235,7 @@ StackFrameAMD64* StackwalkerAMD64::GetCallerBySimulatingReturn( searchwords)) { // No plausible return address at the top of the stack. Unable to simulate // a return. - return NULL; + return nullptr; } // Create a new stack frame (ownership will be transferred to the caller) @@ -263,7 +263,7 @@ StackFrameAMD64* StackwalkerAMD64::GetCallerByStackScan( /*is_context_frame=*/last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { // No plausible return address was found. - return NULL; + return nullptr; } // Create a new stack frame (ownership will be transferred to the caller) @@ -308,7 +308,7 @@ StackFrame* StackwalkerAMD64::GetCallerFrame(const CallStack* stack, bool stack_scan_allowed) { if (!memory_ || !stack) { BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; + return nullptr; } const vector& frames = *stack->frames(); @@ -347,7 +347,7 @@ StackFrame* StackwalkerAMD64::GetCallerFrame(const CallStack* stack, // If nothing worked, tell the caller. if (!new_frame.get()) - return NULL; + return nullptr; if (system_info_->os_short == "nacl") { // Apply constraints from Native Client's x86-64 sandbox. These @@ -364,7 +364,7 @@ StackFrame* StackwalkerAMD64::GetCallerFrame(const CallStack* stack, last_frame->context.rsp, /*first_unwind=*/last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { - return NULL; + return nullptr; } // new_frame->context.rip is the return address, which is the instruction diff --git a/src/processor/stackwalker_amd64_unittest.cc b/src/processor/stackwalker_amd64_unittest.cc index 88f6ef7f0..824e9a8f8 100644 --- a/src/processor/stackwalker_amd64_unittest.cc +++ b/src/processor/stackwalker_amd64_unittest.cc @@ -156,7 +156,7 @@ TEST_F(SanityCheck, NoResolver) { raw_context.rip = 0x00007400c0000200ULL; raw_context.rbp = 0x8000000080000000ULL; - StackFrameSymbolizer frame_symbolizer(NULL, NULL); + StackFrameSymbolizer frame_symbolizer(nullptr, nullptr); StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, &frame_symbolizer); // This should succeed even without a resolver or supplier. @@ -208,7 +208,7 @@ TEST_F(GetContextFrame, NoStackMemory) { raw_context.rbp = 0x8000000080000000ULL; StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerAMD64 walker(&system_info, &raw_context, NULL, &modules, + StackwalkerAMD64 walker(&system_info, &raw_context, nullptr, &modules, &frame_symbolizer); vector modules_without_symbols; vector modules_with_corrupt_symbols; diff --git a/src/processor/stackwalker_arm.cc b/src/processor/stackwalker_arm.cc index f9be5ba69..87c928144 100644 --- a/src/processor/stackwalker_arm.cc +++ b/src/processor/stackwalker_arm.cc @@ -65,7 +65,7 @@ StackwalkerARM::StackwalkerARM(const SystemInfo* system_info, StackFrame* StackwalkerARM::GetContextFrame() { if (!context_) { BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; + return nullptr; } StackFrameARM* frame = new StackFrameARM(); @@ -90,7 +90,7 @@ StackFrameARM* StackwalkerARM::GetCallerByCFIFrameInfo( "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "fps", "cpsr", - NULL + nullptr }; // Populate a dictionary with the valid register values in last_frame. @@ -103,7 +103,7 @@ StackFrameARM* StackwalkerARM::GetCallerByCFIFrameInfo( CFIFrameInfo::RegisterValueMap caller_registers; if (!cfi_frame_info->FindCallerRegs(callee_registers, *memory_, &caller_registers)) - return NULL; + return nullptr; // Construct a new stack frame given the values the CFI recovered. std::unique_ptr frame(new StackFrameARM()); @@ -158,7 +158,7 @@ StackFrameARM* StackwalkerARM::GetCallerByCFIFrameInfo( static const int essentials = (StackFrameARM::CONTEXT_VALID_SP | StackFrameARM::CONTEXT_VALID_PC); if ((frame->context_validity & essentials) != essentials) - return NULL; + return nullptr; frame->trust = StackFrame::FRAME_TRUST_CFI; return frame.release(); @@ -174,7 +174,7 @@ StackFrameARM* StackwalkerARM::GetCallerByStackScan( /*is_context_frame=*/last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { // No plausible return address was found. - return NULL; + return nullptr; } // ScanForReturnAddress found a reasonable return address. Advance @@ -202,7 +202,7 @@ StackFrameARM* StackwalkerARM::GetCallerByFramePointer( if (!(last_frame->context_validity & StackFrameARM::RegisterValidFlag(fp_register_))) { - return NULL; + return nullptr; } uint32_t last_fp = last_frame->context.iregs[fp_register_]; @@ -211,14 +211,14 @@ StackFrameARM* StackwalkerARM::GetCallerByFramePointer( if (last_fp && !memory_->GetMemoryAtAddress(last_fp, &caller_fp)) { BPLOG(ERROR) << "Unable to read caller_fp from last_fp: 0x" << std::hex << last_fp; - return NULL; + return nullptr; } uint32_t caller_lr = 0; if (last_fp && !memory_->GetMemoryAtAddress(last_fp + 4, &caller_lr)) { BPLOG(ERROR) << "Unable to read caller_lr from last_fp + 4: 0x" << std::hex << (last_fp + 4); - return NULL; + return nullptr; } uint32_t caller_sp = last_fp ? last_fp + 8 : @@ -246,7 +246,7 @@ StackFrame* StackwalkerARM::GetCallerFrame(const CallStack* stack, bool stack_scan_allowed) { if (!memory_ || !stack) { BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; + return nullptr; } const vector& frames = *stack->frames(); @@ -274,7 +274,7 @@ StackFrame* StackwalkerARM::GetCallerFrame(const CallStack* stack, // If nothing worked, tell the caller. if (!frame.get()) - return NULL; + return nullptr; // Should we terminate the stack walk? (end-of-stack or broken invariant) if (TerminateWalk(frame->context.iregs[MD_CONTEXT_ARM_REG_PC], @@ -282,7 +282,7 @@ StackFrame* StackwalkerARM::GetCallerFrame(const CallStack* stack, last_frame->context.iregs[MD_CONTEXT_ARM_REG_SP], /*first_unwind=*/last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { - return NULL; + return nullptr; } // The new frame's context's PC is the return address, which is one diff --git a/src/processor/stackwalker_arm64.cc b/src/processor/stackwalker_arm64.cc index a851eb0c8..a174fb5b2 100644 --- a/src/processor/stackwalker_arm64.cc +++ b/src/processor/stackwalker_arm64.cc @@ -87,7 +87,7 @@ uint64_t StackwalkerARM64::PtrauthStrip(uint64_t ptr) { StackFrame* StackwalkerARM64::GetContextFrame() { if (!context_) { BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; + return nullptr; } StackFrameARM64* frame = new StackFrameARM64(); @@ -114,7 +114,7 @@ StackFrameARM64* StackwalkerARM64::GetCallerByCFIFrameInfo( "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "sp", - "pc", NULL + "pc", nullptr }; // Populate a dictionary with the valid register values in last_frame. @@ -128,7 +128,7 @@ StackFrameARM64* StackwalkerARM64::GetCallerByCFIFrameInfo( CFIFrameInfo::RegisterValueMap caller_registers; if (!cfi_frame_info->FindCallerRegs(callee_registers, *memory_, &caller_registers)) { - return NULL; + return nullptr; } // Construct a new stack frame given the values the CFI recovered. std::unique_ptr frame(new StackFrameARM64()); @@ -174,7 +174,7 @@ StackFrameARM64* StackwalkerARM64::GetCallerByCFIFrameInfo( static const uint64_t essentials = (StackFrameARM64::CONTEXT_VALID_SP | StackFrameARM64::CONTEXT_VALID_PC); if ((frame->context_validity & essentials) != essentials) - return NULL; + return nullptr; frame->context.iregs[MD_CONTEXT_ARM64_REG_PC] = PtrauthStrip(frame->context.iregs[MD_CONTEXT_ARM64_REG_PC]); @@ -192,7 +192,7 @@ StackFrameARM64* StackwalkerARM64::GetCallerByStackScan( /*is_context_frame=*/last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { // No plausible return address was found. - return NULL; + return nullptr; } // ScanForReturnAddress found a reasonable return address. Advance @@ -227,14 +227,14 @@ StackFrameARM64* StackwalkerARM64::GetCallerByFramePointer( if (last_fp && !memory_->GetMemoryAtAddress(last_fp, &caller_fp)) { BPLOG(ERROR) << "Unable to read caller_fp from last_fp: 0x" << std::hex << last_fp; - return NULL; + return nullptr; } uint64_t caller_lr = 0; if (last_fp && !memory_->GetMemoryAtAddress(last_fp + 8, &caller_lr)) { BPLOG(ERROR) << "Unable to read caller_lr from last_fp + 8: 0x" << std::hex << (last_fp + 8); - return NULL; + return nullptr; } caller_lr = PtrauthStrip(caller_lr); @@ -313,7 +313,7 @@ StackFrame* StackwalkerARM64::GetCallerFrame(const CallStack* stack, bool stack_scan_allowed) { if (!memory_ || !stack) { BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; + return nullptr; } const vector& frames = *stack->frames(); @@ -336,7 +336,7 @@ StackFrame* StackwalkerARM64::GetCallerFrame(const CallStack* stack, // If nothing worked, tell the caller. if (!frame.get()) - return NULL; + return nullptr; // Should we terminate the stack walk? (end-of-stack or broken invariant) if (TerminateWalk(frame->context.iregs[MD_CONTEXT_ARM64_REG_PC], @@ -344,7 +344,7 @@ StackFrame* StackwalkerARM64::GetCallerFrame(const CallStack* stack, last_frame->context.iregs[MD_CONTEXT_ARM64_REG_SP], /*first_unwind=*/last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { - return NULL; + return nullptr; } // The new frame's context's PC is the return address, which is one diff --git a/src/processor/stackwalker_arm64_unittest.cc b/src/processor/stackwalker_arm64_unittest.cc index f302d7d56..24c3527db 100644 --- a/src/processor/stackwalker_arm64_unittest.cc +++ b/src/processor/stackwalker_arm64_unittest.cc @@ -150,7 +150,7 @@ class SanityCheck: public StackwalkerARM64Fixture, public Test { }; TEST_F(SanityCheck, NoResolver) { // Since the context's frame pointer is garbage, the stack walk will end after // the first frame. - StackFrameSymbolizer frame_symbolizer(NULL, NULL); + StackFrameSymbolizer frame_symbolizer(nullptr, nullptr); StackwalkerARM64 walker(&system_info, &raw_context, &stack_region, &modules, &frame_symbolizer); // This should succeed even without a resolver or supplier. @@ -174,7 +174,7 @@ class GetContextFrame: public StackwalkerARM64Fixture, public Test { }; // without stack memory present. TEST_F(GetContextFrame, NoStackMemory) { StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM64 walker(&system_info, &raw_context, NULL, &modules, + StackwalkerARM64 walker(&system_info, &raw_context, nullptr, &modules, &frame_symbolizer); vector modules_without_symbols; vector modules_with_corrupt_symbols; diff --git a/src/processor/stackwalker_arm_unittest.cc b/src/processor/stackwalker_arm_unittest.cc index 6103e2029..eab51c379 100644 --- a/src/processor/stackwalker_arm_unittest.cc +++ b/src/processor/stackwalker_arm_unittest.cc @@ -152,7 +152,7 @@ TEST_F(SanityCheck, NoResolver) { // Since we have no call frame information, and all unwinding // requires call frame information, the stack walk will end after // the first frame. - StackFrameSymbolizer frame_symbolizer(NULL, NULL); + StackFrameSymbolizer frame_symbolizer(nullptr, nullptr); StackwalkerARM walker(&system_info, &raw_context, -1, &stack_region, &modules, &frame_symbolizer); // This should succeed even without a resolver or supplier. @@ -197,7 +197,7 @@ TEST_F(GetContextFrame, Simple) { // without stack memory present. TEST_F(GetContextFrame, NoStackMemory) { StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerARM walker(&system_info, &raw_context, -1, NULL, &modules, + StackwalkerARM walker(&system_info, &raw_context, -1, nullptr, &modules, &frame_symbolizer); vector modules_without_symbols; vector modules_with_corrupt_symbols; diff --git a/src/processor/stackwalker_mips.cc b/src/processor/stackwalker_mips.cc index 2313cd2a8..4a7c0e107 100644 --- a/src/processor/stackwalker_mips.cc +++ b/src/processor/stackwalker_mips.cc @@ -66,7 +66,7 @@ StackwalkerMIPS::StackwalkerMIPS(const SystemInfo* system_info, << HexString(memory_->GetBase()) << "+" << HexString(memory_->GetSize()); - memory_ = NULL; + memory_ = nullptr; } } else { if (0xffffffff - memory_->GetBase() < memory_->GetSize() - 1) { @@ -74,7 +74,7 @@ StackwalkerMIPS::StackwalkerMIPS(const SystemInfo* system_info, << HexString(memory_->GetBase()) << "+" << HexString(memory_->GetSize()); - memory_ = NULL; + memory_ = nullptr; } } } @@ -83,7 +83,7 @@ StackwalkerMIPS::StackwalkerMIPS(const SystemInfo* system_info, StackFrame* StackwalkerMIPS::GetContextFrame() { if (!context_) { BPLOG(ERROR) << "Can't get context frame without context."; - return NULL; + return nullptr; } StackFrameMIPS* frame = new StackFrameMIPS(); @@ -103,7 +103,7 @@ static const char* const kRegisterNames[] = { "$zero", "$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3", "$to", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7", "$t8", "$t9", "$k0", "$k1", "$gp", "$sp", - "$fp", "$ra", NULL + "$fp", "$ra", nullptr // TODO(gordanac): add float point save registers }; @@ -127,7 +127,7 @@ StackFrameMIPS* StackwalkerMIPS::GetCallerByCFIFrameInfo( if (!cfi_frame_info->FindCallerRegs(callee_registers, *memory_, &caller_registers)) { - return NULL; + return nullptr; } CFIFrameInfo::RegisterValueMap::const_iterator entry = @@ -194,7 +194,7 @@ StackFrameMIPS* StackwalkerMIPS::GetCallerByCFIFrameInfo( if (!cfi_frame_info->FindCallerRegs(callee_registers, *memory_, &caller_registers)) { - return NULL; + return nullptr; } CFIFrameInfo::RegisterValueMap::const_iterator entry = @@ -253,7 +253,7 @@ StackFrame* StackwalkerMIPS::GetCallerFrame(const CallStack* stack, bool stack_scan_allowed) { if (!memory_ || !stack) { BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; + return nullptr; } const vector& frames = *stack->frames(); @@ -273,7 +273,7 @@ StackFrame* StackwalkerMIPS::GetCallerFrame(const CallStack* stack, // If nothing worked, tell the caller. if (!new_frame.get()) { - return NULL; + return nullptr; } // Should we terminate the stack walk? (end-of-stack or broken invariant) @@ -282,7 +282,7 @@ StackFrame* StackwalkerMIPS::GetCallerFrame(const CallStack* stack, last_frame->context.iregs[MD_CONTEXT_MIPS_REG_SP], /*first_unwind=*/last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { - return NULL; + return nullptr; } return new_frame.release(); @@ -327,13 +327,13 @@ StackFrameMIPS* StackwalkerMIPS::GetCallerByStackScan( // If we can't find an instruction pointer even with stack scanning, // give up. BPLOG(ERROR) << " ScanForReturnAddress failed "; - return NULL; + return nullptr; } // Get $fp stored in the stack frame. if (!memory_->GetMemoryAtAddress(caller_sp - sizeof(caller_pc), &caller_fp)) { BPLOG(INFO) << " GetMemoryAtAddress for fp failed " ; - return NULL; + return nullptr; } count = count - (caller_sp - last_sp) / sizeof(caller_pc); @@ -343,7 +343,7 @@ StackFrameMIPS* StackwalkerMIPS::GetCallerByStackScan( if (!count) { BPLOG(INFO) << " No frame found " ; - return NULL; + return nullptr; } // ScanForReturnAddress found a reasonable return address. Advance @@ -393,13 +393,13 @@ StackFrameMIPS* StackwalkerMIPS::GetCallerByStackScan( // If we can't find an instruction pointer even with stack scanning, // give up. BPLOG(ERROR) << " ScanForReturnAddress failed "; - return NULL; + return nullptr; } // Get $fp stored in the stack frame. if (!memory_->GetMemoryAtAddress(caller_sp - sizeof(caller_pc), &caller_fp)) { BPLOG(INFO) << " GetMemoryAtAddress for fp failed " ; - return NULL; + return nullptr; } count = count - (caller_sp - last_sp) / sizeof(caller_pc); @@ -409,7 +409,7 @@ StackFrameMIPS* StackwalkerMIPS::GetCallerByStackScan( if (!count) { BPLOG(INFO) << " No frame found " ; - return NULL; + return nullptr; } // ScanForReturnAddress found a reasonable return address. Advance diff --git a/src/processor/stackwalker_mips64_unittest.cc b/src/processor/stackwalker_mips64_unittest.cc index 55b7503fa..f8791e3c4 100644 --- a/src/processor/stackwalker_mips64_unittest.cc +++ b/src/processor/stackwalker_mips64_unittest.cc @@ -158,7 +158,7 @@ TEST_F(SanityCheck, NoResolver) { raw_context.epc = 0x00400020; raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; - StackFrameSymbolizer frame_symbolizer(NULL, NULL); + StackFrameSymbolizer frame_symbolizer(nullptr, nullptr); StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, &frame_symbolizer); // This should succeed, even without a resolver or supplier. @@ -214,7 +214,7 @@ TEST_F(GetContextFrame, NoStackMemory) { raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerMIPS walker(&system_info, &raw_context, NULL, &modules, + StackwalkerMIPS walker(&system_info, &raw_context, nullptr, &modules, &frame_symbolizer); vector modules_without_symbols; vector modules_with_corrupt_symbols; diff --git a/src/processor/stackwalker_mips_unittest.cc b/src/processor/stackwalker_mips_unittest.cc index 305f4db8d..c92d1f0a7 100644 --- a/src/processor/stackwalker_mips_unittest.cc +++ b/src/processor/stackwalker_mips_unittest.cc @@ -156,7 +156,7 @@ TEST_F(SanityCheck, NoResolver) { raw_context.epc = 0x00400020; raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; - StackFrameSymbolizer frame_symbolizer(NULL, NULL); + StackFrameSymbolizer frame_symbolizer(nullptr, nullptr); StackwalkerMIPS walker(&system_info, &raw_context, &stack_region, &modules, &frame_symbolizer); // This should succeed, even without a resolver or supplier. @@ -210,7 +210,7 @@ TEST_F(GetContextFrame, NoStackMemory) { raw_context.iregs[MD_CONTEXT_MIPS_REG_SP] = 0x80000000; StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerMIPS walker(&system_info, &raw_context, NULL, &modules, + StackwalkerMIPS walker(&system_info, &raw_context, nullptr, &modules, &frame_symbolizer); vector modules_without_symbols; vector modules_with_corrupt_symbols; diff --git a/src/processor/stackwalker_ppc.cc b/src/processor/stackwalker_ppc.cc index 0731a4c6d..4afeec83d 100644 --- a/src/processor/stackwalker_ppc.cc +++ b/src/processor/stackwalker_ppc.cc @@ -62,7 +62,7 @@ StackwalkerPPC::StackwalkerPPC(const SystemInfo* system_info, BPLOG(ERROR) << "Memory out of range for stackwalking: " << HexString(memory_->GetBase()) << "+" << HexString(memory_->GetSize()); - memory_ = NULL; + memory_ = nullptr; } } @@ -70,7 +70,7 @@ StackwalkerPPC::StackwalkerPPC(const SystemInfo* system_info, StackFrame* StackwalkerPPC::GetContextFrame() { if (!context_) { BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; + return nullptr; } StackFramePPC* frame = new StackFramePPC(); @@ -90,7 +90,7 @@ StackFrame* StackwalkerPPC::GetCallerFrame(const CallStack* stack, bool stack_scan_allowed) { if (!memory_ || !stack) { BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; + return nullptr; } // The instruction pointers for previous frames are saved on the stack. @@ -112,7 +112,7 @@ StackFrame* StackwalkerPPC::GetCallerFrame(const CallStack* stack, if (!memory_->GetMemoryAtAddress(last_frame->context.gpr[1], &stack_pointer) || stack_pointer <= last_frame->context.gpr[1]) { - return NULL; + return nullptr; } // Mac OS X/Darwin gives 1 as the return address from the bottom-most @@ -123,7 +123,7 @@ StackFrame* StackwalkerPPC::GetCallerFrame(const CallStack* stack, uint32_t instruction; if (!memory_->GetMemoryAtAddress(stack_pointer + 8, &instruction) || instruction <= 1) { - return NULL; + return nullptr; } std::unique_ptr frame(new StackFramePPC()); @@ -139,7 +139,7 @@ StackFrame* StackwalkerPPC::GetCallerFrame(const CallStack* stack, if (TerminateWalk(instruction, stack_pointer, last_frame->context.gpr[1], /*first_unwind=*/last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { - return NULL; + return nullptr; } // frame->context.srr0 is the return address, which is one instruction diff --git a/src/processor/stackwalker_ppc64.cc b/src/processor/stackwalker_ppc64.cc index 973eb71fa..f0298f2bc 100644 --- a/src/processor/stackwalker_ppc64.cc +++ b/src/processor/stackwalker_ppc64.cc @@ -61,7 +61,7 @@ StackwalkerPPC64::StackwalkerPPC64(const SystemInfo* system_info, StackFrame* StackwalkerPPC64::GetContextFrame() { if (!context_) { BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; + return nullptr; } StackFramePPC64* frame = new StackFramePPC64(); @@ -81,7 +81,7 @@ StackFrame* StackwalkerPPC64::GetCallerFrame(const CallStack* stack, bool stack_scan_allowed) { if (!memory_ || !stack) { BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; + return nullptr; } // The instruction pointers for previous frames are saved on the stack. @@ -103,7 +103,7 @@ StackFrame* StackwalkerPPC64::GetCallerFrame(const CallStack* stack, if (!memory_->GetMemoryAtAddress(last_frame->context.gpr[1], &stack_pointer) || stack_pointer <= last_frame->context.gpr[1]) { - return NULL; + return nullptr; } // Mac OS X/Darwin gives 1 as the return address from the bottom-most @@ -114,7 +114,7 @@ StackFrame* StackwalkerPPC64::GetCallerFrame(const CallStack* stack, uint64_t instruction; if (!memory_->GetMemoryAtAddress(stack_pointer + 16, &instruction) || instruction <= 1) { - return NULL; + return nullptr; } std::unique_ptr frame(new StackFramePPC64()); @@ -130,7 +130,7 @@ StackFrame* StackwalkerPPC64::GetCallerFrame(const CallStack* stack, if (TerminateWalk(instruction, stack_pointer, last_frame->context.gpr[1], /*is_context_frame=*/last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { - return NULL; + return nullptr; } // frame->context.srr0 is the return address, which is one instruction diff --git a/src/processor/stackwalker_riscv.cc b/src/processor/stackwalker_riscv.cc index 1b2fb5809..d350fe54f 100644 --- a/src/processor/stackwalker_riscv.cc +++ b/src/processor/stackwalker_riscv.cc @@ -64,7 +64,7 @@ StackwalkerRISCV::StackwalkerRISCV(const SystemInfo* system_info, StackFrame* StackwalkerRISCV::GetContextFrame() { if (!context_) { BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; + return nullptr; } StackFrameRISCV* frame = new StackFrameRISCV(); @@ -154,7 +154,7 @@ StackFrameRISCV* StackwalkerRISCV::GetCallerByCFIFrameInfo( CFIFrameInfo::RegisterValueMap caller_registers; if (!cfi_frame_info->FindCallerRegs(callee_registers, *memory_, &caller_registers)) { - return NULL; + return nullptr; } // Construct a new stack frame given the values the CFI recovered. @@ -411,7 +411,7 @@ StackFrameRISCV* StackwalkerRISCV::GetCallerByCFIFrameInfo( static const uint64_t essentials = (StackFrameRISCV::CONTEXT_VALID_SP | StackFrameRISCV::CONTEXT_VALID_PC); if ((frame->context_validity & essentials) != essentials) - return NULL; + return nullptr; frame->trust = StackFrame::FRAME_TRUST_CFI; return frame.release(); @@ -427,7 +427,7 @@ StackFrameRISCV* StackwalkerRISCV::GetCallerByStackScan( if (!ScanForReturnAddress(last_sp, &caller_sp, &caller_pc, last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { // No plausible return address was found. - return NULL; + return nullptr; } // ScanForReturnAddress found a reasonable return address. Advance @@ -460,14 +460,14 @@ StackFrameRISCV* StackwalkerRISCV::GetCallerByStackScan( if (last_fp && !memory_->GetMemoryAtAddress(last_fp, &caller_fp)) { BPLOG(ERROR) << "Unable to read caller_fp from last_fp: 0x" << std::hex << last_fp; - return NULL; + return nullptr; } uint32_t caller_ra = 0; if (last_fp && !memory_->GetMemoryAtAddress(last_fp + 4, &caller_ra)) { BPLOG(ERROR) << "Unable to read caller_ra from last_fp + 4: 0x" << std::hex << (last_fp + 4); - return NULL; + return nullptr; } uint32_t caller_sp = last_fp ? last_fp + 8 : last_frame->context.s0; @@ -493,7 +493,7 @@ StackFrame* StackwalkerRISCV::GetCallerFrame(const CallStack* stack, bool stack_scan_allowed) { if (!memory_ || !stack) { BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; + return nullptr; } const vector& frames = *stack->frames(); @@ -517,13 +517,13 @@ StackFrame* StackwalkerRISCV::GetCallerFrame(const CallStack* stack, // If nothing worked, tell the caller. if (!frame.get()) - return NULL; + return nullptr; // Should we terminate the stack walk? (end-of-stack or broken invariant) if (TerminateWalk(frame->context.pc, frame->context.sp, last_frame->context.sp, last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { - return NULL; + return nullptr; } // The new frame's context's PC is the return address, which is one diff --git a/src/processor/stackwalker_riscv64.cc b/src/processor/stackwalker_riscv64.cc index 528aeed72..3da914db9 100644 --- a/src/processor/stackwalker_riscv64.cc +++ b/src/processor/stackwalker_riscv64.cc @@ -64,7 +64,7 @@ StackwalkerRISCV64::StackwalkerRISCV64(const SystemInfo* system_info, StackFrame* StackwalkerRISCV64::GetContextFrame() { if (!context_) { BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; + return nullptr; } StackFrameRISCV64* frame = new StackFrameRISCV64(); @@ -154,7 +154,7 @@ StackFrameRISCV64* StackwalkerRISCV64::GetCallerByCFIFrameInfo( CFIFrameInfo::RegisterValueMap caller_registers; if (!cfi_frame_info->FindCallerRegs(callee_registers, *memory_, &caller_registers)) { - return NULL; + return nullptr; } // Construct a new stack frame given the values the CFI recovered. @@ -411,7 +411,7 @@ StackFrameRISCV64* StackwalkerRISCV64::GetCallerByCFIFrameInfo( static const uint64_t essentials = (StackFrameRISCV64::CONTEXT_VALID_SP | StackFrameRISCV64::CONTEXT_VALID_PC); if ((frame->context_validity & essentials) != essentials) - return NULL; + return nullptr; frame->trust = StackFrame::FRAME_TRUST_CFI; return frame.release(); @@ -427,7 +427,7 @@ StackFrameRISCV64* StackwalkerRISCV64::GetCallerByStackScan( if (!ScanForReturnAddress(last_sp, &caller_sp, &caller_pc, last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { // No plausible return address was found. - return NULL; + return nullptr; } // ScanForReturnAddress found a reasonable return address. Advance @@ -460,14 +460,14 @@ StackFrameRISCV64* StackwalkerRISCV64::GetCallerByFramePointer( if (last_fp && !memory_->GetMemoryAtAddress(last_fp, &caller_fp)) { BPLOG(ERROR) << "Unable to read caller_fp from last_fp: 0x" << std::hex << last_fp; - return NULL; + return nullptr; } uint64_t caller_ra = 0; if (last_fp && !memory_->GetMemoryAtAddress(last_fp + 8, &caller_ra)) { BPLOG(ERROR) << "Unable to read caller_ra from last_fp + 8: 0x" << std::hex << (last_fp + 8); - return NULL; + return nullptr; } uint64_t caller_sp = last_fp ? last_fp + 16 : last_frame->context.s0; @@ -493,7 +493,7 @@ StackFrame* StackwalkerRISCV64::GetCallerFrame(const CallStack* stack, bool stack_scan_allowed) { if (!memory_ || !stack) { BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; + return nullptr; } const vector& frames = *stack->frames(); @@ -517,13 +517,13 @@ StackFrame* StackwalkerRISCV64::GetCallerFrame(const CallStack* stack, // If nothing worked, tell the caller. if (!frame.get()) - return NULL; + return nullptr; // Should we terminate the stack walk? (end-of-stack or broken invariant) if (TerminateWalk(frame->context.pc, frame->context.sp, last_frame->context.sp, last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { - return NULL; + return nullptr; } // The new frame's context's PC is the return address, which is one diff --git a/src/processor/stackwalker_riscv64_unittest.cc b/src/processor/stackwalker_riscv64_unittest.cc index c8579b9b9..5f02c0d9f 100644 --- a/src/processor/stackwalker_riscv64_unittest.cc +++ b/src/processor/stackwalker_riscv64_unittest.cc @@ -151,7 +151,7 @@ class SanityCheck: public StackwalkerRISCV64Fixture, public Test { }; TEST_F(SanityCheck, NoResolver) { // Since the context's frame pointer is garbage, the stack walk will end after // the first frame. - StackFrameSymbolizer frame_symbolizer(NULL, NULL); + StackFrameSymbolizer frame_symbolizer(nullptr, nullptr); StackwalkerRISCV64 walker(&system_info, &raw_context, &stack_region, &modules, &frame_symbolizer); // This should succeed even without a resolver or supplier. @@ -175,7 +175,7 @@ class GetContextFrame: public StackwalkerRISCV64Fixture, public Test { }; // without stack memory present. TEST_F(GetContextFrame, NoStackMemory) { StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerRISCV64 walker(&system_info, &raw_context, NULL, &modules, + StackwalkerRISCV64 walker(&system_info, &raw_context, nullptr, &modules, &frame_symbolizer); vector modules_without_symbols; vector modules_with_corrupt_symbols; diff --git a/src/processor/stackwalker_riscv_unittest.cc b/src/processor/stackwalker_riscv_unittest.cc index 37f0e233a..555b55d01 100644 --- a/src/processor/stackwalker_riscv_unittest.cc +++ b/src/processor/stackwalker_riscv_unittest.cc @@ -151,7 +151,7 @@ class SanityCheck: public StackwalkerRISCVFixture, public Test { }; TEST_F(SanityCheck, NoResolver) { // Since the context's frame pointer is garbage, the stack walk will end after // the first frame. - StackFrameSymbolizer frame_symbolizer(NULL, NULL); + StackFrameSymbolizer frame_symbolizer(nullptr, nullptr); StackwalkerRISCV walker(&system_info, &raw_context, &stack_region, &modules, &frame_symbolizer); // This should succeed even without a resolver or supplier. @@ -175,7 +175,7 @@ class GetContextFrame: public StackwalkerRISCVFixture, public Test { }; // without stack memory present. TEST_F(GetContextFrame, NoStackMemory) { StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerRISCV walker(&system_info, &raw_context, NULL, &modules, + StackwalkerRISCV walker(&system_info, &raw_context, nullptr, &modules, &frame_symbolizer); vector modules_without_symbols; vector modules_with_corrupt_symbols; diff --git a/src/processor/stackwalker_selftest.cc b/src/processor/stackwalker_selftest.cc index 19330b53c..977567cce 100644 --- a/src/processor/stackwalker_selftest.cc +++ b/src/processor/stackwalker_selftest.cc @@ -325,23 +325,23 @@ static unsigned int CountCallerFrames() { context.ebp = GetEBP(); context.esp = GetESP(); - StackwalkerX86 stackwalker = StackwalkerX86(NULL, &context, &memory, NULL, - NULL, &resolver); + StackwalkerX86 stackwalker = StackwalkerX86(nullptr, &context, &memory, + nullptr, nullptr, &resolver); #elif defined(__ppc__) MDRawContextPPC context = MDRawContextPPC(); context.srr0 = GetPC(); context.gpr[1] = GetSP(); - StackwalkerPPC stackwalker = StackwalkerPPC(NULL, &context, &memory, NULL, - NULL, &resolver); + StackwalkerPPC stackwalker = StackwalkerPPC(nullptr, &context, &memory, + nullptr, nullptr, &resolver); #elif defined(__sparc__) MDRawContextSPARC context = MDRawContextSPARC(); context.pc = GetPC(); context.g_r[14] = GetSP(); context.g_r[30] = GetFP(); - StackwalkerSPARC stackwalker = StackwalkerSPARC(NULL, &context, &memory, - NULL, NULL, &resolver); + StackwalkerSPARC stackwalker = StackwalkerSPARC(nullptr, &context, &memory, + nullptr, nullptr, &resolver); #endif // __i386__ || __ppc__ || __sparc__ CallStack stack; diff --git a/src/processor/stackwalker_sparc.cc b/src/processor/stackwalker_sparc.cc index ed7f7dc3d..9fc78a2e6 100644 --- a/src/processor/stackwalker_sparc.cc +++ b/src/processor/stackwalker_sparc.cc @@ -59,7 +59,7 @@ StackwalkerSPARC::StackwalkerSPARC(const SystemInfo* system_info, StackFrame* StackwalkerSPARC::GetContextFrame() { if (!context_) { BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; + return nullptr; } StackFrameSPARC* frame = new StackFrameSPARC(); @@ -79,7 +79,7 @@ StackFrame* StackwalkerSPARC::GetCallerFrame(const CallStack* stack, bool stack_scan_allowed) { if (!memory_ || !stack) { BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; + return nullptr; } StackFrameSPARC* last_frame = static_cast( @@ -99,26 +99,26 @@ StackFrame* StackwalkerSPARC::GetCallerFrame(const CallStack* stack, // end of the stack. uint64_t stack_pointer = last_frame->context.g_r[30]; if (stack_pointer <= last_frame->context.g_r[14]) { - return NULL; + return nullptr; } uint32_t instruction; if (!memory_->GetMemoryAtAddress(stack_pointer + 60, &instruction) || instruction <= 1) { - return NULL; + return nullptr; } uint32_t stack_base; if (!memory_->GetMemoryAtAddress(stack_pointer + 56, &stack_base) || stack_base <= 1) { - return NULL; + return nullptr; } // Should we terminate the stack walk? (end-of-stack or broken invariant) if (TerminateWalk(instruction, stack_pointer, last_frame->context.g_r[14], /*is_context_frame=*/last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { - return NULL; + return nullptr; } StackFrameSPARC* frame = new StackFrameSPARC(); diff --git a/src/processor/stackwalker_unittest_utils.h b/src/processor/stackwalker_unittest_utils.h index 3d651b2cb..ef09ebbd7 100644 --- a/src/processor/stackwalker_unittest_utils.h +++ b/src/processor/stackwalker_unittest_utils.h @@ -147,7 +147,7 @@ class MockCodeModules: public google_breakpad::CodeModules { address - module->base_address() < module->size()) return module; } - return NULL; + return nullptr; }; const CodeModule* GetMainModule() const { return modules_[0]; } diff --git a/src/processor/stackwalker_x86.cc b/src/processor/stackwalker_x86.cc index 7ed22998b..ae8706d1a 100644 --- a/src/processor/stackwalker_x86.cc +++ b/src/processor/stackwalker_x86.cc @@ -72,19 +72,19 @@ StackwalkerX86::cfi_register_map_[] = { StackFrameX86::CONTEXT_VALID_EIP, &MDRawContextX86::eip }, { "$esp", ".cfa", false, StackFrameX86::CONTEXT_VALID_ESP, &MDRawContextX86::esp }, - { "$ebp", NULL, true, + { "$ebp", nullptr, true, StackFrameX86::CONTEXT_VALID_EBP, &MDRawContextX86::ebp }, - { "$eax", NULL, false, + { "$eax", nullptr, false, StackFrameX86::CONTEXT_VALID_EAX, &MDRawContextX86::eax }, - { "$ebx", NULL, true, + { "$ebx", nullptr, true, StackFrameX86::CONTEXT_VALID_EBX, &MDRawContextX86::ebx }, - { "$ecx", NULL, false, + { "$ecx", nullptr, false, StackFrameX86::CONTEXT_VALID_ECX, &MDRawContextX86::ecx }, - { "$edx", NULL, false, + { "$edx", nullptr, false, StackFrameX86::CONTEXT_VALID_EDX, &MDRawContextX86::edx }, - { "$esi", NULL, true, + { "$esi", nullptr, true, StackFrameX86::CONTEXT_VALID_ESI, &MDRawContextX86::esi }, - { "$edi", NULL, true, + { "$edi", nullptr, true, StackFrameX86::CONTEXT_VALID_EDI, &MDRawContextX86::edi }, }; @@ -103,17 +103,17 @@ StackwalkerX86::StackwalkerX86(const SystemInfo* system_info, BPLOG(ERROR) << "Memory out of range for stackwalking: " << HexString(memory_->GetBase()) << "+" << HexString(memory_->GetSize()); - memory_ = NULL; + memory_ = nullptr; } } StackFrameX86::~StackFrameX86() { if (windows_frame_info) delete windows_frame_info; - windows_frame_info = NULL; + windows_frame_info = nullptr; if (cfi_frame_info) delete cfi_frame_info; - cfi_frame_info = NULL; + cfi_frame_info = nullptr; } uint64_t StackFrameX86::ReturnAddress() const { @@ -124,7 +124,7 @@ uint64_t StackFrameX86::ReturnAddress() const { StackFrame* StackwalkerX86::GetContextFrame() { if (!context_) { BPLOG(ERROR) << "Can't get context frame without context"; - return NULL; + return nullptr; } StackFrameX86* frame = new StackFrameX86(); @@ -158,7 +158,7 @@ StackFrameX86* StackwalkerX86::GetCallerByWindowsFrameInfo( // last_frame_info is VALID_PARAMETER_SIZE-only, then we should // assume the traditional frame format or use some other strategy. if (last_frame_info->valid != WindowsFrameInfo::VALID_ALL) - return NULL; + return nullptr; // This stackwalker sets each frame's %esp to its value immediately prior // to the CALL into the callee. This means that %esp points to the last @@ -255,7 +255,7 @@ StackFrameX86* StackwalkerX86::GetCallerByWindowsFrameInfo( // for calculation of the value of .raSearchStart are available. if (ScanForReturnAddress(raSearchStart, &raSearchStart, &found, 3) && last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT && - last_frame->windows_frame_info != NULL && + last_frame->windows_frame_info != nullptr && last_frame_info->type_ == WindowsFrameInfo::STACK_INFO_FPO && raSearchStartOld == raSearchStart && found == last_frame->context.eip) { @@ -404,7 +404,7 @@ StackFrameX86* StackwalkerX86::GetCallerByWindowsFrameInfo( StackFrame::FRAME_TRUST_CONTEXT)) { // if we can't find an instruction pointer even with stack scanning, // give up. - return NULL; + return nullptr; } // This seems like a reasonable return address. Since program string @@ -542,14 +542,14 @@ StackFrameX86* StackwalkerX86::GetCallerByCFIFrameInfo( .FindCallerRegisters(*memory_, *cfi_frame_info, last_frame->context, last_frame->context_validity, &frame->context, &frame->context_validity)) - return NULL; + return nullptr; // Make sure we recovered all the essentials. static const int essentials = (StackFrameX86::CONTEXT_VALID_EIP | StackFrameX86::CONTEXT_VALID_ESP | StackFrameX86::CONTEXT_VALID_EBP); if ((frame->context_validity & essentials) != essentials) - return NULL; + return nullptr; frame->trust = StackFrame::FRAME_TRUST_CFI; @@ -608,7 +608,7 @@ StackFrameX86* StackwalkerX86::GetCallerByEBPAtBase( StackFrame::FRAME_TRUST_CONTEXT)) { // if we can't find an instruction pointer even with stack scanning, // give up. - return NULL; + return nullptr; } // ScanForReturnAddress found a reasonable return address. Advance %esp to @@ -651,7 +651,7 @@ StackFrame* StackwalkerX86::GetCallerFrame(const CallStack* stack, bool stack_scan_allowed) { if (!memory_ || !stack) { BPLOG(ERROR) << "Can't get caller frame without memory or stack"; - return NULL; + return nullptr; } const vector& frames = *stack->frames(); @@ -682,14 +682,14 @@ StackFrame* StackwalkerX86::GetCallerFrame(const CallStack* stack, // If nothing worked, tell the caller. if (!new_frame.get()) - return NULL; + return nullptr; // Should we terminate the stack walk? (end-of-stack or broken invariant) if (TerminateWalk(new_frame->context.eip, new_frame->context.esp, last_frame->context.esp, /*first_unwind=*/last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { - return NULL; + return nullptr; } // new_frame->context.eip is the return address, which is the instruction diff --git a/src/processor/stackwalker_x86_unittest.cc b/src/processor/stackwalker_x86_unittest.cc index b614b0e44..e5bb63e49 100644 --- a/src/processor/stackwalker_x86_unittest.cc +++ b/src/processor/stackwalker_x86_unittest.cc @@ -166,7 +166,7 @@ TEST_F(SanityCheck, NoResolver) { raw_context.eip = 0x40000200; raw_context.ebp = 0x80000000; - StackFrameSymbolizer frame_symbolizer(NULL, NULL); + StackFrameSymbolizer frame_symbolizer(nullptr, nullptr); StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules, &frame_symbolizer); // This should succeed, even without a resolver or supplier. @@ -217,7 +217,7 @@ TEST_F(GetContextFrame, NoStackMemory) { raw_context.ebp = 0x80000000; StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); - StackwalkerX86 walker(&system_info, &raw_context, NULL, &modules, + StackwalkerX86 walker(&system_info, &raw_context, nullptr, &modules, &frame_symbolizer); vector modules_without_symbols; vector modules_with_corrupt_symbols; @@ -278,7 +278,7 @@ TEST_F(GetCallerFrame, Traditional) { EXPECT_EQ(0x4000c7a5U, frame0->instruction); EXPECT_EQ(0x4000c7a5U, frame0->context.eip); EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp); - EXPECT_EQ(NULL, frame0->windows_frame_info); + EXPECT_EQ(nullptr, frame0->windows_frame_info); } { // To avoid reusing locals by mistake @@ -291,7 +291,7 @@ TEST_F(GetCallerFrame, Traditional) { EXPECT_EQ(0x40008679U, frame1->instruction + 1); EXPECT_EQ(0x40008679U, frame1->context.eip); EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_EQ(NULL, frame1->windows_frame_info); + EXPECT_EQ(nullptr, frame1->windows_frame_info); } } @@ -343,7 +343,7 @@ TEST_F(GetCallerFrame, TraditionalScan) { EXPECT_EQ(0x4000f49dU, frame0->context.eip); EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); EXPECT_EQ(0xd43eed6eU, frame0->context.ebp); - EXPECT_EQ(NULL, frame0->windows_frame_info); + EXPECT_EQ(nullptr, frame0->windows_frame_info); } { // To avoid reusing locals by mistake @@ -357,7 +357,7 @@ TEST_F(GetCallerFrame, TraditionalScan) { EXPECT_EQ(0x4000129dU, frame1->context.eip); EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_EQ(NULL, frame1->windows_frame_info); + EXPECT_EQ(nullptr, frame1->windows_frame_info); } } @@ -409,7 +409,7 @@ TEST_F(GetCallerFrame, TraditionalScanLongWay) { EXPECT_EQ(0x4000f49dU, frame0->context.eip); EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); EXPECT_EQ(0xd43eed6eU, frame0->context.ebp); - EXPECT_EQ(NULL, frame0->windows_frame_info); + EXPECT_EQ(nullptr, frame0->windows_frame_info); } { // To avoid reusing locals by mistake @@ -423,7 +423,7 @@ TEST_F(GetCallerFrame, TraditionalScanLongWay) { EXPECT_EQ(0x4000129dU, frame1->context.eip); EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_EQ(NULL, frame1->windows_frame_info); + EXPECT_EQ(nullptr, frame1->windows_frame_info); } } @@ -475,7 +475,7 @@ TEST_F(GetCallerFrame, ScanningNotAllowed) { EXPECT_EQ(0x4000f49dU, frame0->context.eip); EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); EXPECT_EQ(0xd43eed6eU, frame0->context.ebp); - EXPECT_EQ(NULL, frame0->windows_frame_info); + EXPECT_EQ(nullptr, frame0->windows_frame_info); } } @@ -534,7 +534,7 @@ TEST_F(GetCallerFrame, WindowsFrameData) { EXPECT_EQ(0x4000aa85U, frame0->context.eip); EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); EXPECT_EQ(0xf052c1deU, frame0->context.ebp); - EXPECT_TRUE(frame0->windows_frame_info != NULL); + EXPECT_TRUE(frame0->windows_frame_info != nullptr); } { // To avoid reusing locals by mistake @@ -554,7 +554,7 @@ TEST_F(GetCallerFrame, WindowsFrameData) { EXPECT_EQ(0x9068a878U, frame1->context.ebx); EXPECT_EQ(0xa7120d1aU, frame1->context.esi); EXPECT_EQ(0x630891beU, frame1->context.edi); - EXPECT_EQ(NULL, frame1->windows_frame_info); + EXPECT_EQ(nullptr, frame1->windows_frame_info); } } @@ -615,7 +615,7 @@ TEST_F(GetCallerFrame, WindowsFrameDataAligned) { EXPECT_EQ(0x4000aa85U, frame0->context.eip); EXPECT_EQ(frame0_esp.Value(), frame0->context.esp); EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp); - EXPECT_TRUE(frame0->windows_frame_info != NULL); + EXPECT_TRUE(frame0->windows_frame_info != nullptr); } { // To avoid reusing locals by mistake @@ -629,7 +629,7 @@ TEST_F(GetCallerFrame, WindowsFrameDataAligned) { EXPECT_EQ(0x5000129dU, frame1->context.eip); EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_EQ(NULL, frame1->windows_frame_info); + EXPECT_EQ(nullptr, frame1->windows_frame_info); } } @@ -708,7 +708,7 @@ TEST_F(GetCallerFrame, WindowsFrameDataParameterSize) { EXPECT_EQ(0x40001000U, frame0->function_base); // The FUNC record for module1::wheedle should have produced a // WindowsFrameInfo structure with only the parameter size valid. - ASSERT_TRUE(frame0->windows_frame_info != NULL); + ASSERT_TRUE(frame0->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE, frame0->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_UNKNOWN, @@ -730,7 +730,7 @@ TEST_F(GetCallerFrame, WindowsFrameDataParameterSize) { EXPECT_EQ(&module2, frame1->module); EXPECT_EQ("module2::whine", frame1->function_name); EXPECT_EQ(0x5000aa85U, frame1->function_base); - ASSERT_TRUE(frame1->windows_frame_info != NULL); + ASSERT_TRUE(frame1->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, frame1->windows_frame_info->type_); @@ -752,8 +752,8 @@ TEST_F(GetCallerFrame, WindowsFrameDataParameterSize) { EXPECT_EQ(frame2_esp.Value(), frame2->context.esp); EXPECT_EQ(frame2_ebp.Value(), frame2->context.ebp); EXPECT_EQ(0x2558c7f3U, frame2->context.ebx); - EXPECT_EQ(NULL, frame2->module); - EXPECT_EQ(NULL, frame2->windows_frame_info); + EXPECT_EQ(nullptr, frame2->module); + EXPECT_EQ(nullptr, frame2->windows_frame_info); } } @@ -803,7 +803,7 @@ TEST_F(GetCallerFrame, WindowsFrameDataScan) { EXPECT_EQ(0x40000c9cU, frame0->context.eip); EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); EXPECT_EQ(0x2ae314cdU, frame0->context.ebp); - EXPECT_TRUE(frame0->windows_frame_info != NULL); + EXPECT_TRUE(frame0->windows_frame_info != nullptr); } { // To avoid reusing locals by mistake @@ -820,7 +820,7 @@ TEST_F(GetCallerFrame, WindowsFrameDataScan) { EXPECT_EQ(0x50007ce9U, frame1->instruction + 1); EXPECT_EQ(0x50007ce9U, frame1->context.eip); EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); - EXPECT_TRUE(frame1->windows_frame_info != NULL); + EXPECT_TRUE(frame1->windows_frame_info != nullptr); } } @@ -892,7 +892,7 @@ TEST_F(GetCallerFrame, WindowsFrameDataBadEIPScan) { EXPECT_EQ(0x40000700U, frame0->context.eip); EXPECT_EQ(stack_section.start().Value(), frame0->context.esp); EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp); - EXPECT_TRUE(frame0->windows_frame_info != NULL); + EXPECT_TRUE(frame0->windows_frame_info != nullptr); } { // To avoid reusing locals by mistake @@ -910,7 +910,7 @@ TEST_F(GetCallerFrame, WindowsFrameDataBadEIPScan) { EXPECT_EQ(0x5000d000U, frame1->context.eip); EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); - EXPECT_TRUE(frame1->windows_frame_info != NULL); + EXPECT_TRUE(frame1->windows_frame_info != nullptr); } } @@ -971,7 +971,7 @@ TEST_F(GetCallerFrame, WindowsFPOUnchangedEBP) { EXPECT_EQ(0x4000e8a8U, frame0->function_base); // The STACK WIN record for module1::discombobulated should have // produced a fully populated WindowsFrameInfo structure. - ASSERT_TRUE(frame0->windows_frame_info != NULL); + ASSERT_TRUE(frame0->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO, frame0->windows_frame_info->type_); @@ -992,7 +992,7 @@ TEST_F(GetCallerFrame, WindowsFPOUnchangedEBP) { EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); EXPECT_EQ(&module1, frame1->module); EXPECT_EQ("", frame1->function_name); - EXPECT_EQ(NULL, frame1->windows_frame_info); + EXPECT_EQ(nullptr, frame1->windows_frame_info); } } @@ -1054,7 +1054,7 @@ TEST_F(GetCallerFrame, WindowsFPOUsedEBP) { EXPECT_EQ(0x40009aa8U, frame0->function_base); // The STACK WIN record for module1::RaisedByTheAliens should have // produced a fully populated WindowsFrameInfo structure. - ASSERT_TRUE(frame0->windows_frame_info != NULL); + ASSERT_TRUE(frame0->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO, frame0->windows_frame_info->type_); @@ -1075,7 +1075,7 @@ TEST_F(GetCallerFrame, WindowsFPOUsedEBP) { EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp); EXPECT_EQ(&module1, frame1->module); EXPECT_EQ("", frame1->function_name); - EXPECT_EQ(NULL, frame1->windows_frame_info); + EXPECT_EQ(nullptr, frame1->windows_frame_info); } } @@ -1332,7 +1332,7 @@ TEST_F(GetCallerFrame, WindowsFPOSystemCall) { EXPECT_EQ("ZwWaitForSingleObject", frame0->function_name); // The STACK WIN record for module3!ZwWaitForSingleObject should have // produced a fully populated WindowsFrameInfo structure. - ASSERT_TRUE(frame0->windows_frame_info != NULL); + ASSERT_TRUE(frame0->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO, frame0->windows_frame_info->type_); @@ -1356,7 +1356,7 @@ TEST_F(GetCallerFrame, WindowsFPOSystemCall) { EXPECT_EQ("WaitForSingleObjectEx", frame1->function_name); // The STACK WIN record for module4!WaitForSingleObjectEx should have // produced a fully populated WindowsFrameInfo structure. - ASSERT_TRUE(frame1->windows_frame_info != NULL); + ASSERT_TRUE(frame1->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, frame1->windows_frame_info->type_); @@ -1544,7 +1544,7 @@ TEST_F(GetCallerFrame, ReturnAddressIsNotInKnownModule) { EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp); EXPECT_EQ(&msvcrt_dll, frame0->module); EXPECT_EQ("wcsstr", frame0->function_name); - ASSERT_TRUE(frame0->windows_frame_info != NULL); + ASSERT_TRUE(frame0->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, frame0->windows_frame_info->type_); @@ -1569,7 +1569,7 @@ TEST_F(GetCallerFrame, ReturnAddressIsNotInKnownModule) { EXPECT_EQ(frame2_ebp.Value(), frame1->context.ebp); EXPECT_EQ(&kernel32_dll, frame1->module); EXPECT_EQ("FindNextFileW", frame1->function_name); - ASSERT_TRUE(frame1->windows_frame_info != NULL); + ASSERT_TRUE(frame1->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, frame1->windows_frame_info->type_); @@ -1593,7 +1593,7 @@ TEST_F(GetCallerFrame, ReturnAddressIsNotInKnownModule) { EXPECT_EQ(frame3_ebp.Value(), frame2->context.ebp); EXPECT_EQ(&chrome_dll, frame2->module); EXPECT_EQ("file_util::FileEnumerator::Next()", frame2->function_name); - ASSERT_TRUE(frame2->windows_frame_info != NULL); + ASSERT_TRUE(frame2->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame2->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, frame2->windows_frame_info->type_); @@ -1747,7 +1747,7 @@ TEST_F(GetCallerFrame, HandleAlignmentInProgramString) { EXPECT_EQ(frame0_esp.Value(), frame->context.esp); EXPECT_EQ(frame0_ebp.Value(), frame->context.ebp); EXPECT_EQ(&chrome_dll, frame->module); - ASSERT_TRUE(frame->windows_frame_info != NULL); + ASSERT_TRUE(frame->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, frame->windows_frame_info->type_); @@ -1772,7 +1772,7 @@ TEST_F(GetCallerFrame, HandleAlignmentInProgramString) { EXPECT_EQ(frame1_esp.Value(), frame->context.esp); EXPECT_EQ(frame1_ebp.Value(), frame->context.ebp); EXPECT_EQ(&chrome_dll, frame->module); - ASSERT_TRUE(frame->windows_frame_info != NULL); + ASSERT_TRUE(frame->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, frame->windows_frame_info->type_); @@ -1794,7 +1794,7 @@ TEST_F(GetCallerFrame, HandleAlignmentInProgramString) { EXPECT_EQ(frame2_esp.Value(), frame->context.esp); EXPECT_EQ(frame2_ebp.Value(), frame->context.ebp); EXPECT_EQ(&chrome_dll, frame->module); - ASSERT_TRUE(frame->windows_frame_info != NULL); + ASSERT_TRUE(frame->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, frame->windows_frame_info->type_); @@ -1993,9 +1993,9 @@ void GetCallerFrame::IPAddressIsNotInKnownModuleTestImpl( EXPECT_EQ(raw_context.eip, frame0->context.eip); EXPECT_EQ(raw_context.ebp, frame0->context.ebp); EXPECT_EQ(raw_context.esp, frame0->context.esp); - EXPECT_EQ(NULL, frame0->module); // IP not in known module + EXPECT_EQ(nullptr, frame0->module); // IP not in known module EXPECT_EQ("", frame0->function_name); - ASSERT_EQ(NULL, frame0->windows_frame_info); + ASSERT_EQ(nullptr, frame0->windows_frame_info); } { // To avoid reusing locals by mistake @@ -2009,7 +2009,7 @@ void GetCallerFrame::IPAddressIsNotInKnownModuleTestImpl( EXPECT_EQ(frame1_esp.Value(), frame1->context.esp); EXPECT_EQ(&remoting_core_dll, frame1->module); EXPECT_EQ("nsc_ECDSAVerifyStub", frame1->function_name); - ASSERT_TRUE(frame1->windows_frame_info != NULL); + ASSERT_TRUE(frame1->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, frame1->windows_frame_info->type_); @@ -2029,7 +2029,7 @@ void GetCallerFrame::IPAddressIsNotInKnownModuleTestImpl( EXPECT_EQ(frame2_esp.Value(), frame2->context.esp); EXPECT_EQ(&remoting_core_dll, frame2->module); EXPECT_EQ("NSC_Verify", frame2->function_name); - ASSERT_TRUE(frame2->windows_frame_info != NULL); + ASSERT_TRUE(frame2->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame2->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, frame2->windows_frame_info->type_); @@ -2049,7 +2049,7 @@ void GetCallerFrame::IPAddressIsNotInKnownModuleTestImpl( EXPECT_EQ(frame3_esp.Value(), frame3->context.esp); EXPECT_EQ(&remoting_core_dll, frame3->module); EXPECT_EQ("PK11_Verify", frame3->function_name); - ASSERT_TRUE(frame3->windows_frame_info != NULL); + ASSERT_TRUE(frame3->windows_frame_info != nullptr); EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame3->windows_frame_info->valid); EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA, frame3->windows_frame_info->type_); @@ -2134,10 +2134,10 @@ struct CFIFixture: public StackwalkerX86Fixture { ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity); EXPECT_EQ("enchiridion", frame0->function_name); EXPECT_EQ(0x40004000U, frame0->function_base); - ASSERT_TRUE(frame0->windows_frame_info != NULL); + ASSERT_TRUE(frame0->windows_frame_info != nullptr); ASSERT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE, frame0->windows_frame_info->valid); - ASSERT_TRUE(frame0->cfi_frame_info != NULL); + ASSERT_TRUE(frame0->cfi_frame_info != nullptr); } { // To avoid reusing locals by mistake diff --git a/src/processor/static_address_map_unittest.cc b/src/processor/static_address_map_unittest.cc index d99833ce8..7626a0546 100644 --- a/src/processor/static_address_map_unittest.cc +++ b/src/processor/static_address_map_unittest.cc @@ -71,7 +71,7 @@ class TestStaticAddressMap : public ::testing::Test { testdata[2][i] = tempdata[i]; // Test data set3: - srand(time(NULL)); + srand(time(nullptr)); for (int i = 0; i < testsize[3]; ++i) testdata[3][i] = rand(); @@ -83,7 +83,7 @@ class TestStaticAddressMap : public ::testing::Test { sstream << "test " << testdata[testcase][data_item]; addr_map[testcase].Store(testdata[testcase][data_item], sstream.str()); } - map_data[testcase] = serializer.Serialize(addr_map[testcase], NULL); + map_data[testcase] = serializer.Serialize(addr_map[testcase], nullptr); test_map[testcase] = TestMap(map_data[testcase]); } } @@ -100,7 +100,7 @@ class TestStaticAddressMap : public ::testing::Test { int address_test; string entry; string entry_test; - const char* entry_cstring = NULL; + const char* entry_cstring = nullptr; bool found; bool found_test; diff --git a/src/processor/static_contained_range_map-inl.h b/src/processor/static_contained_range_map-inl.h index 589bce4bf..78a2fc15c 100644 --- a/src/processor/static_contained_range_map-inl.h +++ b/src/processor/static_contained_range_map-inl.h @@ -50,7 +50,7 @@ StaticContainedRangeMap::StaticContainedRangeMap( base + sizeof(base_) + sizeof(entry_size_))), map_(base + sizeof(base_) + sizeof(entry_size_) + entry_size_) { if (entry_size_ == 0) - entry_ptr_ = NULL; + entry_ptr_ = nullptr; } diff --git a/src/processor/static_map_iterator-inl.h b/src/processor/static_map_iterator-inl.h index e24a70963..1e1d417ec 100644 --- a/src/processor/static_map_iterator-inl.h +++ b/src/processor/static_map_iterator-inl.h @@ -106,7 +106,7 @@ template const Key* StaticMapIterator::GetKeyPtr() const { if (!IsValid()) { BPLOG(ERROR) << "call GetKeyPtr() on invalid iterator"; - return NULL; + return nullptr; } return &(keys_[index_]); } @@ -115,7 +115,7 @@ template const char* StaticMapIterator::GetValueRawPtr() const { if (!IsValid()) { BPLOG(ERROR) << "call GetValuePtr() on invalid iterator"; - return NULL; + return nullptr; } return base_ + offsets_[index_]; } diff --git a/src/processor/static_map_unittest.cc b/src/processor/static_map_unittest.cc index 9308b04bd..7ad9bb85c 100644 --- a/src/processor/static_map_unittest.cc +++ b/src/processor/static_map_unittest.cc @@ -52,7 +52,7 @@ template class SimpleMapSerializer { public: static char* Serialize(const std::map& stdmap, - unsigned int* size = NULL) { + unsigned int* size = nullptr) { unsigned int size_per_node = sizeof(uint64_t) + sizeof(Key) + sizeof(Value); unsigned int memsize = sizeof(int64_t) + size_per_node * stdmap.size(); diff --git a/src/processor/static_range_map_unittest.cc b/src/processor/static_range_map_unittest.cc index a220d57d8..e7e65d1ca 100644 --- a/src/processor/static_range_map_unittest.cc +++ b/src/processor/static_range_map_unittest.cc @@ -324,7 +324,7 @@ void TestStaticRangeMap::RetrieveIndexTest(const TestMap* range_map, int set) { ASSERT_TRUE(range_map->RetrieveRangeAtIndex(object_index, entry, &base, - NULL)) + nullptr)) << "FAILED: RetrieveRangeAtIndex set " << set << " index " << object_index; @@ -348,9 +348,9 @@ void TestStaticRangeMap::RetrieveIndexTest(const TestMap* range_map, int set) { // Make sure that RetrieveRangeAtIndex doesn't allow lookups at indices that // are too high. ASSERT_FALSE(range_map->RetrieveRangeAtIndex( - object_count, entry, NULL, NULL)) << "FAILED: RetrieveRangeAtIndex set " - << set << " index " << object_count - << " (too large)"; + object_count, entry, nullptr, nullptr)) << "FAILED: RetrieveRangeAtIndex " + << "set " << set << " index " + << object_count << " (too large)"; } // RunTests runs a series of test sets. @@ -375,7 +375,7 @@ void TestStaticRangeMap::RunTestCase(int test_case) { ++stored_count; } - scoped_array memaddr(serializer_.Serialize(*rmap, NULL)); + scoped_array memaddr(serializer_.Serialize(*rmap, nullptr)); std::unique_ptr static_range_map(new TestMap(memaddr.get())); // The RangeMap's own count of objects should also match. diff --git a/src/processor/synth_minidump.h b/src/processor/synth_minidump.h index a52be03bf..b747f2328 100644 --- a/src/processor/synth_minidump.h +++ b/src/processor/synth_minidump.h @@ -259,8 +259,8 @@ class Module: public Section { uint32_t time_date_stamp = 1262805309, uint32_t checksum = 0, const MDVSFixedFileInfo& version_info = Module::stock_version_info, - const Section* cv_record = NULL, - const Section* misc_record = NULL); + const Section* cv_record = nullptr, + const Section* misc_record = nullptr); private: // A standard MDVSFixedFileInfo structure to use as a default for diff --git a/src/processor/testdata/linux_test_app.cc b/src/processor/testdata/linux_test_app.cc index b0bbb6698..fcf78247f 100644 --- a/src/processor/testdata/linux_test_app.cc +++ b/src/processor/testdata/linux_test_app.cc @@ -75,7 +75,7 @@ static void CrashFunction() { } // namespace int main(int argc, char** argv) { - google_breakpad::ExceptionHandler eh(".", NULL, callback, NULL, true); + google_breakpad::ExceptionHandler eh(".", nullptr, callback, nullptr, true); if (!eh.WriteMinidump()) { printf("Failed to generate on-demand minidump\n"); } diff --git a/src/processor/testdata/test_app.cc b/src/processor/testdata/test_app.cc index 83468fbbf..cd5eafd24 100644 --- a/src/processor/testdata/test_app.cc +++ b/src/processor/testdata/test_app.cc @@ -64,7 +64,7 @@ static void CrashFunction() { int main(int argc, char** argv) { google_breakpad::ExceptionHandler eh( - L".", NULL, callback, NULL, + L".", nullptr, callback, nullptr, google_breakpad::ExceptionHandler::HANDLER_ALL); CrashFunction(); printf("did not crash?\n"); diff --git a/src/processor/tokenize.cc b/src/processor/tokenize.cc index 47fc3fec0..87271c8f4 100644 --- a/src/processor/tokenize.cc +++ b/src/processor/tokenize.cc @@ -62,11 +62,11 @@ bool Tokenize(char* line, while (token && --remaining > 0) { tokens->push_back(token); if (remaining > 1) - token = strtok_r(NULL, separators, &save_ptr); + token = strtok_r(nullptr, separators, &save_ptr); } // If there's anything left, just add it as a single token. - if (remaining == 0 && (token = strtok_r(NULL, "\r\n", &save_ptr))) { + if (remaining == 0 && (token = strtok_r(nullptr, "\r\n", &save_ptr))) { tokens->push_back(token); } diff --git a/src/processor/windows_frame_info.h b/src/processor/windows_frame_info.h index 346bc4d4b..88e1b8bbe 100644 --- a/src/processor/windows_frame_info.h +++ b/src/processor/windows_frame_info.h @@ -123,28 +123,28 @@ struct WindowsFrameInfo { StringToVector(string, buffer); std::vector tokens; if (!Tokenize(&buffer[0], " \r\n", 11, &tokens)) - return NULL; + return nullptr; - type = strtol(tokens[0], NULL, 16); + type = strtol(tokens[0], nullptr, 16); if (type < 0 || type > STACK_INFO_LAST - 1) - return NULL; - - rva = strtoull(tokens[1], NULL, 16); - code_size = strtoull(tokens[2], NULL, 16); - uint32_t prolog_size = strtoul(tokens[3], NULL, 16); - uint32_t epilog_size = strtoul(tokens[4], NULL, 16); - uint32_t parameter_size = strtoul(tokens[5], NULL, 16); - uint32_t saved_register_size = strtoul(tokens[6], NULL, 16); - uint32_t local_size = strtoul(tokens[7], NULL, 16); - uint32_t max_stack_size = strtoul(tokens[8], NULL, 16); - int has_program_string = strtoul(tokens[9], NULL, 16); + return nullptr; + + rva = strtoull(tokens[1], nullptr, 16); + code_size = strtoull(tokens[2], nullptr, 16); + uint32_t prolog_size = strtoul(tokens[3], nullptr, 16); + uint32_t epilog_size = strtoul(tokens[4], nullptr, 16); + uint32_t parameter_size = strtoul(tokens[5], nullptr, 16); + uint32_t saved_register_size = strtoul(tokens[6], nullptr, 16); + uint32_t local_size = strtoul(tokens[7], nullptr, 16); + uint32_t max_stack_size = strtoul(tokens[8], nullptr, 16); + int has_program_string = strtoul(tokens[9], nullptr, 16); const char *program_string = ""; int allocates_base_pointer = 0; if (has_program_string) { program_string = tokens[10]; } else { - allocates_base_pointer = strtoul(tokens[10], NULL, 16); + allocates_base_pointer = strtoul(tokens[10], nullptr, 16); } return new WindowsFrameInfo(static_cast(type), diff --git a/src/tools/linux/md2core/minidump-2-core.cc b/src/tools/linux/md2core/minidump-2-core.cc index 29560ed18..53ba6a0ae 100644 --- a/src/tools/linux/md2core/minidump-2-core.cc +++ b/src/tools/linux/md2core/minidump-2-core.cc @@ -147,7 +147,7 @@ static void SetupOptions(int argc, const char* argv[], Options* options) { extern int optind; int ch; - const char* output_file = NULL; + const char* output_file = nullptr; // Initialize the options struct as needed. options->verbose = false; @@ -187,7 +187,7 @@ SetupOptions(int argc, const char* argv[], Options* options) { exit(1); } - if (output_file == NULL || !strcmp(output_file, "-")) { + if (output_file == nullptr || !strcmp(output_file, "-")) { options->out_fd = STDOUT_FILENO; } else { options->out_fd = open(output_file, O_WRONLY|O_CREAT|O_TRUNC, 0664); @@ -283,7 +283,7 @@ typedef struct prpsinfo { /* Information about process */ struct CrashedProcess { CrashedProcess() : exception{-1}, - auxv(NULL), + auxv(nullptr), auxv_length(0) { memset(&prps, 0, sizeof(prps)); prps.pr_sname = 'R'; @@ -830,8 +830,8 @@ ParseMaps(const Options& options, CrashedProcess* crashinfo, eol ? eol - ptr : range.data() + range.length() - ptr); ptr = eol ? eol + 1 : range.data() + range.length(); unsigned long long start, stop, offset; - char* permissions = NULL; - char* filename = NULL; + char* permissions = nullptr; + char* filename = nullptr; sscanf(line.c_str(), "%llx-%llx %m[-rwxp] %llx %*[:0-9a-f] %*d %ms", &start, &stop, &permissions, &offset, &filename); if (filename && *filename == '/') { diff --git a/src/tools/linux/md2core/minidump_memory_range_unittest.cc b/src/tools/linux/md2core/minidump_memory_range_unittest.cc index c939dd647..9c597df40 100644 --- a/src/tools/linux/md2core/minidump_memory_range_unittest.cc +++ b/src/tools/linux/md2core/minidump_memory_range_unittest.cc @@ -85,11 +85,11 @@ const struct { { 0, 4, 9, kBufferPointer + 36 }, { kBufferSize - 1, 1, 0, kBufferPointer + kBufferSize - 1 }, // Invalid array elemenets - { 0, 1, kBufferSize, NULL }, - { 0, 4, 10, NULL }, - { kBufferSize - 1, 1, 1, NULL }, - { kBufferSize - 1, 2, 0, NULL }, - { kBufferSize, 1, 0, NULL }, + { 0, 1, kBufferSize, nullptr }, + { 0, 4, 10, nullptr }, + { kBufferSize - 1, 1, 1, nullptr }, + { kBufferSize - 1, 2, 0, nullptr }, + { kBufferSize, 1, 0, nullptr }, }; const size_t kNumElements = sizeof(kElements) / sizeof(kElements[0]); @@ -97,7 +97,7 @@ const size_t kNumElements = sizeof(kElements) / sizeof(kElements[0]); TEST(MinidumpMemoryRangeTest, DefaultConstructor) { MinidumpMemoryRange range; - EXPECT_EQ(NULL, range.data()); + EXPECT_EQ(nullptr, range.data()); EXPECT_EQ(0U, range.length()); } @@ -110,7 +110,7 @@ TEST(MinidumpMemoryRangeTest, ConstructorWithDataAndLength) { TEST(MinidumpMemoryRangeTest, Reset) { MinidumpMemoryRange range; range.Reset(); - EXPECT_EQ(NULL, range.data()); + EXPECT_EQ(nullptr, range.data()); EXPECT_EQ(0U, range.length()); range.Set(kBuffer, kBufferSize); @@ -118,7 +118,7 @@ TEST(MinidumpMemoryRangeTest, Reset) { EXPECT_EQ(kBufferSize, range.length()); range.Reset(); - EXPECT_EQ(NULL, range.data()); + EXPECT_EQ(nullptr, range.data()); EXPECT_EQ(0U, range.length()); } @@ -128,15 +128,15 @@ TEST(MinidumpMemoryRangeTest, Set) { EXPECT_EQ(kBufferPointer, range.data()); EXPECT_EQ(kBufferSize, range.length()); - range.Set(NULL, 0); - EXPECT_EQ(NULL, range.data()); + range.Set(nullptr, 0); + EXPECT_EQ(nullptr, range.data()); EXPECT_EQ(0U, range.length()); } TEST(MinidumpMemoryRangeTest, SubrangeOfEmptyMemoryRange) { MinidumpMemoryRange range; MinidumpMemoryRange subrange = range.Subrange(0, 10); - EXPECT_EQ(NULL, subrange.data()); + EXPECT_EQ(nullptr, subrange.data()); EXPECT_EQ(0U, subrange.length()); } @@ -158,8 +158,8 @@ TEST(MinidumpMemoryRangeTest, SubrangeAndGetData) { EXPECT_EQ(sub_length, subrange.length()); } else { EXPECT_FALSE(range.Covers(sub_offset, sub_length)); - EXPECT_EQ(NULL, range.GetData(sub_offset, sub_length)); - EXPECT_EQ(NULL, subrange.data()); + EXPECT_EQ(nullptr, range.GetData(sub_offset, sub_length)); + EXPECT_EQ(nullptr, subrange.data()); EXPECT_EQ(0U, subrange.length()); } } @@ -186,8 +186,8 @@ TEST(MinidumpMemoryRangeTest, SubrangeWithMDLocationDescriptor) { EXPECT_EQ(sub_length, subrange.length()); } else { EXPECT_FALSE(range.Covers(sub_offset, sub_length)); - EXPECT_EQ(NULL, range.GetData(sub_offset, sub_length)); - EXPECT_EQ(NULL, subrange.data()); + EXPECT_EQ(nullptr, range.GetData(sub_offset, sub_length)); + EXPECT_EQ(nullptr, subrange.data()); EXPECT_EQ(0U, subrange.length()); } } diff --git a/src/tools/linux/symupload/minidump_upload.cc b/src/tools/linux/symupload/minidump_upload.cc index 9f2c96744..645da8c9e 100644 --- a/src/tools/linux/symupload/minidump_upload.cc +++ b/src/tools/linux/symupload/minidump_upload.cc @@ -78,7 +78,7 @@ static void Start(Options *options) { options->proxy_user_pwd, "", &response, - NULL, + nullptr, &error); if (success) { diff --git a/src/tools/mac/dump_syms/dump_syms_tool.cc b/src/tools/mac/dump_syms/dump_syms_tool.cc index fb966cd67..3eb721630 100644 --- a/src/tools/mac/dump_syms/dump_syms_tool.cc +++ b/src/tools/mac/dump_syms/dump_syms_tool.cc @@ -172,7 +172,7 @@ static bool Start(const Options& options) { return dump_symbols.WriteSymbolFileHeader(std::cout); // Read the primary file into a Breakpad Module. - Module* module = NULL; + Module* module = nullptr; if (!dump_symbols.ReadSymbolData(&module)) return false; std::unique_ptr scoped_module(module); @@ -187,7 +187,7 @@ static bool Start(const Options& options) { !SetArchitecture(dump_symbols, *options.arch, options.srcPath)) { return false; } - Module* cfi_module = NULL; + Module* cfi_module = nullptr; if (!dump_symbols.ReadSymbolData(&cfi_module)) return false; std::unique_ptr scoped_cfi_module(cfi_module); diff --git a/src/tools/windows/converter/ms_symbol_server_converter.cc b/src/tools/windows/converter/ms_symbol_server_converter.cc index d1a6b40d5..42878f52d 100644 --- a/src/tools/windows/converter/ms_symbol_server_converter.cc +++ b/src/tools/windows/converter/ms_symbol_server_converter.cc @@ -333,7 +333,7 @@ MSSymbolServerConverter::LocateFile(const string& debug_or_code_file, // Do the lookup. char path[MAX_PATH]; if (!SymFindFileInPath( - process, NULL, + process, nullptr, const_cast(debug_or_code_file.c_str()), const_cast(identifier.guid_or_signature_pointer()), identifier.age(), 0, @@ -599,7 +599,7 @@ MSSymbolServerConverter::LocateAndConvertSymbolFile( *converted_symbol_file = pdb_file.substr(0, pdb_file.length() - 4) + ".sym"; - FILE* converted_output = NULL; + FILE* converted_output = nullptr; #if _MSC_VER >= 1400 // MSVC 2005/8 errno_t err; if ((err = fopen_s(&converted_output, converted_symbol_file->c_str(), "w")) @@ -695,7 +695,7 @@ MSSymbolServerConverter::LocateAndConvertPEFile( *converted_symbol_file = pe_file.substr(0, pe_file.length() - 4) + ".sym"; - FILE* converted_output = NULL; + FILE* converted_output = nullptr; #if _MSC_VER >= 1400 // MSVC 2005/8 errno_t err; if ((err = fopen_s(&converted_output, converted_symbol_file->c_str(), "w")) diff --git a/src/tools/windows/converter_exe/converter.cc b/src/tools/windows/converter_exe/converter.cc index e7b21862e..9e1df7f8b 100644 --- a/src/tools/windows/converter_exe/converter.cc +++ b/src/tools/windows/converter_exe/converter.cc @@ -276,7 +276,7 @@ static bool SendFetchFailedPing(const wstring& fetch_symbol_failure_url, if (!HTTPDownload::Download(fetch_symbol_failure_url, & parameters, & content, - NULL)) { + nullptr)) { FprintfFlush(stderr, "SendFetchFailedPing: HTTPDownload::Download failed " "for %s %s %s\n", missing_info.debug_file.c_str(), @@ -650,7 +650,7 @@ static bool ReadFile(const string& file_name, string* contents) { return false; } contents->clear(); - while (fgets(buffer, sizeof(buffer), fp) != NULL) { + while (fgets(buffer, sizeof(buffer), fp) != nullptr) { contents->append(buffer); } fclose(fp); @@ -672,7 +672,7 @@ static bool ConvertMissingSymbolsList(const ConverterOptions& options) { return false; } } else if (!HTTPDownload::Download(options.missing_symbols_url,& parameters, - & missing_symbol_list, NULL)) { + & missing_symbol_list, nullptr)) { return false; } diff --git a/src/tools/windows/converter_exe/escaping.cc b/src/tools/windows/converter_exe/escaping.cc index 4f59a46bd..bb7b50363 100644 --- a/src/tools/windows/converter_exe/escaping.cc +++ b/src/tools/windows/converter_exe/escaping.cc @@ -83,7 +83,7 @@ class scoped_array { // Constructor. Defaults to intializing with NULL. // There is no way to create an uninitialized scoped_array. // The input parameter must be allocated with new []. - explicit scoped_array(C* p = NULL) : array_(p) { } + explicit scoped_array(C* p = nullptr) : array_(p) { } // Destructor. If there is a C object, delete it. // We don't need to test ptr_ == NULL because C++ does that for us. @@ -95,7 +95,7 @@ class scoped_array { // Reset. Deletes the current owned object, if any. // Then takes ownership of a new object, if given. // this->reset(this->get()) works. - void reset(C* p = NULL) { + void reset(C* p = nullptr) { if (p != array_) { enum { type_must_be_complete = sizeof(C) }; delete[] array_; @@ -107,7 +107,7 @@ class scoped_array { // Will assert() if there is no current object, or index i is negative. C& operator[](std::ptrdiff_t i) const { assert(i >= 0); - assert(array_ != NULL); + assert(array_ != nullptr); return array_[i]; } @@ -137,7 +137,7 @@ class scoped_array { // and will not own the object any more. C* release() { C* retVal = array_; - array_ = NULL; + array_ = nullptr; return retVal; } @@ -174,7 +174,7 @@ namespace strings { // already work on all current implementations. inline char* string_as_array(string* str) { // DO NOT USE const_cast(str->data())! See the unittest for why. - return str->empty() ? NULL : &*str->begin(); + return str->empty() ? nullptr : &*str->begin(); } int CalculateBase64EscapedLen(int input_len, bool do_padding) { @@ -493,7 +493,7 @@ int Base64Unescape(const char *src, int szsrc, char *dest, int szdest) { // for (i = 0; i < 255; i += 8) { // for (j = i; j < i + 8; j++) { // pos = strchr(Base64, j); - // if ((pos == NULL) || (j == 0)) + // if ((pos == nullptr) || (j == 0)) // idx = -1; // else // idx = pos - Base64; @@ -688,7 +688,7 @@ int WebSafeBase64Unescape(const char *src, int szsrc, char *dest, int szdest) { // for (i = 0; i < 255; i += 8) { // for (j = i; j < i + 8; j++) { // pos = strchr(Base64, j); - // if ((pos == NULL) || (j == 0)) + // if ((pos == nullptr) || (j == 0)) // idx = -1; // else // idx = pos - Base64; diff --git a/src/tools/windows/converter_exe/http_download.cc b/src/tools/windows/converter_exe/http_download.cc index de8241980..054ffbe6f 100644 --- a/src/tools/windows/converter_exe/http_download.cc +++ b/src/tools/windows/converter_exe/http_download.cc @@ -50,7 +50,7 @@ using std::vector; // goes out of scope. class AutoHttpHandle { public: - AutoHttpHandle() : handle_(NULL) {} + AutoHttpHandle() : handle_(nullptr) {} explicit AutoHttpHandle(HttpHandle handle) : handle_(handle) {} ~AutoHttpHandle() { if (handle_) { @@ -118,7 +118,7 @@ static bool CheckParameters(const map* parameters) { HttpClient* HTTPDownload::CreateHttpClient(const wchar_t* url) { const TCHAR* kHttpApiPolicyEnvironmentVariable = TEXT("USE_WINHTTP"); TCHAR buffer[2] = {0}; - HttpClient* http_client = NULL; + HttpClient* http_client = nullptr; if (::GetEnvironmentVariable(kHttpApiPolicyEnvironmentVariable, buffer, @@ -127,7 +127,7 @@ HttpClient* HTTPDownload::CreateHttpClient(const wchar_t* url) { "Environment variable [%ws] is set, use WinHttp\n", kHttpApiPolicyEnvironmentVariable); http_client = CreateWinHttpClient(url); - if (http_client == NULL) { + if (http_client == nullptr) { fprintf(stderr, "WinHttpClient not created, Is the protocol HTTPS? " "Fall back to WinInet API.\n"); } @@ -137,7 +137,7 @@ HttpClient* HTTPDownload::CreateHttpClient(const wchar_t* url) { kHttpApiPolicyEnvironmentVariable); } - if (http_client == NULL) { + if (http_client == nullptr) { return CreateWinInetClient(url); } @@ -190,10 +190,10 @@ bool HTTPDownload::Download(const wstring& url, } AutoHttpHandle internet; - if (!http_client->Open(NULL, // user agent + if (!http_client->Open(nullptr, // user agent HttpClient::ACCESS_TYPE_PRECONFIG, - NULL, // proxy name - NULL, // proxy bypass + nullptr, // proxy name + nullptr, // proxy bypass internet.get_handle_addr())) { fprintf(stderr, "HTTPDownload::Download: Open: error %lu for %ws\n", @@ -238,8 +238,8 @@ bool HTTPDownload::Download(const wstring& url, if (!http_client->OpenRequest(connection.get(), L"GET", request_string.c_str(), - NULL, // version - NULL, // referer + nullptr, // version + nullptr, // referer secure, request.get_handle_addr())) { fprintf(stderr, @@ -248,7 +248,7 @@ bool HTTPDownload::Download(const wstring& url, return false; } - if (!http_client->SendRequest(request.get(), NULL, 0)) { + if (!http_client->SendRequest(request.get(), nullptr, 0)) { fprintf(stderr, "HttpClient::SendRequest: error %lu for %ws\n", GetLastError(), url.c_str()); diff --git a/src/tools/windows/converter_exe/winhttp_client.cc b/src/tools/windows/converter_exe/winhttp_client.cc index 425a9daad..010b32069 100644 --- a/src/tools/windows/converter_exe/winhttp_client.cc +++ b/src/tools/windows/converter_exe/winhttp_client.cc @@ -147,7 +147,7 @@ bool WinHttpClient::Connect(HttpHandle session_handle, ToHINTERNET(session_handle), server, static_cast(port), - NULL)); + nullptr)); return !!(*connection_handle); } @@ -182,16 +182,16 @@ bool WinHttpClient::SendRequest(HttpHandle request_handle, return !!::WinHttpSendRequest(ToHINTERNET(request_handle), headers, headers_length, - NULL, + nullptr, 0, WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, - NULL); + nullptr); } bool WinHttpClient::ReceiveResponse(HttpHandle request_handle) const { assert(request_handle); - return !!::WinHttpReceiveResponse(ToHINTERNET(request_handle), NULL); + return !!::WinHttpReceiveResponse(ToHINTERNET(request_handle), nullptr); } bool WinHttpClient::GetHttpStatusCode(HttpHandle request_handle, @@ -206,7 +206,7 @@ bool WinHttpClient::GetHttpStatusCode(HttpHandle request_handle, return false; } - *status_code = static_cast(_tcstol(http_status_string, NULL, 10)); + *status_code = static_cast(_tcstol(http_status_string, nullptr, 10)); return true; } @@ -225,7 +225,7 @@ bool WinHttpClient::GetContentLength(HttpHandle request_handle, *content_length = kUnknownContentLength; } else { *content_length = - static_cast(wcstol(content_length_string, NULL, 10)); + static_cast(wcstol(content_length_string, nullptr, 10)); } return true; } @@ -295,14 +295,14 @@ HttpClient* CreateWinHttpClient(const TCHAR* url) { path, sizeof(path)/sizeof(path[0]), &port)) { - return NULL; + return nullptr; } if (_wcsicmp(scheme, L"https") == 0) { // Winhttp under WINE doesn't support wildcard certificates, so avoid // to use it if the scheme is https. The caller should fall back to // use wininet if NULL is returned. - return NULL; + return nullptr; } return new internal::WinHttpClient(); diff --git a/src/tools/windows/converter_exe/wininet_client.cc b/src/tools/windows/converter_exe/wininet_client.cc index 571ab86c6..e0492780b 100644 --- a/src/tools/windows/converter_exe/wininet_client.cc +++ b/src/tools/windows/converter_exe/wininet_client.cc @@ -145,8 +145,8 @@ bool WinInetClient::Connect(HttpHandle session_handle, ToHINTERNET(session_handle), server, static_cast(port), - NULL, - NULL, + nullptr, + nullptr, INTERNET_SERVICE_HTTP, 0, 0)); @@ -170,9 +170,9 @@ bool WinInetClient::OpenRequest(HttpHandle connection_handle, uri, version, referrer, - NULL, + nullptr, is_secure ? INTERNET_FLAG_SECURE : 0, - NULL)); + nullptr)); return !!(*request_handle); } @@ -184,7 +184,7 @@ bool WinInetClient::SendRequest(HttpHandle request_handle, return !!::HttpSendRequest(ToHINTERNET(request_handle), headers, headers_length, - NULL, + nullptr, 0); } @@ -206,7 +206,7 @@ bool WinInetClient::GetHttpStatusCode(HttpHandle request_handle, return false; } - *status_code = _tcstol(http_status_string, NULL, 10); + *status_code = _tcstol(http_status_string, nullptr, 10); return true; } @@ -224,7 +224,7 @@ bool WinInetClient::GetContentLength(HttpHandle request_handle, 0)) { *content_length = kUnknownContentLength; } else { - *content_length = wcstol(content_length_string, NULL, 10); + *content_length = wcstol(content_length_string, nullptr, 10); } return true; } diff --git a/src/tools/windows/dump_syms/dump_syms_unittest.cc b/src/tools/windows/dump_syms/dump_syms_unittest.cc index 73c48a2f4..f50bd3b89 100644 --- a/src/tools/windows/dump_syms/dump_syms_unittest.cc +++ b/src/tools/windows/dump_syms/dump_syms_unittest.cc @@ -75,13 +75,13 @@ void TrimLastComponent(const std::wstring& path, while (len > 0 && path[len - 1] != '\\') --len; - if (component != NULL) + if (component != nullptr) component->assign(path.c_str() + len, path.c_str() + path.size()); while (len > 0 && path[len - 1] == '\\') --len; - if (trimmed != NULL) + if (trimmed != nullptr) trimmed->assign(path.c_str(), len); } @@ -90,13 +90,13 @@ bool GetSelfDirectory(std::wstring* self_dir) { std::wstring command_line = GetCommandLineW(); int num_args = 0; - wchar_t** args = NULL; + wchar_t** args = nullptr; args = ::CommandLineToArgvW(command_line.c_str(), &num_args); - if (args == NULL) + if (args == nullptr) return false; *self_dir = args[0]; - TrimLastComponent(*self_dir, self_dir, NULL); + TrimLastComponent(*self_dir, self_dir, nullptr); return true; } @@ -129,12 +129,12 @@ void RunCommand(const std::wstring& command_line, STARTUPINFO startup_info = {}; PROCESS_INFORMATION process_info = {}; startup_info.cb = sizeof(STARTUPINFO); - startup_info.hStdError = NULL; + startup_info.hStdError = nullptr; startup_info.hStdInput = child_stdin_read; startup_info.hStdOutput = child_stdout_write; startup_info.dwFlags = STARTF_USESTDHANDLES; - ASSERT_TRUE(::CreateProcessW(NULL, (LPWSTR)command_line.c_str(), NULL, NULL, - TRUE, 0, NULL, NULL, + ASSERT_TRUE(::CreateProcessW(nullptr, (LPWSTR)command_line.c_str(), nullptr, + nullptr, TRUE, 0, nullptr, nullptr, &startup_info, &process_info)); // Collect the output. @@ -142,7 +142,7 @@ void RunCommand(const std::wstring& command_line, char buffer[4096] = {}; DWORD bytes_read = 0; while (::ReadFile(child_stdout_read, buffer, sizeof(buffer), &bytes_read, - NULL) && bytes_read > 0) { + nullptr) && bytes_read > 0) { stdout_string->append(buffer, bytes_read); } @@ -159,7 +159,7 @@ void RunCommand(const std::wstring& command_line, void GetFileContents(const std::wstring& path, std::string* content) { FILE* f = ::_wfopen(path.c_str(), L"rb"); - ASSERT_TRUE(f != NULL); + ASSERT_TRUE(f != nullptr); char buffer[4096] = {}; while (true) { @@ -177,7 +177,7 @@ class DumpSymsRegressionTest : public testing::TestWithParam { ASSERT_TRUE(GetSelfDirectory(&self_dir)); dump_syms_exe = self_dir + L"\\dump_syms.exe"; - TrimLastComponent(self_dir, &testdata_dir, NULL); + TrimLastComponent(self_dir, &testdata_dir, nullptr); testdata_dir += L"\\testdata"; } @@ -192,7 +192,7 @@ class DumpSymsPEOnlyRegressionTest : public testing::TestWithParam= 1400 // MSVC 2005/8 if (_wfopen_s(&temp_file, temp_filename, L"w") != 0) #else // _MSC_VER >= 1400 @@ -292,7 +292,7 @@ int wmain(int argc, wchar_t* argv[]) { while (currentarg < argc) { int response_code; if (!HTTPUpload::SendMultipartPostRequest(argv[currentarg], parameters, files, - timeout == -1 ? NULL : &timeout, + timeout == -1 ? nullptr : &timeout, nullptr, &response_code)) { success = false; fwprintf(stderr, From 3053b65a101670b3ba5502a05de7d6e06ca869f1 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 24 Mar 2025 12:05:33 -0400 Subject: [PATCH 78/91] add missing assert.h includes Some refactors cleaned up headers in places they weren't used, but other files were relying on those indirect includes. Add assert.h to the various C++ files that use assert(). Change-Id: I7be2b1108548bb1fb126548cb3b891a76024f83b Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6387418 Reviewed-by: Lei Zhang --- src/client/ios/exception_handler_no_mach.cc | 1 + src/client/linux/handler/minidump_descriptor.cc | 1 + src/client/linux/microdump_writer/microdump_writer.cc | 2 ++ src/client/linux/minidump_writer/minidump_writer.cc | 1 + src/client/mac/handler/exception_handler.cc | 1 + src/client/mac/handler/minidump_generator.cc | 1 + src/client/minidump_file_writer.cc | 1 + src/client/solaris/handler/minidump_generator.cc | 1 + src/client/windows/unittests/exception_handler_death_test.cc | 1 + src/client/windows/unittests/exception_handler_test.cc | 1 + src/common/dwarf/dwarf2reader.cc | 1 + src/common/dwarf/dwarf2reader_cfi_unittest.cc | 1 + src/common/dwarf/dwarf2reader_die_unittest.cc | 1 + src/common/dwarf_cfi_to_module.cc | 2 ++ src/common/linux/elf_symbols_to_module.cc | 1 + src/common/mac/macho_reader_unittest.cc | 2 ++ src/common/solaris/dump_symbols.cc | 1 + src/processor/cfi_frame_info.cc | 1 + src/processor/microdump.cc | 1 + src/processor/microdump_processor_unittest.cc | 2 ++ src/processor/synth_minidump.cc | 2 ++ src/processor/synth_minidump_unittest.cc | 2 ++ 22 files changed, 28 insertions(+) diff --git a/src/client/ios/exception_handler_no_mach.cc b/src/client/ios/exception_handler_no_mach.cc index 969e72a9c..5f371eda1 100644 --- a/src/client/ios/exception_handler_no_mach.cc +++ b/src/client/ios/exception_handler_no_mach.cc @@ -30,6 +30,7 @@ #include // Must come first #endif +#include #include #include diff --git a/src/client/linux/handler/minidump_descriptor.cc b/src/client/linux/handler/minidump_descriptor.cc index a185b5e1a..7b4c721f0 100644 --- a/src/client/linux/handler/minidump_descriptor.cc +++ b/src/client/linux/handler/minidump_descriptor.cc @@ -30,6 +30,7 @@ #include // Must come first #endif +#include #include #include "client/linux/handler/minidump_descriptor.h" diff --git a/src/client/linux/microdump_writer/microdump_writer.cc b/src/client/linux/microdump_writer/microdump_writer.cc index c7c163446..903a29d6e 100644 --- a/src/client/linux/microdump_writer/microdump_writer.cc +++ b/src/client/linux/microdump_writer/microdump_writer.cc @@ -35,6 +35,8 @@ #include "client/linux/microdump_writer/microdump_writer.h" +#include + #include #include diff --git a/src/client/linux/minidump_writer/minidump_writer.cc b/src/client/linux/minidump_writer/minidump_writer.cc index 65032a50d..06113954f 100644 --- a/src/client/linux/minidump_writer/minidump_writer.cc +++ b/src/client/linux/minidump_writer/minidump_writer.cc @@ -50,6 +50,7 @@ #include "client/linux/minidump_writer/minidump_writer.h" #include "client/minidump_file_writer-inl.h" +#include #include #include #include diff --git a/src/client/mac/handler/exception_handler.cc b/src/client/mac/handler/exception_handler.cc index d93666fcc..40569a784 100644 --- a/src/client/mac/handler/exception_handler.cc +++ b/src/client/mac/handler/exception_handler.cc @@ -30,6 +30,7 @@ #include // Must come first #endif +#include #include #include #include diff --git a/src/client/mac/handler/minidump_generator.cc b/src/client/mac/handler/minidump_generator.cc index 8e26c2678..bb5ddffa1 100644 --- a/src/client/mac/handler/minidump_generator.cc +++ b/src/client/mac/handler/minidump_generator.cc @@ -32,6 +32,7 @@ #include "client/mac/handler/minidump_generator.h" +#include #include #include #include diff --git a/src/client/minidump_file_writer.cc b/src/client/minidump_file_writer.cc index c00af36c8..877768725 100644 --- a/src/client/minidump_file_writer.cc +++ b/src/client/minidump_file_writer.cc @@ -34,6 +34,7 @@ #include // Must come first #endif +#include #include #include #include diff --git a/src/client/solaris/handler/minidump_generator.cc b/src/client/solaris/handler/minidump_generator.cc index 2723a8a89..9982d0bb1 100644 --- a/src/client/solaris/handler/minidump_generator.cc +++ b/src/client/solaris/handler/minidump_generator.cc @@ -34,6 +34,7 @@ #include "client/solaris/handler/minidump_generator.h" +#include #include #include #include diff --git a/src/client/windows/unittests/exception_handler_death_test.cc b/src/client/windows/unittests/exception_handler_death_test.cc index e7868aefe..5d456a7df 100644 --- a/src/client/windows/unittests/exception_handler_death_test.cc +++ b/src/client/windows/unittests/exception_handler_death_test.cc @@ -30,6 +30,7 @@ #include // Must come first #endif +#include #include #include #include diff --git a/src/client/windows/unittests/exception_handler_test.cc b/src/client/windows/unittests/exception_handler_test.cc index 1b4bc24fd..9ebc93fdc 100644 --- a/src/client/windows/unittests/exception_handler_test.cc +++ b/src/client/windows/unittests/exception_handler_test.cc @@ -32,6 +32,7 @@ #include "client/windows/unittests/exception_handler_test.h" +#include #include #include #include diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc index f9cf4535b..4977dcda7 100644 --- a/src/common/dwarf/dwarf2reader.cc +++ b/src/common/dwarf/dwarf2reader.cc @@ -37,6 +37,7 @@ #include "common/dwarf/dwarf2reader.h" +#include #include #include #include diff --git a/src/common/dwarf/dwarf2reader_cfi_unittest.cc b/src/common/dwarf/dwarf2reader_cfi_unittest.cc index 67b662a35..ce92f1698 100644 --- a/src/common/dwarf/dwarf2reader_cfi_unittest.cc +++ b/src/common/dwarf/dwarf2reader_cfi_unittest.cc @@ -34,6 +34,7 @@ #include // Must come first #endif +#include #include #include diff --git a/src/common/dwarf/dwarf2reader_die_unittest.cc b/src/common/dwarf/dwarf2reader_die_unittest.cc index 2b365396d..2eb663370 100644 --- a/src/common/dwarf/dwarf2reader_die_unittest.cc +++ b/src/common/dwarf/dwarf2reader_die_unittest.cc @@ -34,6 +34,7 @@ #include // Must come first #endif +#include #include #include diff --git a/src/common/dwarf_cfi_to_module.cc b/src/common/dwarf_cfi_to_module.cc index 4c594175e..c6325bd78 100644 --- a/src/common/dwarf_cfi_to_module.cc +++ b/src/common/dwarf_cfi_to_module.cc @@ -37,6 +37,8 @@ #include // Must come first #endif +#include + #include #include #include diff --git a/src/common/linux/elf_symbols_to_module.cc b/src/common/linux/elf_symbols_to_module.cc index f50eda43c..2e5c4eeb5 100644 --- a/src/common/linux/elf_symbols_to_module.cc +++ b/src/common/linux/elf_symbols_to_module.cc @@ -36,6 +36,7 @@ #include "common/linux/elf_symbols_to_module.h" +#include #include #include #include diff --git a/src/common/mac/macho_reader_unittest.cc b/src/common/mac/macho_reader_unittest.cc index b0c69a8bc..7b629d1a0 100644 --- a/src/common/mac/macho_reader_unittest.cc +++ b/src/common/mac/macho_reader_unittest.cc @@ -35,6 +35,8 @@ #include // Must come first #endif +#include + #include #include #include diff --git a/src/common/solaris/dump_symbols.cc b/src/common/solaris/dump_symbols.cc index ed7653a2c..07ca87e7a 100644 --- a/src/common/solaris/dump_symbols.cc +++ b/src/common/solaris/dump_symbols.cc @@ -32,6 +32,7 @@ #include // Must come first #endif +#include #include #include #include diff --git a/src/processor/cfi_frame_info.cc b/src/processor/cfi_frame_info.cc index 77e30eee3..1aef1e36b 100644 --- a/src/processor/cfi_frame_info.cc +++ b/src/processor/cfi_frame_info.cc @@ -37,6 +37,7 @@ #include "processor/cfi_frame_info.h" +#include #include #include diff --git a/src/processor/microdump.cc b/src/processor/microdump.cc index 94d2c200a..ec2314570 100644 --- a/src/processor/microdump.cc +++ b/src/processor/microdump.cc @@ -36,6 +36,7 @@ #include "google_breakpad/processor/microdump.h" +#include #include #include diff --git a/src/processor/microdump_processor_unittest.cc b/src/processor/microdump_processor_unittest.cc index 47f5e35ec..5379def8d 100644 --- a/src/processor/microdump_processor_unittest.cc +++ b/src/processor/microdump_processor_unittest.cc @@ -32,6 +32,8 @@ #include // Must come first #endif +#include + #include #include #include diff --git a/src/processor/synth_minidump.cc b/src/processor/synth_minidump.cc index e51d1060a..3356ee7c0 100644 --- a/src/processor/synth_minidump.cc +++ b/src/processor/synth_minidump.cc @@ -36,6 +36,8 @@ #include "processor/synth_minidump.h" +#include + namespace google_breakpad { namespace SynthMinidump { diff --git a/src/processor/synth_minidump_unittest.cc b/src/processor/synth_minidump_unittest.cc index 582922719..e19fc51cd 100644 --- a/src/processor/synth_minidump_unittest.cc +++ b/src/processor/synth_minidump_unittest.cc @@ -35,6 +35,8 @@ #include // Must come first #endif +#include + #include #include From 10fc52d2a6e406df94be854c90813e48f9c482fb Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 24 Mar 2025 13:08:10 -0400 Subject: [PATCH 79/91] mark unreachable code Change-Id: I8f08b7ea098d6e7814d84677487d7f96ead5cdcc Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6388176 Reviewed-by: Lei Zhang --- .../linux/minidump_writer/linux_dumper_unittest_helper.cc | 3 ++- src/client/mac/handler/exception_handler.cc | 3 ++- src/common/macros.h | 7 +++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc b/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc index 6865abe69..fddfd3ca9 100644 --- a/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc +++ b/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc @@ -41,6 +41,7 @@ #include #include +#include "common/macros.h" #include "common/scoped_ptr.h" #include "third_party/lss/linux_syscall_support.h" @@ -73,7 +74,7 @@ void* thread_function(void* data) { register volatile pid_t* thread_id_ptr asm(TID_PTR_REGISTER) = thread_id; while (true) asm volatile ("" : : "r" (thread_id_ptr)); - return nullptr; + unreachable(); } int main(int argc, char* argv[]) { diff --git a/src/client/mac/handler/exception_handler.cc b/src/client/mac/handler/exception_handler.cc index 40569a784..1c08e5805 100644 --- a/src/client/mac/handler/exception_handler.cc +++ b/src/client/mac/handler/exception_handler.cc @@ -44,6 +44,7 @@ #include "client/mac/handler/minidump_generator.h" #include "common/mac/macho_utilities.h" #include "common/mac/scoped_task_suspend-inl.h" +#include "common/macros.h" #include "google_breakpad/common/minidump_exception_mac.h" #ifndef __EXCEPTIONS @@ -614,7 +615,7 @@ void* ExceptionHandler::WaitForMessage(void* exception_handler_class) { } } - return nullptr; + unreachable(); } // static diff --git a/src/common/macros.h b/src/common/macros.h index 828d49d1a..043a5912b 100644 --- a/src/common/macros.h +++ b/src/common/macros.h @@ -29,6 +29,8 @@ #ifndef BREAKPAD_COMMON_MACROS_H_ #define BREAKPAD_COMMON_MACROS_H_ +#include + // Ensure that this macro definition stays in a private header file: clang // suggests the first macro expanding to [[clang::fallthrough]] in its // diagnostics, so if BP_FALLTHROUGH is visible in code depending on breakpad, @@ -41,4 +43,9 @@ #define BP_FALLTHROUGH #endif +// TODO: Delete when we require C++23. +#ifndef unreachable +#define unreachable() __builtin_unreachable() +#endif + #endif // BREAKPAD_COMMON_MACROS_H_ From 9d802008be8e485977541ce85ee7eaddaeab667d Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 24 Mar 2025 13:11:44 -0400 Subject: [PATCH 80/91] switch to standard C++ fallthrough attribute We require C++20 now, so we can switch to the C++17 [[fallthrough]]. Change-Id: I5c34cd4154bca28f4d950524e5b2ffb1e7ec8afd Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6388177 Reviewed-by: Lei Zhang --- src/common/convert_UTF.cc | 38 +++++++++++++++++++------------------- src/common/macros.h | 12 ------------ src/processor/minidump.cc | 4 ++-- 3 files changed, 21 insertions(+), 33 deletions(-) diff --git a/src/common/convert_UTF.cc b/src/common/convert_UTF.cc index 6e95b2f9b..60a0d7aa9 100644 --- a/src/common/convert_UTF.cc +++ b/src/common/convert_UTF.cc @@ -297,15 +297,15 @@ ConversionResult ConvertUTF16toUTF8 (const UTF16** sourceStart, const UTF16* sou case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - BP_FALLTHROUGH; + [[fallthrough]]; case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - BP_FALLTHROUGH; + [[fallthrough]]; case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - BP_FALLTHROUGH; + [[fallthrough]]; case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); } @@ -338,10 +338,10 @@ Boolean isLegalUTF8(const UTF8 *source, int length) { /* Everything else falls through when "true"... */ case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - BP_FALLTHROUGH; + [[fallthrough]]; case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - BP_FALLTHROUGH; + [[fallthrough]]; case 2: if ((a = (*--srcptr)) > 0xBF) return false; @@ -353,7 +353,7 @@ Boolean isLegalUTF8(const UTF8 *source, int length) { case 0xF4: if (a > 0x8F) return false; break; default: if (a < 0x80) return false; } - BP_FALLTHROUGH; + [[fallthrough]]; case 1: if (*source >= 0x80 && *source < 0xC2) return false; } if (*source > 0xF4) return false; @@ -399,12 +399,12 @@ ConversionResult ConvertUTF8toUTF16 (const UTF8** sourceStart, const UTF8* sourc */ switch (extraBytesToRead) { /* remember, illegal UTF-8 */ - case 5: ch += *source++; ch <<= 6; BP_FALLTHROUGH; + case 5: ch += *source++; ch <<= 6; [[fallthrough]]; /* remember, illegal UTF-8 */ - case 4: ch += *source++; ch <<= 6; BP_FALLTHROUGH; - case 3: ch += *source++; ch <<= 6; BP_FALLTHROUGH; - case 2: ch += *source++; ch <<= 6; BP_FALLTHROUGH; - case 1: ch += *source++; ch <<= 6; BP_FALLTHROUGH; + case 4: ch += *source++; ch <<= 6; [[fallthrough]]; + case 3: ch += *source++; ch <<= 6; [[fallthrough]]; + case 2: ch += *source++; ch <<= 6; [[fallthrough]]; + case 1: ch += *source++; ch <<= 6; [[fallthrough]]; case 0: ch += *source++; } ch -= offsetsFromUTF8[extraBytesToRead]; @@ -493,15 +493,15 @@ ConversionResult ConvertUTF32toUTF8 (const UTF32** sourceStart, const UTF32* sou case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - BP_FALLTHROUGH; + [[fallthrough]]; case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - BP_FALLTHROUGH; + [[fallthrough]]; case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - BP_FALLTHROUGH; + [[fallthrough]]; case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]); } @@ -534,11 +534,11 @@ ConversionResult ConvertUTF8toUTF32 (const UTF8** sourceStart, const UTF8* sourc * The cases all fall through. See "Note A" below. */ switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; BP_FALLTHROUGH; - case 4: ch += *source++; ch <<= 6; BP_FALLTHROUGH; - case 3: ch += *source++; ch <<= 6; BP_FALLTHROUGH; - case 2: ch += *source++; ch <<= 6; BP_FALLTHROUGH; - case 1: ch += *source++; ch <<= 6; BP_FALLTHROUGH; + case 5: ch += *source++; ch <<= 6; [[fallthrough]]; + case 4: ch += *source++; ch <<= 6; [[fallthrough]]; + case 3: ch += *source++; ch <<= 6; [[fallthrough]]; + case 2: ch += *source++; ch <<= 6; [[fallthrough]]; + case 1: ch += *source++; ch <<= 6; [[fallthrough]]; case 0: ch += *source++; } ch -= offsetsFromUTF8[extraBytesToRead]; diff --git a/src/common/macros.h b/src/common/macros.h index 043a5912b..741a1c3b8 100644 --- a/src/common/macros.h +++ b/src/common/macros.h @@ -31,18 +31,6 @@ #include -// Ensure that this macro definition stays in a private header file: clang -// suggests the first macro expanding to [[clang::fallthrough]] in its -// diagnostics, so if BP_FALLTHROUGH is visible in code depending on breakpad, -// clang would suggest BP_FALLTHROUGH for code depending on breakpad, instead of -// the client code's own fallthrough macro. -// TODO(thakis): Once everyone uses C++17, use its [[fallthrough]] instead. -#if defined(__clang__) -#define BP_FALLTHROUGH [[clang::fallthrough]] -#else -#define BP_FALLTHROUGH -#endif - // TODO: Delete when we require C++23. #ifndef unreachable #define unreachable() __builtin_unreachable() diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 7fdd966de..43db2a20e 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -2469,7 +2469,7 @@ string MinidumpModule::code_identifier() const { break; } // Otherwise fall through to the case below. - BP_FALLTHROUGH; + [[fallthrough]]; } case MD_OS_MAC_OS_X: @@ -5823,7 +5823,7 @@ bool Minidump::Read() { stream_type << ", but can only deal with one"; return false; } - BP_FALLTHROUGH; + [[fallthrough]]; } default: { From 6290b99cec981cc894f1d7527d1aecab7d25a04e Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 24 Mar 2025 13:21:06 -0400 Subject: [PATCH 81/91] fix some invalid uses of nullptr Some Windows code was misusing NULL, so when it was changed to nullptr, the extra compile-time checks caught it and broke. Since crash_id_ is an integer, initialize it to 0, not a pointer. client/windows/crash_generation/client_info.cc(60,7): error: cannot initialize a member subobject of type 'DWORD' (aka 'unsigned long') with an rvalue of type 'std::nullptr_t' 60 | crash_id_(nullptr) { Casting a pointer to the MINIDUMP_TYPE enum doesn't make sense, especially when the enum with value 0 is a valid value. Switch to MiniDumpNormal since that's what NULL (0) was doing. client/windows/crash_generation/crash_generation_client.cc(209,23): error: static_cast from 'std::nullptr_t' to 'MINIDUMP_TYPE' (aka '_MINIDUMP_TYPE') is not allowed 209 | static_cast(nullptr), nullptr, nullptr, While these are ULONG_PTR, MSDN says they're status codes & byte counts, so initialize both to 0 rather than a null pointer. client/windows/crash_generation/crash_generation_server.cc(568,26): error: assigning to 'ULONG_PTR' (aka 'unsigned long long') from incompatible type 'std::nullptr_t' 568 | overlapped_.Internal = nullptr; client/windows/crash_generation/crash_generation_server.cc(569,30): error: assigning to 'ULONG_PTR' (aka 'unsigned long long') from incompatible type 'std::nullptr_t' 569 | overlapped_.InternalHigh = nullptr; Since handle_ is an integer, initialize it to 0. client/windows/crash_generation/minidump_generator.cc(109,7): error: cannot initialize a member subobject of type 'ULONG64' (aka 'unsigned long long') with an rvalue of type 'std::nullptr_t' 109 | handle_(nullptr) { While Linux defines AppMemory.ptr as void*, Windows defines it as ULONG64. Cast nullptr to that to match other ptr code in this file. client/windows/handler/exception_handler.cc(256,28): error: assigning to 'ULONG64' (aka 'unsigned long long') from incompatible type 'std::nullptr_t' 256 | instruction_memory.ptr = nullptr; The last arg to WinHttpConnect is a reserved integer, not a pointer, so passing it NULL was incorrect -- change to 0 per MSDN. tools/windows/converter_exe/winhttp_client.cc(150,42): error: cannot initialize a parameter of type 'DWORD' (aka 'unsigned long') with an rvalue of type 'std::nullptr_t' 150 | nullptr)); We need to pass explicit 0 for DWORD_PTR types. tools/windows/converter_exe/wininet_client.cc(175,39): error: cannot initialize a parameter of type 'DWORD_PTR' (aka 'unsigned long long') with an rvalue of type 'std::nullptr_t' 175 | nullptr)); Change-Id: Id5f5b65a4279fe7aa1cbc1b99b18813d6a150117 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6388180 Reviewed-by: Lei Zhang --- src/client/windows/crash_generation/client_info.cc | 2 +- .../windows/crash_generation/crash_generation_client.cc | 2 +- .../windows/crash_generation/crash_generation_server.cc | 4 ++-- src/client/windows/crash_generation/minidump_generator.cc | 2 +- src/client/windows/handler/exception_handler.cc | 2 +- src/tools/windows/converter_exe/winhttp_client.cc | 2 +- src/tools/windows/converter_exe/wininet_client.cc | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/client/windows/crash_generation/client_info.cc b/src/client/windows/crash_generation/client_info.cc index 205336210..75eca7947 100644 --- a/src/client/windows/crash_generation/client_info.cc +++ b/src/client/windows/crash_generation/client_info.cc @@ -57,7 +57,7 @@ ClientInfo::ClientInfo(CrashGenerationServer* crash_server, dump_generated_handle_(nullptr), dump_request_wait_handle_(nullptr), process_exit_wait_handle_(nullptr), - crash_id_(nullptr) { + crash_id_(0) { GetSystemTimeAsFileTime(&start_time_); } diff --git a/src/client/windows/crash_generation/crash_generation_client.cc b/src/client/windows/crash_generation/crash_generation_client.cc index cfacf27d3..2c7257146 100644 --- a/src/client/windows/crash_generation/crash_generation_client.cc +++ b/src/client/windows/crash_generation/crash_generation_client.cc @@ -206,7 +206,7 @@ bool CrashGenerationClient::RequestUpload(DWORD crash_id) { CustomClientInfo custom_info = {nullptr, 0}; ProtocolMessage msg(MESSAGE_TAG_UPLOAD_REQUEST, crash_id, - static_cast(nullptr), nullptr, nullptr, + MiniDumpNormal, nullptr, nullptr, nullptr, custom_info, nullptr, nullptr, nullptr); DWORD bytes_count = 0; bool success = WriteFile(pipe, &msg, sizeof(msg), &bytes_count, nullptr) != 0; diff --git a/src/client/windows/crash_generation/crash_generation_server.cc b/src/client/windows/crash_generation/crash_generation_server.cc index c60b10d29..1b3078c05 100644 --- a/src/client/windows/crash_generation/crash_generation_server.cc +++ b/src/client/windows/crash_generation/crash_generation_server.cc @@ -565,8 +565,8 @@ void CrashGenerationServer::HandleDisconnectingState() { // Done serving the client. client_info_ = nullptr; - overlapped_.Internal = nullptr; - overlapped_.InternalHigh = nullptr; + overlapped_.Internal = 0; + overlapped_.InternalHigh = 0; overlapped_.Offset = 0; overlapped_.OffsetHigh = 0; overlapped_.Pointer = nullptr; diff --git a/src/client/windows/crash_generation/minidump_generator.cc b/src/client/windows/crash_generation/minidump_generator.cc index c6d332e42..3811d4acb 100644 --- a/src/client/windows/crash_generation/minidump_generator.cc +++ b/src/client/windows/crash_generation/minidump_generator.cc @@ -106,7 +106,7 @@ class HandleTraceData { HandleTraceData::HandleTraceData() : verifier_module_(nullptr), enumerate_resource_(nullptr), - handle_(nullptr) { + handle_(0) { } HandleTraceData::~HandleTraceData() { diff --git a/src/client/windows/handler/exception_handler.cc b/src/client/windows/handler/exception_handler.cc index d1bbc3373..12c48067a 100644 --- a/src/client/windows/handler/exception_handler.cc +++ b/src/client/windows/handler/exception_handler.cc @@ -253,7 +253,7 @@ void ExceptionHandler::Initialize( // Reserve one element for the instruction memory AppMemory instruction_memory; - instruction_memory.ptr = nullptr; + instruction_memory.ptr = reinterpret_cast(nullptr); instruction_memory.length = 0; app_memory_info_.push_back(instruction_memory); diff --git a/src/tools/windows/converter_exe/winhttp_client.cc b/src/tools/windows/converter_exe/winhttp_client.cc index 010b32069..2d049c4b5 100644 --- a/src/tools/windows/converter_exe/winhttp_client.cc +++ b/src/tools/windows/converter_exe/winhttp_client.cc @@ -147,7 +147,7 @@ bool WinHttpClient::Connect(HttpHandle session_handle, ToHINTERNET(session_handle), server, static_cast(port), - nullptr)); + 0)); return !!(*connection_handle); } diff --git a/src/tools/windows/converter_exe/wininet_client.cc b/src/tools/windows/converter_exe/wininet_client.cc index e0492780b..43fb43c5b 100644 --- a/src/tools/windows/converter_exe/wininet_client.cc +++ b/src/tools/windows/converter_exe/wininet_client.cc @@ -172,7 +172,7 @@ bool WinInetClient::OpenRequest(HttpHandle connection_handle, referrer, nullptr, is_secure ? INTERNET_FLAG_SECURE : 0, - nullptr)); + 0)); return !!(*request_handle); } From 657a441e5c1a818d4c10b7bafd431454e6614901 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 24 Mar 2025 15:09:13 -0400 Subject: [PATCH 82/91] fix some more invalid uses of nullptr Further work for Windows and NULL->nullptr. Pass explicit 0 for DWORD_PTR types. tools/windows/converter_exe/winhttp_client.cc(188,33): error: cannot initialize a parameter of type 'DWORD_PTR' (aka 'unsigned long long') with an rvalue of type 'std::nullptr_t' 188 | nullptr); Change-Id: I5c62094dfe05b6edcee293284ee02840cccab517 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6387423 Reviewed-by: Lei Zhang --- src/tools/windows/converter_exe/winhttp_client.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/windows/converter_exe/winhttp_client.cc b/src/tools/windows/converter_exe/winhttp_client.cc index 2d049c4b5..371b32c16 100644 --- a/src/tools/windows/converter_exe/winhttp_client.cc +++ b/src/tools/windows/converter_exe/winhttp_client.cc @@ -185,7 +185,7 @@ bool WinHttpClient::SendRequest(HttpHandle request_handle, nullptr, 0, WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, - nullptr); + 0); } bool WinHttpClient::ReceiveResponse(HttpHandle request_handle) const { From 884742b238232b434fa03a284372ee3b5bb96a08 Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Tue, 1 Apr 2025 17:31:18 -0400 Subject: [PATCH 83/91] upload_system_symbols: use full path to PlistBuddy Bug: chromium:407791454 Change-Id: Ib07a9ef0e5559fa076d7f78c4e5313c9b62b5575 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6420191 Reviewed-by: Mark Mentovai --- src/tools/mac/upload_system_symbols/archive/extract.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/mac/upload_system_symbols/archive/extract.go b/src/tools/mac/upload_system_symbols/archive/extract.go index f5df10492..760dbb258 100644 --- a/src/tools/mac/upload_system_symbols/archive/extract.go +++ b/src/tools/mac/upload_system_symbols/archive/extract.go @@ -237,7 +237,7 @@ func (e *ipswExtractor) mountSystemDMG(ipswPath string) (string, error) { // at `manifest`. func (e *ipswExtractor) getSystemDMGPath(manifest string) (string, error) { print_cmd := "print :BuildIdentities:1:Manifest:Cryptex1,SystemOS:Info:Path" - result, err := exec.Command("PlistBuddy", "-c", print_cmd, manifest).Output() + result, err := exec.Command("/usr/libexec/PlistBuddy", "-c", print_cmd, manifest).Output() if err != nil { return "", err } From 232a723f5096ab02d53d87931efa485fa77d3b03 Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Wed, 9 Apr 2025 11:42:44 -0400 Subject: [PATCH 84/91] upload_system_symbols: installer extraction bug fixes Missed a PlistBuddy use last time; also fixed a logic bug when compiling system roots. Bug: chromium:407791454 Change-Id: I1c283d4e7ba4c527570b845bf96b8b88f96cf6cb Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6443735 Reviewed-by: Mark Mentovai --- src/tools/mac/upload_system_symbols/archive/extract.go | 2 +- src/tools/mac/upload_system_symbols/upload_system_symbols.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/mac/upload_system_symbols/archive/extract.go b/src/tools/mac/upload_system_symbols/archive/extract.go index 760dbb258..519c66a14 100644 --- a/src/tools/mac/upload_system_symbols/archive/extract.go +++ b/src/tools/mac/upload_system_symbols/archive/extract.go @@ -300,7 +300,7 @@ func (e *installAssistantExtractor) expandInstaller(installerPath string, destin // macOS version 13 or higher, and accordingly stores dyld shared caches inside cryptexes. func (e *installAssistantExtractor) hasCryptexes(plistPath string) (bool, error) { print_cmd := "print :Assets:0:OSVersion" - result, err := exec.Command("PlistBuddy", "-c", print_cmd, plistPath).Output() + result, err := exec.Command("/usr/libexec/PlistBuddy", "-c", print_cmd, plistPath).Output() if err != nil { return false, fmt.Errorf("couldn't read OS version from %s: %v", plistPath, err) } diff --git a/src/tools/mac/upload_system_symbols/upload_system_symbols.go b/src/tools/mac/upload_system_symbols/upload_system_symbols.go index 2f6d1c19c..1ef3a2274 100644 --- a/src/tools/mac/upload_system_symbols/upload_system_symbols.go +++ b/src/tools/mac/upload_system_symbols/upload_system_symbols.go @@ -569,7 +569,7 @@ func extractSystems(format archive.ArchiveFormat, archivePath string, extractPat } cachePrefix := "dyld_shared_cache_" extractedDirPath := path.Join(extractPath, "extracted") - roots := make([]string, len(files)) + roots := make([]string, 0) for _, file := range files { fileName := file.Name() if filepath.Ext(fileName) == "" && strings.HasPrefix(fileName, cachePrefix) { From b319c12317824bfd0e92828db20bbfe0ec6e31f8 Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Fri, 2 May 2025 16:42:48 -0400 Subject: [PATCH 85/91] Mac installer extraction: check payload extract error Bug: 407791454 Change-Id: I614d31a0d889f99d4c66ebd8240aeaeb3c929def Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6508090 Reviewed-by: Mark Mentovai --- src/tools/mac/upload_system_symbols/archive/extract.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/mac/upload_system_symbols/archive/extract.go b/src/tools/mac/upload_system_symbols/archive/extract.go index 519c66a14..965e154e3 100644 --- a/src/tools/mac/upload_system_symbols/archive/extract.go +++ b/src/tools/mac/upload_system_symbols/archive/extract.go @@ -386,7 +386,9 @@ func (e *installAssistantExtractor) extractCachesFromPayloads(payloadsPath strin payload := path.Join(payloadsPath, f.Name()) if e.payloadHasSharedCache(payload) { e.vlog("Extracting %v\n", payload) - e.extractPayload(payload, scratchDir) + if err := e.extractPayload(payload, scratchDir); err != nil { + return err + } } } return e.copySharedCaches(scratchDir, destination) From 9eeece27b727d2ffac4b7042bb69d7c140e58312 Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Fri, 9 May 2025 17:41:30 -0400 Subject: [PATCH 86/91] upload_system_symbols: add option to separate symbols by architecture when dumping This helps enable uploading all symbols for an architecture together for resumability, and lets us record what has been uploaded at better granularity. Bug: 407791454 Change-Id: I3720409405af6a92ba161269da4926cf5fc82d0c Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6532576 Reviewed-by: Mark Mentovai --- .../upload_system_symbols.go | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/tools/mac/upload_system_symbols/upload_system_symbols.go b/src/tools/mac/upload_system_symbols/upload_system_symbols.go index 1ef3a2274..921e83bf0 100644 --- a/src/tools/mac/upload_system_symbols/upload_system_symbols.go +++ b/src/tools/mac/upload_system_symbols/upload_system_symbols.go @@ -43,6 +43,7 @@ package main import ( "debug/macho" + "errors" "flag" "fmt" "io" @@ -69,6 +70,7 @@ var ( apiKey = flag.String("api-key", "", "API key to use. If this is present, the `sym-upload-v2` protocol is used.\nSee https://chromium.googlesource.com/breakpad/breakpad/+/HEAD/docs/sym_upload_v2_protocol.md or\n`symupload`'s help for more information.") installer = flag.String("installer", "", "Path to macOS installer. Mutually exclusive with --system-root and --ipsw.") ipsw = flag.String("ipsw", "", "Path to macOS IPSW. Mutually exclusive with --system-root and --installer.") + separateArch = flag.Bool("separate-arch", false, "Whether to separate symbols into architecture-specific directories when dumping.") ) var ( @@ -165,7 +167,7 @@ func main() { } } - dq := StartDumpQueue(roots, dumpPath, uq) + dq := StartDumpQueue(roots, dumpPath, *separateArch, uq) dq.Wait() if uq != nil { uq.Wait() @@ -338,9 +340,10 @@ func (uq *UploadQueue) worker() { type DumpQueue struct { *WorkerPool - dumpPath string - queue chan dumpRequest - uq *UploadQueue + dumpPath string + queue chan dumpRequest + separateArch bool + uq *UploadQueue } type dumpRequest struct { @@ -351,11 +354,12 @@ type dumpRequest struct { // StartDumpQueue creates a new worker pool to find all the Mach-O libraries in // root and dump their symbols to dumpPath. If an UploadQueue is passed, the // path to the symbol file will be enqueued there, too. -func StartDumpQueue(roots []string, dumpPath string, uq *UploadQueue) *DumpQueue { +func StartDumpQueue(roots []string, dumpPath string, separateArch bool, uq *UploadQueue) *DumpQueue { dq := &DumpQueue{ - dumpPath: dumpPath, - queue: make(chan dumpRequest), - uq: uq, + dumpPath: dumpPath, + queue: make(chan dumpRequest), + separateArch: separateArch, + uq: uq, } dq.WorkerPool = StartWorkerPool(12, dq.worker) @@ -388,7 +392,14 @@ func (dq *DumpQueue) worker() { dumpSyms := path.Join(*breakpadTools, "dump_syms") for req := range dq.queue { - symfile, f, err := createSymbolFile(dq.dumpPath, req.path, req.arch) + dumpPath := dq.dumpPath + if dq.separateArch { + dumpPath = path.Join(dumpPath, req.arch) + if err := ensureDirectory(dumpPath); err != nil { + log.Fatalf("Error creating directory %s: %v", dumpPath, err) + } + } + symfile, f, err := createSymbolFile(dumpPath, req.path, req.arch) if err != nil { log.Fatalf("Error creating symbol file: %v", err) } @@ -594,3 +605,12 @@ func extractDyldSharedCache(cachePath string, destination string) error { } return nil } + +// ensureDirectory creates a directory at `path` if one does not already exist. +func ensureDirectory(path string) error { + if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) { + return os.MkdirAll(path, 0755) + } else { + return err + } +} From fad82477312f786994151f01c352813fabf924c0 Mon Sep 17 00:00:00 2001 From: Sergey Markelov Date: Thu, 1 May 2025 20:31:01 -0700 Subject: [PATCH 87/91] fix: build with LLVM Clang 20 `-Wnontrivial-memcall` warning is raised: passing non-trivially-copyable destination parameter to `memset`. It's safe to suppress the warning with `static_cast(&msg_)` because `ProtocolMessage msg_` is POD with disabled copy ctor and `operator=`. Change-Id: Iec53a946e1fc5570bf77f792222a4958b20900f0 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6508032 Reviewed-by: Lei Zhang Reviewed-by: Mike Frysinger --- src/client/windows/crash_generation/crash_generation_server.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/windows/crash_generation/crash_generation_server.cc b/src/client/windows/crash_generation/crash_generation_server.cc index 1b3078c05..35596b435 100644 --- a/src/client/windows/crash_generation/crash_generation_server.cc +++ b/src/client/windows/crash_generation/crash_generation_server.cc @@ -367,7 +367,7 @@ void CrashGenerationServer::HandleConnectedState() { assert(server_state_ == IPC_SERVER_STATE_CONNECTED); DWORD bytes_count = 0; - memset(&msg_, 0, sizeof(msg_)); + memset(static_cast(&msg_), 0, sizeof(msg_)); bool success = ReadFile(pipe_, &msg_, sizeof(msg_), From 2625edb085169e92cf036c236ac79ab594a7b1cc Mon Sep 17 00:00:00 2001 From: Sergey Markelov Date: Thu, 20 Mar 2025 16:21:39 -0700 Subject: [PATCH 88/91] Improve computing of aligned values: do it with PageAllocator::AlignUp() Replaced all alignments like `size + (alignment - 1) & (~alignment + 1)` and `size + (alignment - 1) & -alignment` with the function call, except one in common/windows/pe_util.cc, that can't include common/memory_allocator.h. Fixed a bug in computing aligned file name size in `AugmentMappings()` in tools/linux/md2core/minidump-2-core.cc: it was `(filename.size() + 8) & ~7`, shall be `(filename.size() + 7) & ~7`. Change-Id: Id3dbdc71193c1215de67e59915e0067c2637e076 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6333238 Reviewed-by: Lei Zhang Reviewed-by: Mike Frysinger --- .../linux/minidump_writer/linux_dumper.cc | 7 ++-- src/client/mac/handler/dynamic_images.cc | 3 +- src/client/minidump_file_writer.cc | 3 +- src/common/dwarf/bytereader.cc | 3 +- src/common/linux/elf_core_dump.cc | 5 +-- src/common/linux/file_id.cc | 14 +++++--- src/common/linux/synth_elf.cc | 3 +- src/common/mac/MachIPC.mm | 5 +-- src/common/memory_allocator.h | 11 +++++- src/common/memory_allocator_unittest.cc | 35 ++++++++++++++++++- src/common/test_assembler.cc | 4 ++- src/tools/linux/md2core/minidump-2-core.cc | 11 +++--- 12 files changed, 79 insertions(+), 25 deletions(-) diff --git a/src/client/linux/minidump_writer/linux_dumper.cc b/src/client/linux/minidump_writer/linux_dumper.cc index ae3a88205..0e3233210 100644 --- a/src/client/linux/minidump_writer/linux_dumper.cc +++ b/src/client/linux/minidump_writer/linux_dumper.cc @@ -53,6 +53,7 @@ #include "common/linux/linux_libc_support.h" #include "common/linux/memory_mapped_file.h" #include "common/linux/safe_readlink.h" +#include "common/memory_allocator.h" #include "google_breakpad/common/minidump_exception_linux.h" #include "third_party/lss/linux_syscall_support.h" @@ -840,8 +841,7 @@ void LinuxDumper::SanitizeStackCopy(uint8_t* stack_copy, size_t stack_len, } // Zero memory that is below the current stack pointer. - const uintptr_t offset = - (sp_offset + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1); + const uintptr_t offset = PageAllocator::AlignUp(sp_offset, sizeof(uintptr_t)); if (offset) { my_memset(stack_copy, 0, offset); } @@ -891,8 +891,7 @@ bool LinuxDumper::StackHasPointerToMapping(const uint8_t* stack_copy, // aligned word in the target process. const uintptr_t low_addr = mapping.system_mapping_info.start_addr; const uintptr_t high_addr = mapping.system_mapping_info.end_addr; - const uintptr_t offset = - (sp_offset + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1); + const uintptr_t offset = PageAllocator::AlignUp(sp_offset, sizeof(uintptr_t)); for (const uint8_t* sp = stack_copy + offset; sp <= stack_copy + stack_len - sizeof(uintptr_t); diff --git a/src/client/mac/handler/dynamic_images.cc b/src/client/mac/handler/dynamic_images.cc index 1ddb74af8..3bee00b47 100644 --- a/src/client/mac/handler/dynamic_images.cc +++ b/src/client/mac/handler/dynamic_images.cc @@ -51,6 +51,7 @@ extern "C" { // needed to compile on Leopard #include #include "breakpad_nlist_64.h" +#include "common/memory_allocator.h" #if !TARGET_OS_IPHONE #include @@ -192,7 +193,7 @@ kern_return_t ReadTaskMemory(task_port_t target_task, mach_vm_address_t page_address = address & (-systemPageSize); mach_vm_address_t last_page_address = - (address + length + (systemPageSize - 1)) & (-systemPageSize); + PageAllocator::AlignUp(address + length, systemPageSize); mach_vm_size_t page_size = last_page_address - page_address; uint8_t* local_start; diff --git a/src/client/minidump_file_writer.cc b/src/client/minidump_file_writer.cc index 877768725..d82fd8158 100644 --- a/src/client/minidump_file_writer.cc +++ b/src/client/minidump_file_writer.cc @@ -43,6 +43,7 @@ #include "client/minidump_file_writer-inl.h" #include "common/linux/linux_libc_support.h" +#include "common/memory_allocator.h" #include "common/string_conversion.h" #if defined(__linux__) && __linux__ #include "third_party/lss/linux_syscall_support.h" @@ -288,7 +289,7 @@ MDRVA MinidumpFileWriter::Allocate(size_t size) { return current_position; } #endif - size_t aligned_size = (size + 7) & ~7; // 64-bit alignment + size_t aligned_size = PageAllocator::AlignUp(size, 8); // 64-bit alignment if (position_ + aligned_size > size_) { size_t growth = aligned_size; diff --git a/src/common/dwarf/bytereader.cc b/src/common/dwarf/bytereader.cc index 4c6f1d183..eea6850d6 100644 --- a/src/common/dwarf/bytereader.cc +++ b/src/common/dwarf/bytereader.cc @@ -36,6 +36,7 @@ #include "common/dwarf/bytereader-inl.h" #include "common/dwarf/bytereader.h" +#include "common/memory_allocator.h" namespace google_breakpad { @@ -132,7 +133,7 @@ uint64_t ByteReader::ReadEncodedPointer(const uint8_t* buffer, // Now find the offset from that aligned address to buffer. uint64_t offset = skew + (buffer - buffer_base_); // Round up to the next boundary. - uint64_t aligned = (offset + AddressSize() - 1) & -AddressSize(); + uint64_t aligned = PageAllocator::AlignUp(offset, AddressSize()); // Convert back to a pointer. const uint8_t* aligned_buffer = buffer_base_ + (aligned - skew); // Finally, store the length and actually fetch the pointer. diff --git a/src/common/linux/elf_core_dump.cc b/src/common/linux/elf_core_dump.cc index 2df53bda7..89cfed5bd 100644 --- a/src/common/linux/elf_core_dump.cc +++ b/src/common/linux/elf_core_dump.cc @@ -39,6 +39,8 @@ #include #include +#include "common/memory_allocator.h" + namespace google_breakpad { // Implementation of ElfCoreDump::Note. @@ -92,8 +94,7 @@ ElfCoreDump::Note ElfCoreDump::Note::GetNextNote() const { // static size_t ElfCoreDump::Note::AlignedSize(size_t size) { - size_t mask = sizeof(Word) - 1; - return (size + mask) & ~mask; + return PageAllocator::AlignUp(size, sizeof(Word)); } diff --git a/src/common/linux/file_id.cc b/src/common/linux/file_id.cc index 83e72c40f..1dfd5e956 100644 --- a/src/common/linux/file_id.cc +++ b/src/common/linux/file_id.cc @@ -48,6 +48,7 @@ #include "common/linux/elfutils.h" #include "common/linux/linux_libc_support.h" #include "common/linux/memory_mapped_file.h" +#include "common/memory_allocator.h" #include "common/using_std_string.h" #include "third_party/lss/linux_syscall_support.h" @@ -60,7 +61,10 @@ const size_t kMDGUIDSize = sizeof(MDGUID); FileID::FileID(const char* path) : path_(path) {} // ELF note name and desc are 32-bits word padded. -#define NOTE_PADDING(a) ((a + 3) & ~3) +template +inline T NotePadding(T size) { + return PageAllocator::AlignUp(size, 4); +} // These functions are also used inside the crashed process, so be safe // and use the syscall/libc wrappers instead of direct syscalls or libc. @@ -77,9 +81,9 @@ static bool ElfClassBuildIDNoteIdentifier(const void* section, size_t length, if (note_header->n_type == NT_GNU_BUILD_ID) break; note_header = reinterpret_cast( - reinterpret_cast(note_header) + sizeof(Nhdr) + - NOTE_PADDING(note_header->n_namesz) + - NOTE_PADDING(note_header->n_descsz)); + reinterpret_cast(note_header) + sizeof(Nhdr) + + NotePadding(note_header->n_namesz) + + NotePadding(note_header->n_descsz)); } if (reinterpret_cast(note_header) >= section_end || note_header->n_descsz == 0) { @@ -87,7 +91,7 @@ static bool ElfClassBuildIDNoteIdentifier(const void* section, size_t length, } const uint8_t* build_id = reinterpret_cast(note_header) + - sizeof(Nhdr) + NOTE_PADDING(note_header->n_namesz); + sizeof(Nhdr) + NotePadding(note_header->n_namesz); identifier.insert(identifier.end(), build_id, build_id + note_header->n_descsz); diff --git a/src/common/linux/synth_elf.cc b/src/common/linux/synth_elf.cc index 8e9170e7f..4de506666 100644 --- a/src/common/linux/synth_elf.cc +++ b/src/common/linux/synth_elf.cc @@ -10,6 +10,7 @@ #include #include "common/linux/elf_gnu_compat.h" +#include "common/memory_allocator.h" #include "common/using_std_string.h" namespace google_breakpad { @@ -159,7 +160,7 @@ void ELF::AddSegment(int start, int end, uint32_t type, uint32_t flags) { if (sections_[i].type_ != SHT_NOBITS) { assert(!prev_was_nobits); // non SHT_NOBITS sections are 4-byte aligned (see AddSection) - size = (size + 3) & ~3; + size = PageAllocator::AlignUp(size, 4); filesz += size; } else { prev_was_nobits = true; diff --git a/src/common/mac/MachIPC.mm b/src/common/mac/MachIPC.mm index 62e0f6b59..e2e7332bd 100644 --- a/src/common/mac/MachIPC.mm +++ b/src/common/mac/MachIPC.mm @@ -29,9 +29,10 @@ // MachIPC.mm // Wrapper for mach IPC calls -#import #import "MachIPC.h" +#import #include "common/mac/bootstrap_compat.h" +#include "common/memory_allocator.h" namespace google_breakpad { //============================================================================== @@ -77,7 +78,7 @@ size_t size = sizeof(mach_msg_header_t) + sizeof(mach_msg_body_t); // add space for MessageDataPacket - int32_t alignedDataLength = (GetDataLength() + 3) & ~0x3; + size_t alignedDataLength = PageAllocator::AlignUp(GetDataLength(), 4); size += 2*sizeof(int32_t) + alignedDataLength; // add space for descriptors diff --git a/src/common/memory_allocator.h b/src/common/memory_allocator.h index 6dc943144..e6dc4e9f2 100644 --- a/src/common/memory_allocator.h +++ b/src/common/memory_allocator.h @@ -29,10 +29,11 @@ #ifndef GOOGLE_BREAKPAD_COMMON_MEMORY_ALLOCATOR_H_ #define GOOGLE_BREAKPAD_COMMON_MEMORY_ALLOCATOR_H_ +#include #include #include -#include #include +#include #include #include @@ -70,6 +71,14 @@ class PageAllocator { FreeAll(); } + // Rounds up `offset` to the closest properly aligned value. `alignment` must + // be positive and a power of two. + template + static T AlignUp(T offset, size_t alignment) { + assert(alignment > 0 && ((alignment - 1) & alignment) == 0); + return (offset + (alignment - 1)) & ~(alignment - 1); + } + void* Alloc(size_t bytes) { if (!bytes) return nullptr; diff --git a/src/common/memory_allocator_unittest.cc b/src/common/memory_allocator_unittest.cc index 57a7562d7..07bce6f85 100644 --- a/src/common/memory_allocator_unittest.cc +++ b/src/common/memory_allocator_unittest.cc @@ -30,6 +30,10 @@ #include // Must come first #endif +#include + +#include + #include "breakpad_googletest_includes.h" #include "common/memory_allocator.h" @@ -37,7 +41,7 @@ using namespace google_breakpad; namespace { typedef testing::Test PageAllocatorTest; -} +} // namespace TEST(PageAllocatorTest, Setup) { PageAllocator allocator; @@ -69,6 +73,35 @@ TEST(PageAllocatorTest, LargeObject) { } } +TEST(PageAllocatorTest, AlignUp) { + EXPECT_EQ(PageAllocator::AlignUp(0x11U, 1), 0x11U); + EXPECT_EQ(PageAllocator::AlignUp(0x11U, 2), 0x12U); + EXPECT_EQ(PageAllocator::AlignUp(0x13U, 2), 0x14U); + EXPECT_EQ(PageAllocator::AlignUp(0x11U, 4), 0x14U); + EXPECT_EQ(PageAllocator::AlignUp(0x15U, 4), 0x18U); + EXPECT_EQ(PageAllocator::AlignUp(0x11U, 8), 0x18U); + EXPECT_EQ(PageAllocator::AlignUp(0x19U, 8), 0x20U); + + // Ensure large 64 bit values are not truncated. + constexpr uint64_t kUnalignedU64 = 0x8000'0000'0000'0011; + constexpr uint64_t kAligned8U64 = 0x8000'0000'0000'0018; + static_assert(kUnalignedU64 > std::numeric_limits::max()); + static_assert(kAligned8U64 > std::numeric_limits::max()); + EXPECT_EQ(PageAllocator::AlignUp(kUnalignedU64, 8), kAligned8U64); +} + +namespace { +typedef testing::Test PageAllocatorDeathTest; +} // namespace + +TEST(PageAllocatorDeathTest, AlignUpBad0) { + EXPECT_DEBUG_DEATH({ PageAllocator::AlignUp(0x11U, 0); }, ""); +} + +TEST(PageAllocatorDeathTest, AlignUpBad9) { + EXPECT_DEBUG_DEATH({ PageAllocator::AlignUp(0x11U, 9); }, ""); +} + namespace { typedef testing::Test WastefulVectorTest; } diff --git a/src/common/test_assembler.cc b/src/common/test_assembler.cc index 00b2fd0a1..95c1619a3 100644 --- a/src/common/test_assembler.cc +++ b/src/common/test_assembler.cc @@ -42,6 +42,8 @@ #include +#include "common/memory_allocator.h" + namespace google_breakpad { namespace test_assembler { @@ -327,7 +329,7 @@ Section& Section::ULEB128(uint64_t value) { Section& Section::Align(size_t alignment, uint8_t pad_byte) { // ALIGNMENT must be a power of two. assert(((alignment - 1) & alignment) == 0); - size_t new_size = (contents_.size() + alignment - 1) & ~(alignment - 1); + size_t new_size = PageAllocator::AlignUp(contents_.size(), alignment); contents_.append(new_size - contents_.size(), pad_byte); assert((contents_.size() & (alignment - 1)) == 0); return *this; diff --git a/src/tools/linux/md2core/minidump-2-core.cc b/src/tools/linux/md2core/minidump-2-core.cc index 53ba6a0ae..d60de5fcf 100644 --- a/src/tools/linux/md2core/minidump-2-core.cc +++ b/src/tools/linux/md2core/minidump-2-core.cc @@ -49,6 +49,7 @@ #include #include "common/linux/memory_mapped_file.h" +#include "common/memory_allocator.h" #include "common/minidump_type_helper.h" #include "common/path_helper.h" #include "common/scoped_ptr.h" @@ -97,6 +98,7 @@ typedef gregset_t user_regs_struct; using google_breakpad::MDTypeHelper; using google_breakpad::MemoryMappedFile; using google_breakpad::MinidumpMemoryRange; +using google_breakpad::PageAllocator; typedef MDTypeHelper::MDRawDebug MDRawDebug; typedef MDTypeHelper::MDRawLinkMap MDRawLinkMap; @@ -1190,8 +1192,7 @@ AddDataToMapping(CrashedProcess* crashinfo, const string& data, CrashedProcess::Mapping mapping; mapping.permissions = PF_R | PF_W; mapping.start_address = addr & ~4095; - mapping.end_address = - (addr + data.size() + 4095) & ~4095; + mapping.end_address = PageAllocator::AlignUp(addr + data.size(), 4096); mapping.data.assign(addr & 4095, 0).append(data); mapping.data.append(-mapping.data.size() & 4095, 0); crashinfo->mappings[mapping.start_address] = mapping; @@ -1290,9 +1291,9 @@ AugmentMappings(const Options& options, CrashedProcess* crashinfo, if (std::distance(iter, crashinfo->link_map.end()) == 1) { link_map.l_next = 0; } else { - link_map.l_next = (struct link_map*)(start_addr + data.size() + - sizeof(link_map) + - ((filename.size() + 8) & ~7)); + link_map.l_next = + (struct link_map*)(start_addr + data.size() + sizeof(link_map) + + PageAllocator::AlignUp(filename.size(), 8)); } data.append((char*)&link_map, sizeof(link_map)); data.append(filename); From 8f1914ef4fb5813c0eb364fa288e6f5787cd0410 Mon Sep 17 00:00:00 2001 From: Takuto Ikuta Date: Mon, 9 Jun 2025 17:04:14 +0900 Subject: [PATCH 89/91] Add missing includes for the build with use_libcxx_modules This is to fix build error when we set use_libcxx_modules=true in chromium build for ChromeOS. Bug: 40263312 Change-Id: I9ec8cf3d0de3b1099100a8d524c939d58586ad34 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6629550 Reviewed-by: Lei Zhang --- src/client/linux/minidump_writer/linux_dumper.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/client/linux/minidump_writer/linux_dumper.cc b/src/client/linux/minidump_writer/linux_dumper.cc index 0e3233210..25cf19018 100644 --- a/src/client/linux/minidump_writer/linux_dumper.cc +++ b/src/client/linux/minidump_writer/linux_dumper.cc @@ -47,6 +47,10 @@ #include #include +#if defined(__CHROMEOS__) +#include +#endif // defined(__CHROMEOS__) + #include "client/linux/minidump_writer/line_reader.h" #include "common/linux/elfutils.h" #include "common/linux/file_id.h" From 9d1f417714a6883f8d4e345c07802eb79edd2e90 Mon Sep 17 00:00:00 2001 From: Takuto Ikuta Date: Thu, 12 Jun 2025 19:07:30 +0900 Subject: [PATCH 90/91] fix(build): Remove libdis namespace to fix C++ module import error With C++ modules enabled (`-fmodules`), including a system header like from within a namespace is not permitted. This was causing a build failure in the `:stackwalk_common` target: fatal error: import of module '_Builtin_stdint' appears within namespace 'libdis' The code in `disassembler_x86.h` was wrapping the `libdisasm` third-party library, including its headers, inside a `libdis` namespace. This change removes the `libdis` namespace wrapper, resolving the build failure. This allows C++ modules to be re-enabled for the breakpad target, contributing to the broader effort to use modules for system headers. Bug: 424364315 Change-Id: I9e5bfe29f63b6e1659c7912a15a3eaa376b865d2 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/6636461 Reviewed-by: Primiano Tucci --- src/processor/disassembler_x86.cc | 102 ++++++++++----------- src/processor/disassembler_x86.h | 11 +-- src/processor/disassembler_x86_unittest.cc | 46 +++++----- src/processor/exploitability_win.cc | 4 +- 4 files changed, 80 insertions(+), 83 deletions(-) diff --git a/src/processor/disassembler_x86.cc b/src/processor/disassembler_x86.cc index a772cffd9..16d864ca6 100644 --- a/src/processor/disassembler_x86.cc +++ b/src/processor/disassembler_x86.cc @@ -56,26 +56,26 @@ DisassemblerX86::DisassemblerX86(const uint8_t* bytecode, pushed_bad_value_(false), end_of_block_(false), flags_(0) { - libdis::x86_init(libdis::opt_none, nullptr, nullptr); + x86_init(opt_none, nullptr, nullptr); } DisassemblerX86::~DisassemblerX86() { if (instr_valid_) - libdis::x86_oplist_free(¤t_instr_); + x86_oplist_free(¤t_instr_); - libdis::x86_cleanup(); + x86_cleanup(); } uint32_t DisassemblerX86::NextInstruction() { if (instr_valid_) - libdis::x86_oplist_free(¤t_instr_); + x86_oplist_free(¤t_instr_); if (current_byte_offset_ >= size_) { instr_valid_ = false; return 0; } uint32_t instr_size = 0; - instr_size = libdis::x86_disasm((unsigned char*)bytecode_, size_, + instr_size = x86_disasm((unsigned char*)bytecode_, size_, virtual_address_, current_byte_offset_, ¤t_instr_); if (instr_size == 0) { @@ -85,39 +85,39 @@ uint32_t DisassemblerX86::NextInstruction() { current_byte_offset_ += instr_size; current_inst_offset_++; - instr_valid_ = libdis::x86_insn_is_valid(¤t_instr_); + instr_valid_ = x86_insn_is_valid(¤t_instr_); if (!instr_valid_) return 0; - if (current_instr_.type == libdis::insn_return) + if (current_instr_.type == insn_return) end_of_block_ = true; - libdis::x86_op_t* src = libdis::x86_get_src_operand(¤t_instr_); - libdis::x86_op_t* dest = libdis::x86_get_dest_operand(¤t_instr_); + x86_op_t* src = x86_get_src_operand(¤t_instr_); + x86_op_t* dest = x86_get_dest_operand(¤t_instr_); if (register_valid_) { switch (current_instr_.group) { // Flag branches based off of bad registers and calls that occur // after pushing bad values. - case libdis::insn_controlflow: + case insn_controlflow: switch (current_instr_.type) { - case libdis::insn_jmp: - case libdis::insn_jcc: - case libdis::insn_call: - case libdis::insn_callcc: + case insn_jmp: + case insn_jcc: + case insn_call: + case insn_callcc: if (dest) { switch (dest->type) { - case libdis::op_expression: + case op_expression: if (dest->data.expression.base.id == bad_register_.id) flags_ |= DISX86_BAD_BRANCH_TARGET; break; - case libdis::op_register: + case op_register: if (dest->data.reg.id == bad_register_.id) flags_ |= DISX86_BAD_BRANCH_TARGET; break; default: if (pushed_bad_value_ && - (current_instr_.type == libdis::insn_call || - current_instr_.type == libdis::insn_callcc)) + (current_instr_.type == insn_call || + current_instr_.type == insn_callcc)) flags_ |= DISX86_BAD_ARGUMENT_PASSED; break; } @@ -129,24 +129,24 @@ uint32_t DisassemblerX86::NextInstruction() { break; // Flag block data operations that use bad registers for src or dest. - case libdis::insn_string: - if (dest && dest->type == libdis::op_expression && + case insn_string: + if (dest && dest->type == op_expression && dest->data.expression.base.id == bad_register_.id) flags_ |= DISX86_BAD_BLOCK_WRITE; - if (src && src->type == libdis::op_expression && + if (src && src->type == op_expression && src->data.expression.base.id == bad_register_.id) flags_ |= DISX86_BAD_BLOCK_READ; break; // Flag comparisons based on bad data. - case libdis::insn_comparison: - if ((dest && dest->type == libdis::op_expression && + case insn_comparison: + if ((dest && dest->type == op_expression && dest->data.expression.base.id == bad_register_.id) || - (src && src->type == libdis::op_expression && + (src && src->type == op_expression && src->data.expression.base.id == bad_register_.id) || - (dest && dest->type == libdis::op_register && + (dest && dest->type == op_register && dest->data.reg.id == bad_register_.id) || - (src && src->type == libdis::op_register && + (src && src->type == op_register && src->data.reg.id == bad_register_.id)) flags_ |= DISX86_BAD_COMPARISON; break; @@ -154,10 +154,10 @@ uint32_t DisassemblerX86::NextInstruction() { // Flag any other instruction which derefs a bad register for // src or dest. default: - if (dest && dest->type == libdis::op_expression && + if (dest && dest->type == op_expression && dest->data.expression.base.id == bad_register_.id) flags_ |= DISX86_BAD_WRITE; - if (src && src->type == libdis::op_expression && + if (src && src->type == op_expression && src->data.expression.base.id == bad_register_.id) flags_ |= DISX86_BAD_READ; break; @@ -166,14 +166,14 @@ uint32_t DisassemblerX86::NextInstruction() { // When a register is marked as tainted check if it is pushed. // TODO(cdn): may also want to check for MOVs into EBP offsets. - if (register_valid_ && dest && current_instr_.type == libdis::insn_push) { + if (register_valid_ && dest && current_instr_.type == insn_push) { switch (dest->type) { - case libdis::op_expression: + case op_expression: if (dest->data.expression.base.id == bad_register_.id || dest->data.expression.index.id == bad_register_.id) pushed_bad_value_ = true; break; - case libdis::op_register: + case op_register: if (dest->data.reg.id == bad_register_.id) pushed_bad_value_ = true; break; @@ -187,31 +187,31 @@ uint32_t DisassemblerX86::NextInstruction() { // there is a hit. if (register_valid_) { switch (current_instr_.type) { - case libdis::insn_xor: - if (src && src->type == libdis::op_register && - dest && dest->type == libdis::op_register && + case insn_xor: + if (src && src->type == op_register && + dest && dest->type == op_register && src->data.reg.id == bad_register_.id && src->data.reg.id == dest->data.reg.id) register_valid_ = false; break; - case libdis::insn_pop: - case libdis::insn_mov: - case libdis::insn_movcc: - if (dest && dest->type == libdis::op_register && + case insn_pop: + case insn_mov: + case insn_movcc: + if (dest && dest->type == op_register && dest->data.reg.id == bad_register_.id) register_valid_ = false; break; - case libdis::insn_popregs: + case insn_popregs: register_valid_ = false; break; - case libdis::insn_xchg: - case libdis::insn_xchgcc: - if (dest && dest->type == libdis::op_register && - src && src->type == libdis::op_register) { + case insn_xchg: + case insn_xchgcc: + if (dest && dest->type == op_register && + src && src->type == op_register) { if (dest->data.reg.id == bad_register_.id) - memcpy(&bad_register_, &src->data.reg, sizeof(libdis::x86_reg_t)); + memcpy(&bad_register_, &src->data.reg, sizeof(x86_reg_t)); else if (src->data.reg.id == bad_register_.id) - memcpy(&bad_register_, &dest->data.reg, sizeof(libdis::x86_reg_t)); + memcpy(&bad_register_, &dest->data.reg, sizeof(x86_reg_t)); } break; default: @@ -226,12 +226,12 @@ bool DisassemblerX86::setBadRead() { if (!instr_valid_) return false; - libdis::x86_op_t* operand = libdis::x86_get_src_operand(¤t_instr_); - if (!operand || operand->type != libdis::op_expression) + x86_op_t* operand = x86_get_src_operand(¤t_instr_); + if (!operand || operand->type != op_expression) return false; memcpy(&bad_register_, &operand->data.expression.base, - sizeof(libdis::x86_reg_t)); + sizeof(x86_reg_t)); register_valid_ = true; return true; } @@ -240,12 +240,12 @@ bool DisassemblerX86::setBadWrite() { if (!instr_valid_) return false; - libdis::x86_op_t* operand = libdis::x86_get_dest_operand(¤t_instr_); - if (!operand || operand->type != libdis::op_expression) + x86_op_t* operand = x86_get_dest_operand(¤t_instr_); + if (!operand || operand->type != op_expression) return false; memcpy(&bad_register_, &operand->data.expression.base, - sizeof(libdis::x86_reg_t)); + sizeof(x86_reg_t)); register_valid_ = true; return true; } diff --git a/src/processor/disassembler_x86.h b/src/processor/disassembler_x86.h index 8f95ed0c7..4f3b6bf57 100644 --- a/src/processor/disassembler_x86.h +++ b/src/processor/disassembler_x86.h @@ -39,10 +39,7 @@ #include #include "google_breakpad/common/breakpad_types.h" - -namespace libdis { #include "third_party/libdisasm/libdis.h" -} namespace google_breakpad { @@ -77,12 +74,12 @@ class DisassemblerX86 { // Returns the current instruction as defined in libdis.h, // or NULL if the current instruction is not valid. - const libdis::x86_insn_t* currentInstruction() { + const x86_insn_t* currentInstruction() { return instr_valid_ ? ¤t_instr_ : nullptr; } // Returns the type of the current instruction as defined in libdis.h. - libdis::x86_insn_group currentInstructionGroup() { + x86_insn_group currentInstructionGroup() { return current_instr_.group; } @@ -108,12 +105,12 @@ class DisassemblerX86 { uint32_t current_inst_offset_; bool instr_valid_; - libdis::x86_insn_t current_instr_; + x86_insn_t current_instr_; // TODO(cdn): Maybe also track an expression's index register. // ex: mov eax, [ebx + ecx]; ebx is base, ecx is index. bool register_valid_; - libdis::x86_reg_t bad_register_; + x86_reg_t bad_register_; bool pushed_bad_value_; bool end_of_block_; diff --git a/src/processor/disassembler_x86_unittest.cc b/src/processor/disassembler_x86_unittest.cc index 95ae65dc1..9bb57af88 100644 --- a/src/processor/disassembler_x86_unittest.cc +++ b/src/processor/disassembler_x86_unittest.cc @@ -88,10 +88,10 @@ TEST(DisassemblerX86Test, SimpleReturnInstruction) { EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); EXPECT_TRUE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_controlflow, dis.currentInstructionGroup()); - const libdis::x86_insn_t* instruction = dis.currentInstruction(); - EXPECT_EQ(libdis::insn_controlflow, instruction->group); - EXPECT_EQ(libdis::insn_return, instruction->type); + EXPECT_EQ(insn_controlflow, dis.currentInstructionGroup()); + const x86_insn_t* instruction = dis.currentInstruction(); + EXPECT_EQ(insn_controlflow, instruction->group); + EXPECT_EQ(insn_return, instruction->type); EXPECT_EQ(0U, dis.NextInstruction()); EXPECT_FALSE(dis.currentInstructionValid()); EXPECT_EQ(nullptr, dis.currentInstruction()); @@ -109,18 +109,18 @@ TEST(DisassemblerX86Test, BadReadLeadsToBranch) { EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); + EXPECT_EQ(insn_move, dis.currentInstructionGroup()); EXPECT_TRUE(dis.setBadRead()); EXPECT_EQ(2U, dis.NextInstruction()); EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_logic, dis.currentInstructionGroup()); + EXPECT_EQ(insn_logic, dis.currentInstructionGroup()); EXPECT_EQ(2U, dis.NextInstruction()); EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(google_breakpad::DISX86_BAD_BRANCH_TARGET, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_controlflow, dis.currentInstructionGroup()); + EXPECT_EQ(insn_controlflow, dis.currentInstructionGroup()); } TEST(DisassemblerX86Test, BadWriteLeadsToPushedArg) { @@ -130,13 +130,13 @@ TEST(DisassemblerX86Test, BadWriteLeadsToPushedArg) { EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); + EXPECT_EQ(insn_move, dis.currentInstructionGroup()); EXPECT_TRUE(dis.setBadWrite()); EXPECT_EQ(3U, dis.NextInstruction()); EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_arithmetic, dis.currentInstructionGroup()); + EXPECT_EQ(insn_arithmetic, dis.currentInstructionGroup()); EXPECT_EQ(1U, dis.NextInstruction()); EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); @@ -144,7 +144,7 @@ TEST(DisassemblerX86Test, BadWriteLeadsToPushedArg) { EXPECT_EQ(5U, dis.NextInstruction()); EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(google_breakpad::DISX86_BAD_ARGUMENT_PASSED, dis.flags()); - EXPECT_EQ(libdis::insn_controlflow, dis.currentInstructionGroup()); + EXPECT_EQ(insn_controlflow, dis.currentInstructionGroup()); EXPECT_FALSE(dis.endOfBlock()); } @@ -155,18 +155,18 @@ TEST(DisassemblerX86Test, BadReadLeadsToBlockWrite) { EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); + EXPECT_EQ(insn_move, dis.currentInstructionGroup()); EXPECT_TRUE(dis.setBadRead()); EXPECT_EQ(2U, dis.NextInstruction()); EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); + EXPECT_EQ(insn_move, dis.currentInstructionGroup()); EXPECT_EQ(2U, dis.NextInstruction()); EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(google_breakpad::DISX86_BAD_BLOCK_WRITE, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_string, dis.currentInstructionGroup()); + EXPECT_EQ(insn_string, dis.currentInstructionGroup()); } TEST(DisassemblerX86Test, BadReadClobberThenWrite) { @@ -175,18 +175,18 @@ TEST(DisassemblerX86Test, BadReadClobberThenWrite) { EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_arithmetic, dis.currentInstructionGroup()); + EXPECT_EQ(insn_arithmetic, dis.currentInstructionGroup()); EXPECT_TRUE(dis.setBadRead()); EXPECT_EQ(2U, dis.NextInstruction()); EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); + EXPECT_EQ(insn_move, dis.currentInstructionGroup()); EXPECT_EQ(2U, dis.NextInstruction()); EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); + EXPECT_EQ(insn_move, dis.currentInstructionGroup()); } TEST(DisassemblerX86Test, BadReadXCHGThenWrite) { @@ -195,23 +195,23 @@ TEST(DisassemblerX86Test, BadReadXCHGThenWrite) { EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_arithmetic, dis.currentInstructionGroup()); + EXPECT_EQ(insn_arithmetic, dis.currentInstructionGroup()); EXPECT_TRUE(dis.setBadRead()); EXPECT_EQ(1U, dis.NextInstruction()); EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); + EXPECT_EQ(insn_move, dis.currentInstructionGroup()); EXPECT_EQ(2U, dis.NextInstruction()); EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); + EXPECT_EQ(insn_move, dis.currentInstructionGroup()); EXPECT_EQ(2U, dis.NextInstruction()); EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(google_breakpad::DISX86_BAD_WRITE, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup()); + EXPECT_EQ(insn_move, dis.currentInstructionGroup()); } TEST(DisassemblerX86Test, BadReadThenCMP) { @@ -220,17 +220,17 @@ TEST(DisassemblerX86Test, BadReadThenCMP) { EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(0U, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_arithmetic, dis.currentInstructionGroup()); + EXPECT_EQ(insn_arithmetic, dis.currentInstructionGroup()); EXPECT_TRUE(dis.setBadRead()); EXPECT_EQ(3U, dis.NextInstruction()); EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(google_breakpad::DISX86_BAD_COMPARISON, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_comparison, dis.currentInstructionGroup()); + EXPECT_EQ(insn_comparison, dis.currentInstructionGroup()); EXPECT_EQ(2U, dis.NextInstruction()); EXPECT_TRUE(dis.currentInstructionValid()); EXPECT_EQ(google_breakpad::DISX86_BAD_COMPARISON, dis.flags()); EXPECT_FALSE(dis.endOfBlock()); - EXPECT_EQ(libdis::insn_controlflow, dis.currentInstructionGroup()); + EXPECT_EQ(insn_controlflow, dis.currentInstructionGroup()); } } diff --git a/src/processor/exploitability_win.cc b/src/processor/exploitability_win.cc index f124e613d..fb0a1c76c 100644 --- a/src/processor/exploitability_win.cc +++ b/src/processor/exploitability_win.cc @@ -226,10 +226,10 @@ ExploitabilityRating ExploitabilityWin::CheckPlatformExploitability() { // Check if the faulting instruction falls into one of // several interesting groups. switch (disassembler.currentInstructionGroup()) { - case libdis::insn_controlflow: + case insn_controlflow: exploitability_weight += kLargeBump; break; - case libdis::insn_string: + case insn_string: exploitability_weight += kHugeBump; break; default: From 62abdcf1c1b5117f5a3a941a20044c4dc9dde793 Mon Sep 17 00:00:00 2001 From: JoshuaMoelans <60878493+JoshuaMoelans@users.noreply.github.com> Date: Fri, 13 Jun 2025 14:46:08 +0200 Subject: [PATCH 91/91] Include AvailabilityMacros for MAC_OS_X_VERSION_MAX_ALLOWED --- src/client/mac/handler/minidump_generator.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/client/mac/handler/minidump_generator.h b/src/client/mac/handler/minidump_generator.h index 8c0cc6270..d74b28f1e 100644 --- a/src/client/mac/handler/minidump_generator.h +++ b/src/client/mac/handler/minidump_generator.h @@ -44,6 +44,7 @@ #include "dynamic_images.h" #include "mach_vm_compat.h" +#include "AvailabilityMacros.h" #if !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7) #define HAS_PPC_SUPPORT