bool GetStepInAvoidsNoDebug() const;
bool GetStepOutAvoidsNoDebug() const;
+
+ uint64_t GetMaxBacktraceDepth() const;
};
typedef std::shared_ptr<ThreadProperties> ThreadPropertiesSP;
--- /dev/null
+LEVEL = ../../../make
+
+CXXFLAGS += -std=c++11
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+include $(LEVEL)/Makefile.rules
--- /dev/null
+"""
+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())
--- /dev/null
+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);
+}
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
// 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.",
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 {
ePropertyStepOutAvoidsNoDebug,
ePropertyStepAvoidRegex,
ePropertyStepAvoidLibraries,
- ePropertyEnableThreadTrace
+ ePropertyEnableThreadTrace,
+ ePropertyMaxBacktraceDepth
};
class ThreadOptionValueProperties : public OptionValueProperties {
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
//------------------------------------------------------------------