Skip to content

Commit 9a5aae3

Browse files
jeffreytan81jeffreytan81
authored andcommitted
Fix dap stacktrace perf issue (llvm#104874)
We have got several customer reporting of slow stepping over the past year in VSCode. Profiling shows the slow stepping is caused by `stackTrace` request which can take around 1 second for certain targets. Since VSCode sends `stackTrace` during each stop event, the slow `stackTrace` request would slow down stepping in VSCode. Below is the hot path: ``` |--68.75%--lldb_dap::DAP::HandleObject(llvm::json::Object const&) | | | |--57.70%--(anonymous namespace)::request_stackTrace(llvm::json::Object const&) | | | | | |--54.43%--lldb::SBThread::GetCurrentExceptionBacktrace() | | | lldb_private::Thread::GetCurrentExceptionBacktrace() | | | lldb_private::Thread::GetCurrentException() | | | lldb_private::ItaniumABILanguageRuntime::GetExceptionObjectForThread(std::shared_ptr<lldb_private::Thread>) | | | | | | | |--53.43%--lldb_private::FunctionCaller::ExecuteFunction(lldb_private::ExecutionContext&, unsigned long*, lldb_private::EvaluateExpressionOptions const&, lldb_private::DiagnosticManager&, lldb_private::Value&) | | | | | | | | | |--25.23%--lldb_private::FunctionCaller::InsertFunction(lldb_private::ExecutionContext&, unsigned long&, lldb_private::DiagnosticManager&) | | | | | | | | | | | |--24.56%--lldb_private::FunctionCaller::WriteFunctionWrapper(lldb_private::ExecutionContext&, lldb_private::DiagnosticManager&) | | | | | | | | | | | | | |--19.73%--lldb_private::ExpressionParser::PrepareForExecution(unsigned long&, unsigned long&, std::shared_ptr<lldb_private::IRExecutionUnit>&, lldb_private::ExecutionContext&, bool&, lldb_private::ExecutionPolicy) | | | | | | | lldb_private::ClangExpressionParser::DoPrepareForExecution(unsigned long&, unsigned long&, std::shared_ptr<lldb_private::IRExecutionUnit>&, lldb_private::ExecutionContext&, bool&, lldb_private::ExecutionPolicy) | | | | | | | lldb_private::IRExecutionUnit::GetRunnableInfo(lldb_private::Status&, unsigned long&, unsigned long&) | | | | | | | | ``` The hot path is added by https://reviews.llvm.org/D156465 which should at least be disabled for Linux. Note: I am seeing similar performance hot path on Mac. This PR hides the feature behind `enableDisplayExtendedBacktrace` option which needs to be enabled on-demand. --------- Co-authored-by: jeffreytan81 <[email protected]> (cherry picked from commit e5140ae)
1 parent c2a3c16 commit 9a5aae3

File tree

3 files changed

+13
-4
lines changed

3 files changed

+13
-4
lines changed

lldb/tools/lldb-dap/DAP.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ DAP::DAP()
3636
focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), is_attach(false),
3737
enable_auto_variable_summaries(false),
3838
enable_synthetic_child_debugging(false),
39+
enable_display_extended_backtrace(false),
3940
restarting_process_id(LLDB_INVALID_PROCESS_ID),
4041
configuration_done_sent(false), waiting_for_run_in_terminal(false),
4142
progress_event_reporter(

lldb/tools/lldb-dap/DAP.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ struct DAP {
181181
bool is_attach;
182182
bool enable_auto_variable_summaries;
183183
bool enable_synthetic_child_debugging;
184+
bool enable_display_extended_backtrace;
184185
// The process event thread normally responds to process exited events by
185186
// shutting down the entire adapter. When we're restarting, we keep the id of
186187
// the old process here so we can detect this case and keep running.

lldb/tools/lldb-dap/lldb-dap.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,8 @@ void request_attach(const llvm::json::Object &request) {
701701
GetBoolean(arguments, "enableAutoVariableSummaries", false);
702702
g_dap.enable_synthetic_child_debugging =
703703
GetBoolean(arguments, "enableSyntheticChildDebugging", false);
704+
g_dap.enable_display_extended_backtrace =
705+
GetBoolean(arguments, "enableDisplayExtendedBacktrace", false);
704706
g_dap.command_escape_prefix =
705707
GetString(arguments, "commandEscapePrefix", "`");
706708
g_dap.SetFrameFormat(GetString(arguments, "customFrameFormat"));
@@ -1925,6 +1927,8 @@ void request_launch(const llvm::json::Object &request) {
19251927
GetBoolean(arguments, "enableAutoVariableSummaries", false);
19261928
g_dap.enable_synthetic_child_debugging =
19271929
GetBoolean(arguments, "enableSyntheticChildDebugging", false);
1930+
g_dap.enable_display_extended_backtrace =
1931+
GetBoolean(arguments, "enableDisplayExtendedBacktrace", false);
19281932
g_dap.command_escape_prefix =
19291933
GetString(arguments, "commandEscapePrefix", "`");
19301934
g_dap.SetFrameFormat(GetString(arguments, "customFrameFormat"));
@@ -3111,17 +3115,20 @@ void request_stackTrace(const llvm::json::Object &request) {
31113115
// This will always return an invalid thread when
31123116
// libBacktraceRecording.dylib is not loaded or if there is no extended
31133117
// backtrace.
3114-
lldb::SBThread queue_backtrace_thread =
3115-
thread.GetExtendedBacktraceThread("libdispatch");
3118+
lldb::SBThread queue_backtrace_thread;
3119+
if (g_dap.enable_display_extended_backtrace)
3120+
queue_backtrace_thread = thread.GetExtendedBacktraceThread("libdispatch");
31163121
if (queue_backtrace_thread.IsValid()) {
31173122
// One extra frame as a label to mark the enqueued thread.
31183123
totalFrames += queue_backtrace_thread.GetNumFrames() + 1;
31193124
}
31203125

31213126
// This will always return an invalid thread when there is no exception in
31223127
// the current thread.
3123-
lldb::SBThread exception_backtrace_thread =
3124-
thread.GetCurrentExceptionBacktrace();
3128+
lldb::SBThread exception_backtrace_thread;
3129+
if (g_dap.enable_display_extended_backtrace)
3130+
exception_backtrace_thread = thread.GetCurrentExceptionBacktrace();
3131+
31253132
if (exception_backtrace_thread.IsValid()) {
31263133
// One extra frame as a label to mark the exception thread.
31273134
totalFrames += exception_backtrace_thread.GetNumFrames() + 1;

0 commit comments

Comments
 (0)