summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2018-09-25 21:01:54 +0000
committerJason Molenda <jmolenda@apple.com>2018-09-25 21:01:54 +0000
commita11b3fe26f468d00a3006c14e94056b0652e28e6 (patch)
tree811b60e85c4e70b8878f2e6d0aee0f07871e99d4
parentb1e3d4531826e6134b05e8ff3c96a5696a72ad50 (diff)
downloadbcm5719-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
-rw-r--r--lldb/include/lldb/Target/Thread.h2
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/Makefile6
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/TestBacktraceLimit.py31
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/main.cpp13
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp4
-rw-r--r--lldb/source/Target/Thread.cpp11
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
//------------------------------------------------------------------
OpenPOWER on IntegriCloud