[Lldb-commits] [lldb] e5140ae - Fix dap stacktrace perf issue (#104874)

via lldb-commits lldb-commits at lists.llvm.org
Thu Aug 22 11:30:38 PDT 2024


Author: jeffreytan81
Date: 2024-08-22T11:30:34-07:00
New Revision: e5140aed275fe60b83188143f39011d5c0ee5bb0

URL: https://github.com/llvm/llvm-project/commit/e5140aed275fe60b83188143f39011d5c0ee5bb0
DIFF: https://github.com/llvm/llvm-project/commit/e5140aed275fe60b83188143f39011d5c0ee5bb0.diff

LOG: Fix dap stacktrace perf issue (#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 <jeffreytan at fb.com>

Added: 
    

Modified: 
    lldb/tools/lldb-dap/DAP.cpp
    lldb/tools/lldb-dap/DAP.h
    lldb/tools/lldb-dap/lldb-dap.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 1fd560f21904ab..57b93c28ce9301 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 27ea6c7ff8423f..0fc77ac1e81683 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 7b83767d1afeab..495ed0256120e8 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;


        


More information about the lldb-commits mailing list