diff options
| author | Jason Molenda <jmolenda@apple.com> | 2018-09-25 21:01:54 +0000 |
|---|---|---|
| committer | Jason Molenda <jmolenda@apple.com> | 2018-09-25 21:01:54 +0000 |
| commit | a11b3fe26f468d00a3006c14e94056b0652e28e6 (patch) | |
| tree | 811b60e85c4e70b8878f2e6d0aee0f07871e99d4 | |
| parent | b1e3d4531826e6134b05e8ff3c96a5696a72ad50 (diff) | |
| download | bcm5719-llvm-a11b3fe26f468d00a3006c14e94056b0652e28e6.tar.gz bcm5719-llvm-a11b3fe26f468d00a3006c14e94056b0652e28e6.zip | |
Change the unwinder to not use a hard-coded limit on the
max number of stack frames to backtrace, make it a setting,
target.process.thread.max-backtrace-depth.
Add a test case for the setting.
<rdar://problem/28759559>
llvm-svn: 343029
6 files changed, 65 insertions, 2 deletions
diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index 9ce73e0cbef..28a477a4d6e 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -57,6 +57,8 @@ public: bool GetStepInAvoidsNoDebug() const; bool GetStepOutAvoidsNoDebug() const; + + uint64_t GetMaxBacktraceDepth() const; }; typedef std::shared_ptr<ThreadProperties> ThreadPropertiesSP; diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/Makefile new file mode 100644 index 00000000000..f0bcf9752de --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../../make + +CXXFLAGS += -std=c++11 +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/TestBacktraceLimit.py b/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/TestBacktraceLimit.py new file mode 100644 index 00000000000..4e595ea4c5f --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/TestBacktraceLimit.py @@ -0,0 +1,31 @@ +""" +Test that the target.process.thread.max-backtrace-depth setting works. +""" + +import unittest2 +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class BacktraceLimitSettingTest(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + def test_backtrace_depth(self): + """Test that the max-backtrace-depth setting limits backtraces.""" + self.build() + self.main_source_file = lldb.SBFileSpec("main.cpp") + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "Set a breakpoint here", self.main_source_file) + interp = self.dbg.GetCommandInterpreter() + result = lldb.SBCommandReturnObject() + interp.HandleCommand("settings set target.process.thread.max-backtrace-depth 30", result) + self.assertEqual(True, result.Succeeded()) + self.assertEqual(30, thread.GetNumFrames()) diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/main.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/main.cpp new file mode 100644 index 00000000000..eca1eadc8e4 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/main.cpp @@ -0,0 +1,13 @@ +int bottom () { + return 1; // Set a breakpoint here +} +int foo(int in) { + if (in > 0) + return foo(--in) + 5; + else + return bottom(); +} +int main() +{ + return foo(500); +} diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp index 55559f07f1e..49c06fea78a 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -130,6 +130,8 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB( m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this)); + uint64_t max_stack_depth = m_thread.GetMaxBacktraceDepth(); + // We want to detect an unwind that cycles erroneously and stop backtracing. // Don't want this maximum unwind limit to be too low -- if you have a // backtrace with an "infinitely recursing" bug, it will crash when the stack @@ -138,7 +140,7 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { // unwind at 10,000 or something. Realistically anything over around 200,000 // is going to blow out the stack space. If we're still unwinding at that // point, we're probably never going to finish. - if (cur_idx > 300000) { + if (cur_idx >= max_stack_depth) { if (log) log->Printf("%*sFrame %d unwound too many frames, assuming unwind has " "gone astray, stopping.", diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 7fbad420700..660cb773d11 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -80,6 +80,8 @@ static PropertyDefinition g_properties[] = { nullptr, "A list of libraries that source stepping won't stop in."}, {"trace-thread", OptionValue::eTypeBoolean, false, false, nullptr, nullptr, "If true, this thread will single-step and log execution."}, + {"max-backtrace-depth", OptionValue::eTypeUInt64, false, 300000, nullptr, + nullptr, "Maximum number of frames to backtrace."}, {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}}; enum { @@ -87,7 +89,8 @@ enum { ePropertyStepOutAvoidsNoDebug, ePropertyStepAvoidRegex, ePropertyStepAvoidLibraries, - ePropertyEnableThreadTrace + ePropertyEnableThreadTrace, + ePropertyMaxBacktraceDepth }; class ThreadOptionValueProperties : public OptionValueProperties { @@ -165,6 +168,12 @@ bool ThreadProperties::GetStepOutAvoidsNoDebug() const { nullptr, idx, g_properties[idx].default_uint_value != 0); } +uint64_t ThreadProperties::GetMaxBacktraceDepth() const { + const uint32_t idx = ePropertyMaxBacktraceDepth; + return m_collection_sp->GetPropertyAtIndexAsUInt64( + nullptr, idx, g_properties[idx].default_uint_value != 0); +} + //------------------------------------------------------------------ // Thread Event Data //------------------------------------------------------------------ |

