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