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 <jeffrey...@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;


        
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to