diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp index 1fd560f21904a..57b93c28ce930 100644 --- a/lldb/tools/lldb-dap/DAP.cpp +++ b/lldb/tools/lldb-dap/DAP.cpp @@ -36,6 +36,7 @@ DAP::DAP() focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), is_attach(false), enable_auto_variable_summaries(false), enable_synthetic_child_debugging(false), + enable_display_extended_backtrace(false), restarting_process_id(LLDB_INVALID_PROCESS_ID), configuration_done_sent(false), waiting_for_run_in_terminal(false), progress_event_reporter( diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h index 27ea6c7ff8423..0fc77ac1e8168 100644 --- a/lldb/tools/lldb-dap/DAP.h +++ b/lldb/tools/lldb-dap/DAP.h @@ -181,6 +181,7 @@ struct DAP { bool is_attach; bool enable_auto_variable_summaries; bool enable_synthetic_child_debugging; + bool enable_display_extended_backtrace; // The process event thread normally responds to process exited events by // shutting down the entire adapter. When we're restarting, we keep the id of // the old process here so we can detect this case and keep running. diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp index 7b83767d1afea..495ed0256120e 100644 --- a/lldb/tools/lldb-dap/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/lldb-dap.cpp @@ -701,6 +701,8 @@ void request_attach(const llvm::json::Object &request) { GetBoolean(arguments, "enableAutoVariableSummaries", false); g_dap.enable_synthetic_child_debugging = GetBoolean(arguments, "enableSyntheticChildDebugging", false); + g_dap.enable_display_extended_backtrace = + GetBoolean(arguments, "enableDisplayExtendedBacktrace", false); g_dap.command_escape_prefix = GetString(arguments, "commandEscapePrefix", "`"); g_dap.SetFrameFormat(GetString(arguments, "customFrameFormat")); @@ -1925,6 +1927,8 @@ void request_launch(const llvm::json::Object &request) { GetBoolean(arguments, "enableAutoVariableSummaries", false); g_dap.enable_synthetic_child_debugging = GetBoolean(arguments, "enableSyntheticChildDebugging", false); + g_dap.enable_display_extended_backtrace = + GetBoolean(arguments, "enableDisplayExtendedBacktrace", false); g_dap.command_escape_prefix = GetString(arguments, "commandEscapePrefix", "`"); g_dap.SetFrameFormat(GetString(arguments, "customFrameFormat")); @@ -3111,8 +3115,9 @@ void request_stackTrace(const llvm::json::Object &request) { // This will always return an invalid thread when // libBacktraceRecording.dylib is not loaded or if there is no extended // backtrace. - lldb::SBThread queue_backtrace_thread = - thread.GetExtendedBacktraceThread("libdispatch"); + lldb::SBThread queue_backtrace_thread; + if (g_dap.enable_display_extended_backtrace) + queue_backtrace_thread = thread.GetExtendedBacktraceThread("libdispatch"); if (queue_backtrace_thread.IsValid()) { // One extra frame as a label to mark the enqueued thread. totalFrames += queue_backtrace_thread.GetNumFrames() + 1; @@ -3120,8 +3125,10 @@ void request_stackTrace(const llvm::json::Object &request) { // This will always return an invalid thread when there is no exception in // the current thread. - lldb::SBThread exception_backtrace_thread = - thread.GetCurrentExceptionBacktrace(); + lldb::SBThread exception_backtrace_thread; + if (g_dap.enable_display_extended_backtrace) + exception_backtrace_thread = thread.GetCurrentExceptionBacktrace(); + if (exception_backtrace_thread.IsValid()) { // One extra frame as a label to mark the exception thread. totalFrames += exception_backtrace_thread.GetNumFrames() + 1;