michael@0: # HG changeset patch michael@0: # User Julian Seward michael@0: # Date 1366643454 -7200 michael@0: # Mon Apr 22 17:10:54 2013 +0200 michael@0: # Node ID 3e64f12d9dab619c90bee02ed071bcda0100844e michael@0: # Parent 6d06a09b3f5624dd833bd6f905bfd88e3fdec00a michael@0: Bug 859745 - Install sane unwinding limit for SPS/breakpad. r=ted michael@0: michael@0: diff --git a/src/google_breakpad/processor/stackwalker.h b/src/google_breakpad/processor/stackwalker.h michael@0: --- a/src/google_breakpad/processor/stackwalker.h michael@0: +++ b/src/google_breakpad/processor/stackwalker.h michael@0: @@ -83,17 +83,20 @@ class Stackwalker { michael@0: // argument. If no suitable concrete subclass exists, returns NULL. michael@0: static Stackwalker* StackwalkerForCPU( michael@0: const SystemInfo* system_info, michael@0: MinidumpContext* context, michael@0: MemoryRegion* memory, michael@0: const CodeModules* modules, michael@0: StackFrameSymbolizer* resolver_helper); michael@0: michael@0: - static void set_max_frames(uint32_t max_frames) { max_frames_ = max_frames; } michael@0: + static void set_max_frames(uint32_t max_frames) { michael@0: + max_frames_ = max_frames; michael@0: + max_frames_set_ = true; michael@0: + } michael@0: static uint32_t max_frames() { return max_frames_; } michael@0: michael@0: protected: michael@0: // system_info identifies the operating system, NULL or empty if unknown. michael@0: // memory identifies a MemoryRegion that provides the stack memory michael@0: // for the stack to walk. modules, if non-NULL, is a CodeModules michael@0: // object that is used to look up which code module each stack frame is michael@0: // associated with. frame_symbolizer is a StackFrameSymbolizer object that michael@0: @@ -191,14 +194,19 @@ class Stackwalker { michael@0: // the end of the stack has been reached). GetCallerFrame allocates a new michael@0: // StackFrame (or StackFrame subclass), ownership of which is taken by michael@0: // the caller. michael@0: virtual StackFrame* GetCallerFrame(const CallStack* stack) = 0; michael@0: michael@0: // The maximum number of frames Stackwalker will walk through. michael@0: // This defaults to 1024 to prevent infinite loops. michael@0: static uint32_t max_frames_; michael@0: + michael@0: + // Keep track of whether max_frames_ has been set by the user, since michael@0: + // it affects whether or not an error message is printed in the case michael@0: + // where an unwind got stopped by the limit. michael@0: + static bool max_frames_set_; michael@0: }; michael@0: michael@0: } // namespace google_breakpad michael@0: michael@0: michael@0: #endif // GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__ michael@0: diff --git a/src/processor/stackwalker.cc b/src/processor/stackwalker.cc michael@0: --- a/src/processor/stackwalker.cc michael@0: +++ b/src/processor/stackwalker.cc michael@0: @@ -52,16 +52,17 @@ michael@0: #include "processor/stackwalker_x86.h" michael@0: #include "processor/stackwalker_amd64.h" michael@0: #include "processor/stackwalker_arm.h" michael@0: michael@0: namespace google_breakpad { michael@0: michael@0: const int Stackwalker::kRASearchWords = 30; michael@0: uint32_t Stackwalker::max_frames_ = 1024; michael@0: +bool Stackwalker::max_frames_set_ = false; michael@0: michael@0: Stackwalker::Stackwalker(const SystemInfo* system_info, michael@0: MemoryRegion* memory, michael@0: const CodeModules* modules, michael@0: StackFrameSymbolizer* frame_symbolizer) michael@0: : system_info_(system_info), michael@0: memory_(memory), michael@0: modules_(modules), michael@0: @@ -120,17 +121,20 @@ bool Stackwalker::Walk(CallStack* stack, michael@0: modules_without_symbols->push_back(frame->module); michael@0: } michael@0: } michael@0: michael@0: // Add the frame to the call stack. Relinquish the ownership claim michael@0: // over the frame, because the stack now owns it. michael@0: stack->frames_.push_back(frame.release()); michael@0: if (stack->frames_.size() > max_frames_) { michael@0: - BPLOG(ERROR) << "The stack is over " << max_frames_ << " frames."; michael@0: + // Only emit an error message in the case where the limit that we michael@0: + // reached is the default limit, not set by the user. michael@0: + if (!max_frames_set_) michael@0: + BPLOG(ERROR) << "The stack is over " << max_frames_ << " frames."; michael@0: break; michael@0: } michael@0: michael@0: // Get the next frame and take ownership. michael@0: frame.reset(GetCallerFrame(stack)); michael@0: } michael@0: michael@0: return true;