[Lldb-commits] [lldb] [lldb] returning command completions up to a maximum (PR #135565)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/135565 >From 04e503abe160bc6a9214ad1f345ef90be1e8c7e0 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 13 Apr 2025 20:46:56 +0200 Subject: [PATCH 1/3] [lldb] returning command completions up to a maximum - Adding `max_return_elements` field to `CompletionRequest`. - adding maximum checks to `SymbolCompleter` and `SourceFileCompleter`. --- lldb/include/lldb/Utility/CompletionRequest.h | 24 +++ lldb/source/API/SBCommandInterpreter.cpp | 2 ++ lldb/source/Commands/CommandCompletions.cpp | 14 --- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/lldb/include/lldb/Utility/CompletionRequest.h b/lldb/include/lldb/Utility/CompletionRequest.h index 865d6db576298..2d3f0a8a44a0a 100644 --- a/lldb/include/lldb/Utility/CompletionRequest.h +++ b/lldb/include/lldb/Utility/CompletionRequest.h @@ -115,6 +115,11 @@ class CompletionRequest { CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos, CompletionResult &result); + /// Sets the maximum number of completions that should be returned. + void SetMaxReturnElements(size_t max_return_elements) { +m_max_return_elements = max_return_elements; + } + /// Returns the raw user input used to create this CompletionRequest cut off /// at the cursor position. The cursor will be at the end of the raw line. llvm::StringRef GetRawLine() const { @@ -157,6 +162,23 @@ class CompletionRequest { size_t GetCursorIndex() const { return m_cursor_index; } + size_t GetMaxReturnElements() const { return m_max_return_elements; } + + /// Returns true if the maximum number of completions has been reached + /// already. + bool ShouldStopAddingResults() const { +return m_result.GetNumberOfResults() >= m_max_return_elements; + } + + /// Returns the maximum number of completions that need to be added + /// until reaching the maximum + size_t GetMaxNumberOfResultsToAdd() const { +const size_t number_of_results = m_result.GetNumberOfResults(); +if (number_of_results >= m_max_return_elements) + return 0; +return m_max_return_elements - number_of_results; + } + /// Adds a possible completion string. If the completion was already /// suggested before, it will not be added to the list of results. A copy of /// the suggested completion is stored, so the given string can be free'd @@ -231,6 +253,8 @@ class CompletionRequest { size_t m_cursor_index; /// The cursor position in the argument indexed by m_cursor_index. size_t m_cursor_char_position; + /// The maximum number of completions that should be returned. + size_t m_max_return_elements = SIZE_MAX; /// The result this request is supposed to fill out. /// We keep this object private to ensure that no backend can in any way diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp index de22a9dd96bd8..ad3cc3c556fd4 100644 --- a/lldb/source/API/SBCommandInterpreter.cpp +++ b/lldb/source/API/SBCommandInterpreter.cpp @@ -266,6 +266,8 @@ int SBCommandInterpreter::HandleCompletionWithDescriptions( lldb_private::StringList lldb_matches, lldb_descriptions; CompletionResult result; CompletionRequest request(current_line, cursor - current_line, result); + if (max_return_elements >= 0) +request.SetMaxReturnElements(max_return_elements); m_opaque_ptr->HandleCompletion(request); result.GetMatches(lldb_matches); result.GetDescriptions(lldb_descriptions); diff --git a/lldb/source/Commands/CommandCompletions.cpp b/lldb/source/Commands/CommandCompletions.cpp index 216aaf9abce6c..11cb94d4eda15 100644 --- a/lldb/source/Commands/CommandCompletions.cpp +++ b/lldb/source/Commands/CommandCompletions.cpp @@ -91,7 +91,7 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks( nullptr} // This one has to be last in the list. }; - for (int i = 0;; i++) { + for (int i = 0; !request.ShouldStopAddingResults(); i++) { if (common_completions[i].type == lldb::eTerminatorCompletion) break; else if ((common_completions[i].type & completion_mask) == @@ -167,7 +167,9 @@ class SourceFileCompleter : public Completer { m_matching_files.AppendIfUnique(context.comp_unit->GetPrimaryFile()); } } -return Searcher::eCallbackReturnContinue; +return m_matching_files.GetSize() >= m_request.GetMaxNumberOfResultsToAdd() + ? Searcher::eCallbackReturnStop + : Searcher::eCallbackReturnContinue; } void DoCompletion(SearchFilter *filter) override { @@ -230,6 +232,10 @@ class SymbolCompleter : public Completer { // Now add the functions & symbols to the list - only add if unique: for (const SymbolContext &sc : sc_list) { +if (m_match_set.size() >= m_request.GetMaxNumberOfResultsToAdd()) { + break; +} + ConstString func_name = sc.GetFunctionName(Mang
[Lldb-commits] [lldb] [lldb] returning command completions up to a maximum (PR #135565)
@@ -230,6 +232,9 @@ class SymbolCompleter : public Completer { // Now add the functions & symbols to the list - only add if unique: for (const SymbolContext &sc : sc_list) { +if (m_match_set.size() >= m_request.GetMaxNumberOfResultsToAdd()) eronnen wrote: In this case at the last iteration `m_match_set.size() == 254` before adding the last completion, so it will still be added... if `m_match_set.size() > m_request.GetMaxNumberOfResultsToAdd()` it means that the number of completions added at the end will be bigger than the max number https://github.com/llvm/llvm-project/pull/135565 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] fix inconsistent debugAdapterHostname argument name (PR #135544)
https://github.com/eronnen created https://github.com/llvm/llvm-project/pull/135544 the argument is written as `debugAdapterHostname` in package.json but used as `debugAdapterHost` >From 2428391183090dd68a5433b8c3a89bf8ad326625 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 13 Apr 2025 14:33:17 +0200 Subject: [PATCH] fix inconsistent debugAdapterHostname parameter name --- lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts| 2 +- lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts index e23d717a70101..3a86d1f3f418f 100644 --- a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts +++ b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts @@ -211,7 +211,7 @@ export class LLDBDapDescriptorFactory if (session.configuration.debugAdapterPort) { return new vscode.DebugAdapterServer( session.configuration.debugAdapterPort, -session.configuration.debugAdapterHost, +session.configuration.debugAdapterHostname, ); } diff --git a/lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts b/lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts index 0272509ee55f7..8d92139c02a00 100644 --- a/lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts +++ b/lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts @@ -32,11 +32,11 @@ export class LLDBDapConfigurationProvider ): Promise { try { if ( -"debugAdapterHost" in debugConfiguration && +"debugAdapterHostname" in debugConfiguration && !("debugAdapterPort" in debugConfiguration) ) { throw new ErrorWithNotification( - "A debugAdapterPort must be provided when debugAdapterHost is set. Please update your launch configuration.", + "A debugAdapterPort must be provided when debugAdapterHostname is set. Please update your launch configuration.", new ConfigureButton(), ); } @@ -83,7 +83,7 @@ export class LLDBDapConfigurationProvider // and list of arguments. delete debugConfiguration.debugAdapterExecutable; delete debugConfiguration.debugAdapterArgs; - debugConfiguration.debugAdapterHost = serverInfo.host; + debugConfiguration.debugAdapterHostname = serverInfo.host; debugConfiguration.debugAdapterPort = serverInfo.port; } } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] fallback to assembly when source code is not available (PR #136494)
eronnen wrote: @jasonmolenda fair enough, but still as a user who would like to see assembly instead of an error when the source is not available I don't have any solution currently. If I were to check the `stop-disassembly-display` value when returning the source info, would that be acceptable? https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] fallback to assembly when source code is not available (PR #136494)
eronnen wrote: Maybe this setting should be exposed in the vscode launch configuration so it will be more findable for users though https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] fallback to assembly when source code is not available (PR #136494)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136494 >From 0bf4cfcbd1fe2a006a68cb6f85af9a09a49b47e7 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 17:07:09 +0200 Subject: [PATCH 1/3] fallback to assembly when source code is not available --- lldb/tools/lldb-dap/JSONUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..1a44df7740639 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -750,9 +750,10 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, EmplaceSafeString(object, "name", frame_name); auto line_entry = frame.GetLineEntry(); + auto file_spec = line_entry.GetFileSpec(); // A line entry of 0 indicates the line is compiler generated i.e. no source // file is associated with the frame. - if (line_entry.GetFileSpec().IsValid() && + if (file_spec.IsValid() && file_spec.Exists() && (line_entry.GetLine() != 0 || line_entry.GetLine() != LLDB_INVALID_LINE_NUMBER)) { object.try_emplace("source", CreateSource(line_entry)); >From cbcebed97b9ce9251aa27ee384347b283d0625d3 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:03:02 +0200 Subject: [PATCH 2/3] fix TestDAP_coreFile.py with source maps --- .../API/tools/lldb-dap/coreFile/TestDAP_coreFile.py| 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index 1896acea15a99..ce54133a61f3e 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py +++ b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py @@ -19,7 +19,9 @@ def test_core_file(self): core_file = os.path.join(current_dir, "linux-x86_64.core") self.create_debug_adapter() -self.attach(exe_file, coreFile=core_file) + +source_map = [["/home/labath/test", current_dir]] +self.attach(exe_file, coreFile=core_file, sourceMap=source_map) expected_frames = [ { @@ -27,7 +29,7 @@ def test_core_file(self): "id": 524288, "line": 4, "name": "bar", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40011C", }, { @@ -35,7 +37,7 @@ def test_core_file(self): "id": 524289, "line": 10, "name": "foo", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x400142", }, { @@ -43,7 +45,7 @@ def test_core_file(self): "id": 524290, "line": 16, "name": "_start", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40015F", }, ] >From d2062b80083929a28a1e8e75d43ea5f96f057fa4 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:04:46 +0200 Subject: [PATCH 3/3] use stop-disassembly-display setting to determine when to show disassembly --- .../lldb-dap/coreFile/TestDAP_coreFile.py | 10 +- .../stackTraceDisassemblyDisplay/Makefile | 3 + .../TestDAP_stackTraceDisassemblyDisplay.py | 120 ++ .../stackTraceDisassemblyDisplay/main.c | 10 ++ lldb/tools/lldb-dap/DAP.h | 4 + .../lldb-dap/Handler/AttachRequestHandler.cpp | 1 + .../lldb-dap/Handler/LaunchRequestHandler.cpp | 1 + .../tools/lldb-dap/Handler/RequestHandler.cpp | 4 + lldb/tools/lldb-dap/Handler/RequestHandler.h | 3 + .../Handler/StackTraceRequestHandler.cpp | 3 +- lldb/tools/lldb-dap/JSONUtils.cpp | 34 +++-- lldb/tools/lldb-dap/JSONUtils.h | 21 ++- lldb/tools/lldb-dap/LLDBUtils.cpp | 19 +++ lldb/tools/lldb-dap/LLDBUtils.h | 9 ++ 14 files changed, 225 insertions(+), 17 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/main.c diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index ce54133a61f3e..1896acea15a99 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/T
[Lldb-commits] [lldb] fallback to assembly when source code is not available (PR #136494)
eronnen wrote: I refactored the code now to use the `stop-assembly-display` setting, I think it makes sense to use it especially since it support the `no-source` value which was what I was looking for https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] fallback to assembly when source code is not available (PR #136494)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136494 >From 0bf4cfcbd1fe2a006a68cb6f85af9a09a49b47e7 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 17:07:09 +0200 Subject: [PATCH 1/3] fallback to assembly when source code is not available --- lldb/tools/lldb-dap/JSONUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..1a44df7740639 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -750,9 +750,10 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, EmplaceSafeString(object, "name", frame_name); auto line_entry = frame.GetLineEntry(); + auto file_spec = line_entry.GetFileSpec(); // A line entry of 0 indicates the line is compiler generated i.e. no source // file is associated with the frame. - if (line_entry.GetFileSpec().IsValid() && + if (file_spec.IsValid() && file_spec.Exists() && (line_entry.GetLine() != 0 || line_entry.GetLine() != LLDB_INVALID_LINE_NUMBER)) { object.try_emplace("source", CreateSource(line_entry)); >From cbcebed97b9ce9251aa27ee384347b283d0625d3 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:03:02 +0200 Subject: [PATCH 2/3] fix TestDAP_coreFile.py with source maps --- .../API/tools/lldb-dap/coreFile/TestDAP_coreFile.py| 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index 1896acea15a99..ce54133a61f3e 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py +++ b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py @@ -19,7 +19,9 @@ def test_core_file(self): core_file = os.path.join(current_dir, "linux-x86_64.core") self.create_debug_adapter() -self.attach(exe_file, coreFile=core_file) + +source_map = [["/home/labath/test", current_dir]] +self.attach(exe_file, coreFile=core_file, sourceMap=source_map) expected_frames = [ { @@ -27,7 +29,7 @@ def test_core_file(self): "id": 524288, "line": 4, "name": "bar", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40011C", }, { @@ -35,7 +37,7 @@ def test_core_file(self): "id": 524289, "line": 10, "name": "foo", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x400142", }, { @@ -43,7 +45,7 @@ def test_core_file(self): "id": 524290, "line": 16, "name": "_start", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40015F", }, ] >From dd8735e1eb7c9582a7f16d45f8106cbfcda2d02f Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:04:46 +0200 Subject: [PATCH 3/3] use stop-disassembly-display setting to determine when to show disassembly --- .../lldb-dap/coreFile/TestDAP_coreFile.py | 10 +- .../stackTraceDisassemblyDisplay/Makefile | 3 + .../TestDAP_stackTraceDisassemblyDisplay.py | 195 ++ .../stackTraceDisassemblyDisplay/main.c | 10 + lldb/tools/lldb-dap/DAP.h | 4 + .../lldb-dap/Handler/AttachRequestHandler.cpp | 1 + .../lldb-dap/Handler/LaunchRequestHandler.cpp | 1 + .../tools/lldb-dap/Handler/RequestHandler.cpp | 4 + lldb/tools/lldb-dap/Handler/RequestHandler.h | 3 + .../Handler/StackTraceRequestHandler.cpp | 3 +- lldb/tools/lldb-dap/JSONUtils.cpp | 34 ++- lldb/tools/lldb-dap/JSONUtils.h | 21 +- lldb/tools/lldb-dap/LLDBUtils.cpp | 19 ++ lldb/tools/lldb-dap/LLDBUtils.h | 9 + 14 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/main.c diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index ce54133a61f3e..1896acea15a99 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP
[Lldb-commits] [lldb] fallback to assembly when source code is not available (PR #136494)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] fallback to assembly when source code is not available (PR #136494)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] fix wrong assembly line number (PR #136486)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/136486 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] fix wrong assembly line number x64 (PR #136486)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/136486 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
@@ -163,6 +163,25 @@ GetEnvironmentFromArguments(const llvm::json::Object &arguments) { return envs; } +std::string GetStopDisassemblyDisplay(lldb::SBDebugger &debugger) { + std::string stop_disassembly_display = "no-debuginfo"; // default value eronnen wrote: I wonder whethre this setting should be exported from `SBDebugger`, wdyt? @JDevlieghere https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] fix wrong assembly line number (PR #136486)
https://github.com/eronnen created https://github.com/llvm/llvm-project/pull/136486 Fix wrong assembly line number calculation that assumes the instruction size is `GetAddressByteSize() / 2` >From 0efcbcfa2383e8ffac29904af90313f04bcdfa4a Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 14:27:53 +0200 Subject: [PATCH] fix wrong assembly line number when debugging assembly with different sized instructions --- .../Handler/StackTraceRequestHandler.cpp | 3 ++- lldb/tools/lldb-dap/JSONUtils.cpp | 22 ++- lldb/tools/lldb-dap/JSONUtils.h | 7 -- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp index a58e3325af100..5d1d2835b4392 100644 --- a/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp @@ -67,7 +67,8 @@ static bool FillStackFrames(DAP &dap, lldb::SBThread &thread, break; } -stack_frames.emplace_back(CreateStackFrame(frame, dap.frame_format)); +stack_frames.emplace_back( +CreateStackFrame(frame, dap.frame_format, dap.target)); } if (dap.configuration.displayExtendedBacktrace && reached_end_of_stack) { diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..552fdc9439845 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -19,6 +19,8 @@ #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBFrame.h" #include "lldb/API/SBFunction.h" +#include "lldb/API/SBInstruction.h" +#include "lldb/API/SBInstructionList.h" #include "lldb/API/SBLineEntry.h" #include "lldb/API/SBModule.h" #include "lldb/API/SBQueue.h" @@ -719,8 +721,8 @@ llvm::json::Value CreateSource(llvm::StringRef source_path) { // }, // "required": [ "id", "name", "line", "column" ] // } -llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, - lldb::SBFormat &format) { +llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, lldb::SBFormat &format, + lldb::SBTarget &target) { llvm::json::Object object; int64_t frame_id = MakeDAPFrameID(frame); object.try_emplace("id", frame_id); @@ -776,10 +778,18 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, // Calculate the line of the current PC from the start of the current // symbol. -lldb::addr_t inst_offset = frame.GetPCAddress().GetOffset() - - frame.GetSymbol().GetStartAddress().GetOffset(); -lldb::addr_t inst_line = -inst_offset / (frame.GetThread().GetProcess().GetAddressByteSize() / 2); +lldb::SBAddress current_address = frame.GetPCAddress(); +lldb::SBInstructionList inst_list = +frame.GetSymbol().GetInstructions(target); +size_t inst_line = 0; +for (size_t i = 0; i < inst_list.GetSize(); ++i) { + lldb::SBInstruction inst = inst_list.GetInstructionAtIndex(i); + if (inst.GetAddress() == current_address) { +inst_line = i; +break; + } +} + // Line numbers are 1-based. object.try_emplace("line", inst_line + 1); object.try_emplace("column", 1); diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h index b8c53353bf42d..ffa10743501b8 100644 --- a/lldb/tools/lldb-dap/JSONUtils.h +++ b/lldb/tools/lldb-dap/JSONUtils.h @@ -363,11 +363,14 @@ llvm::json::Value CreateSource(llvm::StringRef source_path); /// The LLDB format to use when populating out the "StackFrame" /// object. /// +/// \param[in] target +/// The LLDB target to use when populating out the "StackFrame" +/// object. /// \return /// A "StackFrame" JSON object with that follows the formal JSON /// definition outlined by Microsoft. -llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, - lldb::SBFormat &format); +llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, lldb::SBFormat &format, + lldb::SBTarget &target); /// Create a "StackFrame" label object for a LLDB thread. /// ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] fallback to assembly when source code is not available (PR #136494)
https://github.com/eronnen created https://github.com/llvm/llvm-project/pull/136494 Show assembly code when the source code for a frame is not available in the debugger machine Fix #136492 After the fix: [Screencast From 2025-04-20 18-00-30.webm](https://github.com/user-attachments/assets/1ce41715-cf4f-42a1-8f5c-6196b9d685dc) >From f9d6bcdc606d28db5de42fcdeca55408979ddafb Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 17:07:09 +0200 Subject: [PATCH] fallback to assembly when source code is not available --- lldb/tools/lldb-dap/JSONUtils.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..5b647950cfc6e 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -750,9 +750,11 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, EmplaceSafeString(object, "name", frame_name); auto line_entry = frame.GetLineEntry(); + auto file_spec = line_entry.GetFileSpec(); // A line entry of 0 indicates the line is compiler generated i.e. no source // file is associated with the frame. - if (line_entry.GetFileSpec().IsValid() && + if (file_spec.IsValid() && + file_spec.Exists() && (line_entry.GetLine() != 0 || line_entry.GetLine() != LLDB_INVALID_LINE_NUMBER)) { object.try_emplace("source", CreateSource(line_entry)); ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] fallback to assembly when source code is not available (PR #136494)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136494 >From c7da2d8281823d689b85bc836f3ed947857aaa32 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 17:07:09 +0200 Subject: [PATCH] fallback to assembly when source code is not available --- lldb/tools/lldb-dap/JSONUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..1a44df7740639 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -750,9 +750,10 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, EmplaceSafeString(object, "name", frame_name); auto line_entry = frame.GetLineEntry(); + auto file_spec = line_entry.GetFileSpec(); // A line entry of 0 indicates the line is compiler generated i.e. no source // file is associated with the frame. - if (line_entry.GetFileSpec().IsValid() && + if (file_spec.IsValid() && file_spec.Exists() && (line_entry.GetLine() != 0 || line_entry.GetLine() != LLDB_INVALID_LINE_NUMBER)) { object.try_emplace("source", CreateSource(line_entry)); ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show load addresses in disassembly (PR #136755)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136755 >From c1c072875b9a7ad3d11a03d3c1e4a8b6452749f9 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Tue, 22 Apr 2025 21:58:19 +0200 Subject: [PATCH 1/3] [lldb-dap]: show load addresses in disassembly --- lldb/include/lldb/API/SBFrame.h | 1 + lldb/include/lldb/API/SBInstructionList.h | 7 +++-- lldb/source/API/SBInstructionList.cpp | 29 ++- .../lldb-dap/Handler/SourceRequestHandler.cpp | 2 +- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h index 3635ee5a537ad..66db059d531a8 100644 --- a/lldb/include/lldb/API/SBFrame.h +++ b/lldb/include/lldb/API/SBFrame.h @@ -221,6 +221,7 @@ class LLDB_API SBFrame { friend class SBBlock; friend class SBExecutionContext; friend class SBInstruction; + friend class SBInstructionList; friend class SBThread; friend class SBValue; diff --git a/lldb/include/lldb/API/SBInstructionList.h b/lldb/include/lldb/API/SBInstructionList.h index 4c26ec9a294e0..b337c91721653 100644 --- a/lldb/include/lldb/API/SBInstructionList.h +++ b/lldb/include/lldb/API/SBInstructionList.h @@ -54,6 +54,10 @@ class LLDB_API SBInstructionList { bool GetDescription(lldb::SBStream &description); + // Writes assembly instructions to `description` with load addresses using + // `frame`. + bool GetDescription(lldb::SBStream &description, lldb::SBFrame &frame); + bool DumpEmulationForAllInstructions(const char *triple); protected: @@ -62,8 +66,7 @@ class LLDB_API SBInstructionList { friend class SBTarget; void SetDisassembler(const lldb::DisassemblerSP &opaque_sp); - bool GetDescription(lldb_private::Stream &description); - + bool GetDescription(lldb_private::Stream &description, lldb::SBFrame *frame); private: lldb::DisassemblerSP m_opaque_sp; diff --git a/lldb/source/API/SBInstructionList.cpp b/lldb/source/API/SBInstructionList.cpp index c18204375dff1..79432e8c6c91a 100644 --- a/lldb/source/API/SBInstructionList.cpp +++ b/lldb/source/API/SBInstructionList.cpp @@ -15,8 +15,10 @@ #include "lldb/Core/Module.h" #include "lldb/Host/StreamFile.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/ExecutionContext.h" #include "lldb/Utility/Instrumentation.h" #include "lldb/Utility/Stream.h" +#include using namespace lldb; using namespace lldb_private; @@ -114,7 +116,7 @@ void SBInstructionList::Print(FILE *out) { if (out == nullptr) return; StreamFile stream(out, false); - GetDescription(stream); + GetDescription(stream, nullptr); } void SBInstructionList::Print(SBFile out) { @@ -122,7 +124,7 @@ void SBInstructionList::Print(SBFile out) { if (!out.IsValid()) return; StreamFile stream(out.m_opaque_sp); - GetDescription(stream); + GetDescription(stream, nullptr); } void SBInstructionList::Print(FileSP out_sp) { @@ -130,15 +132,21 @@ void SBInstructionList::Print(FileSP out_sp) { if (!out_sp || !out_sp->IsValid()) return; StreamFile stream(out_sp); - GetDescription(stream); + GetDescription(stream, nullptr); } bool SBInstructionList::GetDescription(lldb::SBStream &stream) { LLDB_INSTRUMENT_VA(this, stream); - return GetDescription(stream.ref()); + return GetDescription(stream.ref(), nullptr); } -bool SBInstructionList::GetDescription(Stream &sref) { +bool SBInstructionList::GetDescription(lldb::SBStream &stream, + lldb::SBFrame &frame) { + LLDB_INSTRUMENT_VA(this, stream); + return GetDescription(stream.ref(), &frame); +} + +bool SBInstructionList::GetDescription(Stream &sref, lldb::SBFrame *frame) { if (m_opaque_sp) { size_t num_instructions = GetSize(); @@ -148,10 +156,15 @@ bool SBInstructionList::GetDescription(Stream &sref) { const uint32_t max_opcode_byte_size = m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize(); FormatEntity::Entry format; - FormatEntity::Parse("${addr}: ", format); + FormatEntity::Parse("${addr-file-or-load}: ", format); SymbolContext sc; SymbolContext prev_sc; + std::shared_ptr exec_ctx; + if (nullptr != frame) { +exec_ctx = std::make_shared(frame->GetFrameSP()); + } + // Expected address of the next instruction. Used to print an empty line // for non-contiguous blocks of insns. std::optional next_addr; @@ -172,8 +185,8 @@ bool SBInstructionList::GetDescription(Stream &sref) { if (next_addr && *next_addr != addr) sref.EOL(); inst->Dump(&sref, max_opcode_byte_size, true, false, - /*show_control_flow_kind=*/false, nullptr, &sc, &prev_sc, - &format, 0); + /*show_control_flow_kind=*/false, exec_ctx.get(), &sc, + &prev_sc, &format, 0); sref.EOL(); next_addr = addr; next_addr->Slide(ins
[Lldb-commits] [lldb] [lldb-dap] Show load addresses in disassembly (PR #136755)
@@ -62,8 +67,8 @@ class LLDB_API SBInstructionList { friend class SBTarget; void SetDisassembler(const lldb::DisassemblerSP &opaque_sp); - bool GetDescription(lldb_private::Stream &description); - + bool GetDescription(lldb_private::Stream &description, + lldb::SBExecutionContext *exe_ctx = nullptr); eronnen wrote: :100: https://github.com/llvm/llvm-project/pull/136755 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show load addresses in disassembly (PR #136755)
@@ -138,7 +141,14 @@ bool SBInstructionList::GetDescription(lldb::SBStream &stream) { return GetDescription(stream.ref()); } -bool SBInstructionList::GetDescription(Stream &sref) { +bool SBInstructionList::GetDescription(lldb::SBStream &stream, + lldb::SBExecutionContext &exe_ctx) { + LLDB_INSTRUMENT_VA(this, stream); + return GetDescription(stream.ref(), &exe_ctx); +} + +bool SBInstructionList::GetDescription(Stream &sref, + lldb::SBExecutionContext *exe_ctx) { eronnen wrote: :100: https://github.com/llvm/llvm-project/pull/136755 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show load addresses in disassembly (PR #136755)
@@ -148,10 +158,15 @@ bool SBInstructionList::GetDescription(Stream &sref) { const uint32_t max_opcode_byte_size = m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize(); FormatEntity::Entry format; - FormatEntity::Parse("${addr}: ", format); + FormatEntity::Parse("${addr-file-or-load}: ", format); SymbolContext sc; SymbolContext prev_sc; + std::shared_ptr exe_ctx_ptr; + if (nullptr != exe_ctx) { +exe_ctx_ptr = std::make_shared(exe_ctx->get()); + } eronnen wrote: :100: https://github.com/llvm/llvm-project/pull/136755 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show load addresses in disassembly (PR #136755)
eronnen wrote: @JDevlieghere Nice catch, now that the internal `GetDescription` gets the private type there is no need for the `shared_ptr` eveb https://github.com/llvm/llvm-project/pull/136755 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] migrate set breakpoint requests (PR #137448)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137448 >From dc8388b0027c75dba465c72009ac0c25750ae877 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sat, 26 Apr 2025 10:25:21 +0200 Subject: [PATCH 1/2] adding breakpoints protocol types add all breakpoint requests JSON types decouple JSON from DAP Breakpoint classes forgor exception breakpoint response migrating breakpoint requests migrate breakpoints requests handler implementations remove CreateBreakpoint data breakpoint requests serialization fix GetFrame fix data breakpoint return exception breakpoints list restore exception breakpoints --- lldb/tools/lldb-dap/Breakpoint.cpp| 22 +- lldb/tools/lldb-dap/Breakpoint.h | 6 +- lldb/tools/lldb-dap/BreakpointBase.cpp| 12 +- lldb/tools/lldb-dap/BreakpointBase.h | 8 +- lldb/tools/lldb-dap/DAP.cpp | 11 +- lldb/tools/lldb-dap/DAP.h | 1 + lldb/tools/lldb-dap/FunctionBreakpoint.cpp| 8 +- lldb/tools/lldb-dap/FunctionBreakpoint.h | 3 +- .../DataBreakpointInfoRequestHandler.cpp | 175 -- .../Handler/InitializeRequestHandler.cpp | 2 +- lldb/tools/lldb-dap/Handler/RequestHandler.h | 51 ++-- .../Handler/SetBreakpointsRequestHandler.cpp | 180 +++--- .../SetDataBreakpointsRequestHandler.cpp | 98 ++-- .../SetFunctionBreakpointsRequestHandler.cpp | 115 ++--- ...etInstructionBreakpointsRequestHandler.cpp | 223 ++ ...TestGetTargetBreakpointsRequestHandler.cpp | 2 +- lldb/tools/lldb-dap/InstructionBreakpoint.cpp | 15 +- lldb/tools/lldb-dap/InstructionBreakpoint.h | 4 +- lldb/tools/lldb-dap/JSONUtils.cpp | 161 + lldb/tools/lldb-dap/JSONUtils.h | 67 +- .../lldb-dap/Protocol/ProtocolRequests.cpp| 70 ++ .../lldb-dap/Protocol/ProtocolRequests.h | 147 .../tools/lldb-dap/Protocol/ProtocolTypes.cpp | 127 ++ lldb/tools/lldb-dap/Protocol/ProtocolTypes.h | 181 ++ lldb/tools/lldb-dap/SourceBreakpoint.cpp | 13 +- lldb/tools/lldb-dap/SourceBreakpoint.h| 3 +- lldb/tools/lldb-dap/Watchpoint.cpp| 26 +- lldb/tools/lldb-dap/Watchpoint.h | 6 +- llvm/include/llvm/Support/JSON.h | 8 + 29 files changed, 790 insertions(+), 955 deletions(-) diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp b/lldb/tools/lldb-dap/Breakpoint.cpp index 5679fd545d53f..26d633d1d172e 100644 --- a/lldb/tools/lldb-dap/Breakpoint.cpp +++ b/lldb/tools/lldb-dap/Breakpoint.cpp @@ -14,7 +14,6 @@ #include "lldb/API/SBLineEntry.h" #include "lldb/API/SBMutex.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/Support/JSON.h" #include #include #include @@ -30,13 +29,16 @@ void Breakpoint::SetHitCondition() { m_bp.SetIgnoreCount(hitCount - 1); } -void Breakpoint::CreateJsonObject(llvm::json::Object &object) { +protocol::Breakpoint Breakpoint::ToProtocolBreakpoint() { + protocol::Breakpoint breakpoint; + // Each breakpoint location is treated as a separate breakpoint for VS code. // They don't have the notion of a single breakpoint with multiple locations. if (!m_bp.IsValid()) -return; - object.try_emplace("verified", m_bp.GetNumResolvedLocations() > 0); - object.try_emplace("id", m_bp.GetID()); +return breakpoint; + + breakpoint.verified = m_bp.GetNumResolvedLocations() > 0; + breakpoint.id = m_bp.GetID(); // VS Code DAP doesn't currently allow one breakpoint to have multiple // locations so we just report the first one. If we report all locations // then the IDE starts showing the wrong line numbers and locations for @@ -60,16 +62,18 @@ void Breakpoint::CreateJsonObject(llvm::json::Object &object) { if (bp_addr.IsValid()) { std::string formatted_addr = "0x" + llvm::utohexstr(bp_addr.GetLoadAddress(m_bp.GetTarget())); -object.try_emplace("instructionReference", formatted_addr); +breakpoint.instructionReference = formatted_addr; auto line_entry = bp_addr.GetLineEntry(); const auto line = line_entry.GetLine(); if (line != UINT32_MAX) - object.try_emplace("line", line); + breakpoint.line = line; const auto column = line_entry.GetColumn(); if (column != 0) - object.try_emplace("column", column); -object.try_emplace("source", CreateSource(line_entry)); + breakpoint.column = column; +breakpoint.source = CreateSource(line_entry); } + + return breakpoint; } bool Breakpoint::MatchesName(const char *name) { diff --git a/lldb/tools/lldb-dap/Breakpoint.h b/lldb/tools/lldb-dap/Breakpoint.h index 580017125af44..c4f1fa291f181 100644 --- a/lldb/tools/lldb-dap/Breakpoint.h +++ b/lldb/tools/lldb-dap/Breakpoint.h @@ -17,14 +17,16 @@ namespace lldb_dap { class Breakpoint : public BreakpointBase { public: - Breakpoint(DAP &d, const llvm::json::Object &obj) : BreakpointBase(d,
[Lldb-commits] [lldb] [llvm] [lldb-dap] migrate set breakpoint requests (PR #137448)
@@ -322,6 +323,186 @@ enum SteppingGranularity : unsigned { bool fromJSON(const llvm::json::Value &, SteppingGranularity &, llvm::json::Path); +/// Information about a breakpoint created in `setBreakpoints`, +/// `setFunctionBreakpoints`, `setInstructionBreakpoints`, or +/// `setDataBreakpoints` requests. +struct Breakpoint { + /// A machine-readable explanation of why a breakpoint may not be verified. + enum class Reason : unsigned { +/// Indicates a breakpoint might be verified in the future, but +/// the adapter cannot verify it in the current state. +eBreakpointReasonPending, +/// Indicates a breakpoint was not able to be verified, and the +/// adapter does not believe it can be verified without intervention. +eBreakpointReasonFailed, + }; + + /// The identifier for the breakpoint. It is needed if breakpoint events are + /// used to update or remove breakpoints. + std::optional id; + + /// If true, the breakpoint could be set (but not necessarily at the desired + /// location). + bool verified; + + /// A message about the state of the breakpoint. + /// This is shown to the user and can be used to explain why a breakpoint + /// could not be verified. + std::optional message; + + /// The source where the breakpoint is located. + std::optional source; + + /// The start line of the actual range covered by the breakpoint. + std::optional line; + + /// Start position of the source range covered by the breakpoint. It is + /// measured in UTF-16 code units and the client capability `columnsStartAt1` + /// determines whether it is 0- or 1-based. + std::optional column; + + /// The end line of the actual range covered by the breakpoint. + std::optional endLine; + + /// End position of the source range covered by the breakpoint. It is measured + /// in UTF-16 code units and the client capability `columnsStartAt1` + /// determines whether it is 0- or 1-based. If no end line is given, then the + /// end column is assumed to be in the start line. + std::optional endColumn; + + /// A memory reference to where the breakpoint is set. + std::optional instructionReference; + + /// The offset from the instruction reference. + /// This can be negative. + std::optional offset; + + /// A machine-readable explanation of why a breakpoint may not be verified. If + /// a breakpoint is verified or a specific reason is not known, the adapter + /// should omit this property. + std::optional reason; +}; +llvm::json::Value toJSON(const Breakpoint &); + +/// Properties of a breakpoint or logpoint passed to the `setBreakpoints` +/// request +struct SourceBreakpoint { + /// The source line of the breakpoint or logpoint. + uint32_t line; eronnen wrote: added https://github.com/llvm/llvm-project/pull/137448 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] migrate set breakpoint requests (PR #137448)
@@ -43,6 +43,32 @@ bool fromJSON(const json::Value &Params, Source &S, json::Path P) { O.map("sourceReference", S.sourceReference); } +static llvm::json::Value ToString(PresentationHint hint) { eronnen wrote: :100: https://github.com/llvm/llvm-project/pull/137448 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] migrate set breakpoint requests (PR #137448)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/137448 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] add settings to control how synthetic symbol names are generated (PR #137512)
eronnen wrote: The use case is to make it easier to work with static disassemblers: If I see an interesting unnamed function while debugging, it would be immediate to search it in the static disassembler if it was named `lldb_unnamed_symbol_{file-addreds}` as opposed to a random index. Also vice versa: If I see an interesting function in a static disassembler, I could immediately set a breakpoint on it using the file address. https://github.com/llvm/llvm-project/pull/137512 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] migrate set breakpoint requests (PR #137448)
@@ -322,6 +323,186 @@ enum SteppingGranularity : unsigned { bool fromJSON(const llvm::json::Value &, SteppingGranularity &, llvm::json::Path); +/// Information about a breakpoint created in `setBreakpoints`, +/// `setFunctionBreakpoints`, `setInstructionBreakpoints`, or +/// `setDataBreakpoints` requests. +struct Breakpoint { + /// A machine-readable explanation of why a breakpoint may not be verified. + enum class Reason : unsigned { +/// Indicates a breakpoint might be verified in the future, but +/// the adapter cannot verify it in the current state. +eBreakpointReasonPending, +/// Indicates a breakpoint was not able to be verified, and the +/// adapter does not believe it can be verified without intervention. +eBreakpointReasonFailed, + }; + + /// The identifier for the breakpoint. It is needed if breakpoint events are + /// used to update or remove breakpoints. + std::optional id; + + /// If true, the breakpoint could be set (but not necessarily at the desired + /// location). + bool verified; eronnen wrote: :100: https://github.com/llvm/llvm-project/pull/137448 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] migrate set breakpoint requests (PR #137448)
@@ -322,6 +323,186 @@ enum SteppingGranularity : unsigned { bool fromJSON(const llvm::json::Value &, SteppingGranularity &, llvm::json::Path); +/// Information about a breakpoint created in `setBreakpoints`, +/// `setFunctionBreakpoints`, `setInstructionBreakpoints`, or +/// `setDataBreakpoints` requests. +struct Breakpoint { + /// A machine-readable explanation of why a breakpoint may not be verified. + enum class Reason : unsigned { +/// Indicates a breakpoint might be verified in the future, but +/// the adapter cannot verify it in the current state. +eBreakpointReasonPending, +/// Indicates a breakpoint was not able to be verified, and the +/// adapter does not believe it can be verified without intervention. +eBreakpointReasonFailed, + }; eronnen wrote: :100: https://github.com/llvm/llvm-project/pull/137448 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Handle stack frames without a module (PR #136777)
https://github.com/eronnen created https://github.com/llvm/llvm-project/pull/136777 * Fix error in lldb-dap when the stack trace contains a frame without a module by simply showing the first 32 assembly instructions after the PC >From 93764e39ce2588ea0f86cf8283fa6c82bd89a8de Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Wed, 23 Apr 2025 00:06:28 +0200 Subject: [PATCH] [lldb-dap] handle stack frames without a module --- .../lldb-dap/stackTraceMissingModule/Makefile | 2 + .../TestDAP_stackTraceMissingModule.py| 54 +++ .../lldb-dap/stackTraceMissingModule/main.c | 37 + .../lldb-dap/Handler/SourceRequestHandler.cpp | 14 - lldb/tools/lldb-dap/JSONUtils.cpp | 10 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c diff --git a/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile new file mode 100644 index 0..c9319d6e6888a --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile @@ -0,0 +1,2 @@ +C_SOURCES := main.c +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py new file mode 100644 index 0..1eb00f9935a22 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py @@ -0,0 +1,54 @@ +""" +Test lldb-dap stack trace when module is missing +""" + +from lldbsuite.test.decorators import skipUnlessPlatform +from lldbsuite.test.lldbtest import line_number +import lldbdap_testcase +import re + + +class TestDAP_stackTraceMissingModule(lldbdap_testcase.DAPTestCaseBase): +@skipUnlessPlatform(["linux"]) +def test_missingModule(self): +""" +Test that the stack frame without a module still has assembly source. +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program, commandEscapePrefix="") + +source = "main.c" +self.set_source_breakpoints( +source, +[line_number(source, "// Break here")], +) +self.continue_to_next_stop() + +# Evaluate expr -- func +expr_result = self.dap_server.request_evaluate( +expression="expr -f pointer -- func", +context="repl", +) + +expr_result_address = re.search( +r"0x[0-9a-fA-F]+", expr_result["body"]["result"] +) +self.assertIsNotNone( +expr_result_address, "Failed to get address of dynamic allocated func" +) +func_address = expr_result_address.group(0) + +self.dap_server.request_evaluate( +expression=f"breakpoint set --address {func_address}", +context="repl", +) + +self.continue_to_next_stop() + +frame_without_module = self.get_stackFrames()[0] + +self.assertIn("line", frame_without_module, "Line number missing.") +self.assertIn("column", frame_without_module, "Column number missing.") +self.assertIn("source", frame_without_module, "Source location missing.") +source = frame_without_module["source"] +self.assertIn("sourceReference", source, "Source reference missing.") diff --git a/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c new file mode 100644 index 0..d706231fbd5c2 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include + +extern uint8_t __start_target_section[]; +extern uint8_t __stop_target_section[]; + +__attribute__((used, section("target_section"))) int target_function(void) { + return 42; +} + +typedef int (*target_function_t)(void); + +int main(void) { + size_t target_function_size = __stop_target_section - __start_target_section; + size_t page_size = sysconf(_SC_PAGESIZE); + size_t page_aligned_size = + (target_function_size + page_size - 1) & ~(page_size - 1); + + void *executable_memory = + mmap(NULL, page_aligned_size, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (executable_memory == MAP_FAILED) { +perror("mmap"); +return 1; + } + + memcpy(executable_memory, __start_target_section, target_function_size); + + target_function_t func = (target_function_t)executable_memory; + int result = func(); // Break here + printf("Result from target function: %d\n", result); + + return 0; +} diff --git a/lldb/tools/lldb-dap/Handler/Source
[Lldb-commits] [lldb] [lldb-dap] Handle stack frames without a module (PR #136777)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/136777 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
@@ -163,6 +163,19 @@ GetEnvironmentFromArguments(const llvm::json::Object &arguments) { return envs; } +std::string GetStopDisassemblyDisplay(lldb::SBDebugger &debugger) { + lldb::SBStructuredData result = + debugger.GetSetting("stop-disassembly-display"); + const size_t result_length = result.GetStringValue(nullptr, 0); + if (result_length > 0) { +std::string result_string(result_length, '\0'); +result.GetStringValue(result_string.data(), result_length + 1); +return result_string; + } + + return "no-debuginfo"; eronnen wrote: not sure I understand the suggestion, do you mean having an alternative setting in the lldb-dap launch configuration and use it instead of `debugger.GetSetting`, or just export the existing `StopDisassemblyType` enum and convert the current `GetSetting` to use it? https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136494 >From 9bb3be7a7fe315cda2e63dd10d90b161e6677263 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 17:07:09 +0200 Subject: [PATCH 1/5] fallback to assembly when source code is not available --- lldb/tools/lldb-dap/JSONUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..1a44df7740639 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -750,9 +750,10 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, EmplaceSafeString(object, "name", frame_name); auto line_entry = frame.GetLineEntry(); + auto file_spec = line_entry.GetFileSpec(); // A line entry of 0 indicates the line is compiler generated i.e. no source // file is associated with the frame. - if (line_entry.GetFileSpec().IsValid() && + if (file_spec.IsValid() && file_spec.Exists() && (line_entry.GetLine() != 0 || line_entry.GetLine() != LLDB_INVALID_LINE_NUMBER)) { object.try_emplace("source", CreateSource(line_entry)); >From 87426fea3817fb4b54cf2a25560edfed763fe999 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:03:02 +0200 Subject: [PATCH 2/5] fix TestDAP_coreFile.py with source maps --- .../API/tools/lldb-dap/coreFile/TestDAP_coreFile.py| 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index 1896acea15a99..ce54133a61f3e 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py +++ b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py @@ -19,7 +19,9 @@ def test_core_file(self): core_file = os.path.join(current_dir, "linux-x86_64.core") self.create_debug_adapter() -self.attach(exe_file, coreFile=core_file) + +source_map = [["/home/labath/test", current_dir]] +self.attach(exe_file, coreFile=core_file, sourceMap=source_map) expected_frames = [ { @@ -27,7 +29,7 @@ def test_core_file(self): "id": 524288, "line": 4, "name": "bar", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40011C", }, { @@ -35,7 +37,7 @@ def test_core_file(self): "id": 524289, "line": 10, "name": "foo", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x400142", }, { @@ -43,7 +45,7 @@ def test_core_file(self): "id": 524290, "line": 16, "name": "_start", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40015F", }, ] >From e9043dc00010c603553ae067d5ff1e30aba0985e Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:04:46 +0200 Subject: [PATCH 3/5] use stop-disassembly-display setting to determine when to show disassembly --- .../lldb-dap/coreFile/TestDAP_coreFile.py | 10 +- .../stackTraceDisassemblyDisplay/Makefile | 3 + .../TestDAP_stackTraceDisassemblyDisplay.py | 195 ++ .../stackTraceDisassemblyDisplay/main.c | 10 + lldb/tools/lldb-dap/DAP.h | 4 + .../lldb-dap/Handler/AttachRequestHandler.cpp | 1 + .../lldb-dap/Handler/LaunchRequestHandler.cpp | 1 + .../tools/lldb-dap/Handler/RequestHandler.cpp | 4 + lldb/tools/lldb-dap/Handler/RequestHandler.h | 3 + .../Handler/StackTraceRequestHandler.cpp | 3 +- lldb/tools/lldb-dap/JSONUtils.cpp | 34 ++- lldb/tools/lldb-dap/JSONUtils.h | 21 +- lldb/tools/lldb-dap/LLDBUtils.cpp | 19 ++ lldb/tools/lldb-dap/LLDBUtils.h | 9 + 14 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/main.c diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index ce54133a61f3e..1896acea15a99 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP
[Lldb-commits] [lldb] [lldb-dap] fix wrong assembly line number x64 (PR #136486)
@@ -0,0 +1,64 @@ +""" +Test lldb-dap stack trace containing x86 assembly +""" + +import lldbdap_testcase +from lldbsuite.test.decorators import skipUnlessArch, skipUnlessPlatform +from lldbsuite.test.lldbtest import line_number + + +class TestDAP_stacktrace_x86(lldbdap_testcase.DAPTestCaseBase): +@skipUnlessArch("x86_64") +@skipUnlessPlatform(["linux"]) +def test_stacktrace_x86(self): +""" +Tests that lldb-dap steps through correctly and the source lines are correct in x86 assembly. +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch( +program, +initCommands=[ +"settings set target.process.thread.step-in-avoid-nodebug false" +], +) + +source = "main.c" +breakpoint_ids = self.set_source_breakpoints( +source, +[line_number(source, "// Break here")], +) +self.continue_to_breakpoints(breakpoint_ids) +self.stepIn() + +frame = self.get_stackFrames()[0] +self.assertEqual( +frame["name"], +"no_branch_func", +"verify we are in the no_branch_func function", +) + +self.assertEqual(frame["line"], 1, "verify we are at the start of the function") +minimum_assembly_lines = ( +line_number(source, "Assembly end") +- line_number(source, "Assembly start") ++ 1 +) +self.assertLessEqual( +10, +minimum_assembly_lines, +"verify we have a reasonable number of assembly lines", +) + +for i in range(2, minimum_assembly_lines): +self.stepIn() eronnen wrote: It should be the same because it's a function without debug symbols so each step should execute one instruction https://github.com/llvm/llvm-project/pull/136486 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] add settings to control how synthetic symbol names are generated (PR #137512)
@@ -639,7 +639,18 @@ void Symbol::SynthesizeNameIfNeeded() const { // breakpoints on them. llvm::SmallString<256> name; llvm::raw_svector_ostream os(name); -os << GetSyntheticSymbolPrefix() << GetID(); +os << GetSyntheticSymbolPrefix(); +switch (ModuleList::GetGlobalModuleListProperties() eronnen wrote: Not sure whether it's better to cache this setting for the session or not https://github.com/llvm/llvm-project/pull/137512 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] add settings to control how synthetic symbol names are generated (PR #137512)
https://github.com/eronnen deleted https://github.com/llvm/llvm-project/pull/137512 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] add settings to control how synthetic symbol names are generated (PR #137512)
@@ -639,7 +639,18 @@ void Symbol::SynthesizeNameIfNeeded() const { // breakpoints on them. llvm::SmallString<256> name; llvm::raw_svector_ostream os(name); -os << GetSyntheticSymbolPrefix() << GetID(); +os << GetSyntheticSymbolPrefix(); eronnen wrote: Not sure whether it's better to cache this setting for the session or not https://github.com/llvm/llvm-project/pull/137512 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] add settings to control how synthetic symbol names are generated (PR #137512)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137512 >From fd74de70151567d402eb7c0326a6234a21cb2db7 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 27 Apr 2025 13:48:45 +0200 Subject: [PATCH] [lldb] add settings to control how synthetic symbol names are generated --- lldb/include/lldb/Core/ModuleList.h | 15 +++ lldb/include/lldb/lldb-enumerations.h | 6 ++ lldb/source/Core/CoreProperties.td| 5 + lldb/source/Core/ModuleList.cpp | 8 lldb/source/Symbol/Symbol.cpp | 13 - 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index 909ee08f9ba62..baed175be5313 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -67,6 +67,20 @@ static constexpr OptionEnumValueElement g_auto_download_enum_values[] = { }, }; +static constexpr OptionEnumValueElement +g_synthetic_symbols_name_style_values[] = { +{ +lldb::eSyntheticSymbolsNameStyleIndex, +"index", +"Function index style", +}, +{ +lldb::eSyntheticSymbolsNameStyleFileAddress, +"file-address", +"Function file address in module style", +}, +}; + class ModuleListProperties : public Properties { mutable llvm::sys::RWMutex m_symlink_paths_mutex; PathMappingList m_symlink_paths; @@ -91,6 +105,7 @@ class ModuleListProperties : public Properties { bool GetLoadSymbolOnDemand(); lldb::SymbolDownload GetSymbolAutoDownload() const; + lldb::SyntheticSymbolsNameStyle GetSyntheticSymbolsNameStyle() const; PathMappingList GetSymlinkMappings() const; }; diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 6d10cc8bcffcb..26e83cefbe571 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -1391,6 +1391,12 @@ enum StopDisassemblyType { eStopDisassemblyTypeAlways }; +/// Format to use for unknown symbols. +enum SyntheticSymbolsNameStyle { + eSyntheticSymbolsNameStyleIndex = 0, + eSyntheticSymbolsNameStyleFileAddress = 1, +}; + } // namespace lldb #endif // LLDB_LLDB_ENUMERATIONS_H diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index a1a4e994c3b9c..7eaecb729c36d 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -46,6 +46,11 @@ let Definition = "modulelist" in { Global, DefaultFalse, Desc<"Enable on demand symbol loading in LLDB. LLDB will load debug info on demand for each module based on various conditions (e.g. matched breakpoint, resolved stack frame addresses and matched global variables/function symbols in symbol table) to improve performance. Please refer to docs/use/ondemand.rst for details.">; + def SyntheticSymbolsNameStyle: Property<"synthetic-symbols-name-style", "Enum">, +Global, +DefaultEnumValue<"eSyntheticSymbolsNameStyleIndex">, +EnumValues<"OptionEnumValues(g_synthetic_symbols_name_style_values)">, +Desc<"Determines the way synthetic symbol names are generated for unknown symbols">; } let Definition = "debugger" in { diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 6052cc151744d..c48c5bbfb5e92 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -115,6 +115,14 @@ SymbolDownload ModuleListProperties::GetSymbolAutoDownload() const { g_modulelist_properties[idx].default_uint_value)); } +lldb::SyntheticSymbolsNameStyle +ModuleListProperties::GetSyntheticSymbolsNameStyle() const { + const uint32_t idx = ePropertySyntheticSymbolsNameStyle; + return GetPropertyAtIndexAs( + idx, static_cast( + g_modulelist_properties[idx].default_uint_value)); +} + FileSpec ModuleListProperties::GetClangModulesCachePath() const { const uint32_t idx = ePropertyClangModulesCachePath; return GetPropertyAtIndexAs(idx, {}); diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 4828de4fdfa37..825ca5babe28e 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -639,7 +639,18 @@ void Symbol::SynthesizeNameIfNeeded() const { // breakpoints on them. llvm::SmallString<256> name; llvm::raw_svector_ostream os(name); -os << GetSyntheticSymbolPrefix() << GetID(); +os << GetSyntheticSymbolPrefix(); +switch (ModuleList::GetGlobalModuleListProperties() +.GetSyntheticSymbolsNameStyle()) { +case eSyntheticSymbolsNameStyleIndex: + os << GetID(); + break; +case eSyntheticSymbolsNameStyleFileAddress: + os << "_" + << llvm::format_hex_no_prefix( +m_addr_range.GetBaseAddress().GetFileAddress(), 0); + break; +} m_mangled.SetDemangledName(ConstString(os.str())); }
[Lldb-commits] [lldb] [lldb] add settings to control how synthetic symbol names are generated (PR #137512)
https://github.com/eronnen created https://github.com/llvm/llvm-project/pull/137512 Adds a setting that makes lldb generate synthetic symbol names according to the file address of the function instead of the index, this could make it easier when debugging crashes and stack traces to understand which function the unnamed symbols corrresponds to >From 62d7d6635a2e8c3be8916148d0572f8f36ce4db1 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 27 Apr 2025 13:48:45 +0200 Subject: [PATCH] [lldb] add settings to control how synthetic symbol names are generated --- lldb/include/lldb/Core/ModuleList.h | 14 ++ lldb/include/lldb/Symbol/Symbol.h | 1 + lldb/include/lldb/lldb-enumerations.h | 6 ++ lldb/source/Core/CoreProperties.td| 5 + lldb/source/Core/ModuleList.cpp | 7 +++ lldb/source/Symbol/Symbol.cpp | 10 +- 6 files changed, 42 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index 909ee08f9ba62..23f64a153d47d 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -67,6 +67,19 @@ static constexpr OptionEnumValueElement g_auto_download_enum_values[] = { }, }; +static constexpr OptionEnumValueElement g_synthetic_symbols_name_style_values[] = { + { + lldb::eSyntheticSymbolsNameStyleIndex, + "index", + "Function index style", + }, + { +lldb::eSyntheticSymbolsNameStyleFileAddress, + "file-address", + "Function file address in module style", + }, +}; + class ModuleListProperties : public Properties { mutable llvm::sys::RWMutex m_symlink_paths_mutex; PathMappingList m_symlink_paths; @@ -91,6 +104,7 @@ class ModuleListProperties : public Properties { bool GetLoadSymbolOnDemand(); lldb::SymbolDownload GetSymbolAutoDownload() const; + lldb::SyntheticSymbolsNameStyle GetSyntheticSymbolsNameStyle() const; PathMappingList GetSymlinkMappings() const; }; diff --git a/lldb/include/lldb/Symbol/Symbol.h b/lldb/include/lldb/Symbol/Symbol.h index e05c845a69f3e..5c37b33e7442e 100644 --- a/lldb/include/lldb/Symbol/Symbol.h +++ b/lldb/include/lldb/Symbol/Symbol.h @@ -339,6 +339,7 @@ class Symbol : public SymbolContextScope { m_is_weak : 1, m_type : 6;// Values from the lldb::SymbolType enum. mutable Mangled m_mangled; // uniqued symbol name/mangled name pair + AddressRange m_addr_range; // Contains the value, or the section offset // address when the value is an address in a // section, and the size (if any) diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 6d10cc8bcffcb..26e83cefbe571 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -1391,6 +1391,12 @@ enum StopDisassemblyType { eStopDisassemblyTypeAlways }; +/// Format to use for unknown symbols. +enum SyntheticSymbolsNameStyle { + eSyntheticSymbolsNameStyleIndex = 0, + eSyntheticSymbolsNameStyleFileAddress = 1, +}; + } // namespace lldb #endif // LLDB_LLDB_ENUMERATIONS_H diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index a1a4e994c3b9c..7eaecb729c36d 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -46,6 +46,11 @@ let Definition = "modulelist" in { Global, DefaultFalse, Desc<"Enable on demand symbol loading in LLDB. LLDB will load debug info on demand for each module based on various conditions (e.g. matched breakpoint, resolved stack frame addresses and matched global variables/function symbols in symbol table) to improve performance. Please refer to docs/use/ondemand.rst for details.">; + def SyntheticSymbolsNameStyle: Property<"synthetic-symbols-name-style", "Enum">, +Global, +DefaultEnumValue<"eSyntheticSymbolsNameStyleIndex">, +EnumValues<"OptionEnumValues(g_synthetic_symbols_name_style_values)">, +Desc<"Determines the way synthetic symbol names are generated for unknown symbols">; } let Definition = "debugger" in { diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 6052cc151744d..a507d1c2efaf5 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -115,6 +115,13 @@ SymbolDownload ModuleListProperties::GetSymbolAutoDownload() const { g_modulelist_properties[idx].default_uint_value)); } +lldb::SyntheticSymbolsNameStyle ModuleListProperties::GetSyntheticSymbolsNameStyle() const { + const uint32_t idx = ePropertySyntheticSymbolsNameStyle; + return GetPropertyAtIndexAs( + idx, static_cast( + g_modulelist_properties[idx].default_uint_value)); +} + FileSpec ModuleListProperties::GetClangModulesCachePath() const { const uint32_t idx = ePropertyClangModulesCachePath; return GetPropertyAtIndexAs(idx, {}); di
[Lldb-commits] [lldb] [lldb] add settings to control how synthetic symbol names are generated (PR #137512)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137512 >From 10d4c2497a55ccac91c27009ceafc2042476e7ab Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 27 Apr 2025 13:48:45 +0200 Subject: [PATCH] [lldb] add settings to control how synthetic symbol names are generated --- lldb/include/lldb/Core/ModuleList.h | 15 +++ lldb/include/lldb/lldb-enumerations.h | 6 ++ lldb/source/Core/CoreProperties.td| 7 +++ lldb/source/Core/ModuleList.cpp | 8 lldb/source/Symbol/Symbol.cpp | 13 - 5 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index 909ee08f9ba62..baed175be5313 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -67,6 +67,20 @@ static constexpr OptionEnumValueElement g_auto_download_enum_values[] = { }, }; +static constexpr OptionEnumValueElement +g_synthetic_symbols_name_style_values[] = { +{ +lldb::eSyntheticSymbolsNameStyleIndex, +"index", +"Function index style", +}, +{ +lldb::eSyntheticSymbolsNameStyleFileAddress, +"file-address", +"Function file address in module style", +}, +}; + class ModuleListProperties : public Properties { mutable llvm::sys::RWMutex m_symlink_paths_mutex; PathMappingList m_symlink_paths; @@ -91,6 +105,7 @@ class ModuleListProperties : public Properties { bool GetLoadSymbolOnDemand(); lldb::SymbolDownload GetSymbolAutoDownload() const; + lldb::SyntheticSymbolsNameStyle GetSyntheticSymbolsNameStyle() const; PathMappingList GetSymlinkMappings() const; }; diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 6d10cc8bcffcb..26e83cefbe571 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -1391,6 +1391,12 @@ enum StopDisassemblyType { eStopDisassemblyTypeAlways }; +/// Format to use for unknown symbols. +enum SyntheticSymbolsNameStyle { + eSyntheticSymbolsNameStyleIndex = 0, + eSyntheticSymbolsNameStyleFileAddress = 1, +}; + } // namespace lldb #endif // LLDB_LLDB_ENUMERATIONS_H diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index a1a4e994c3b9c..84326abc650b6 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -46,6 +46,13 @@ let Definition = "modulelist" in { Global, DefaultFalse, Desc<"Enable on demand symbol loading in LLDB. LLDB will load debug info on demand for each module based on various conditions (e.g. matched breakpoint, resolved stack frame addresses and matched global variables/function symbols in symbol table) to improve performance. Please refer to docs/use/ondemand.rst for details.">; + def SyntheticSymbolsNameStyle + : Property<"synthetic-symbols-name-style", "Enum">, +Global, +DefaultEnumValue<"eSyntheticSymbolsNameStyleIndex">, +EnumValues<"OptionEnumValues(g_synthetic_symbols_name_style_values)">, +Desc<"Determines the way synthetic symbol names are generated for " + "unknown symbols">; } let Definition = "debugger" in { diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 6052cc151744d..c48c5bbfb5e92 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -115,6 +115,14 @@ SymbolDownload ModuleListProperties::GetSymbolAutoDownload() const { g_modulelist_properties[idx].default_uint_value)); } +lldb::SyntheticSymbolsNameStyle +ModuleListProperties::GetSyntheticSymbolsNameStyle() const { + const uint32_t idx = ePropertySyntheticSymbolsNameStyle; + return GetPropertyAtIndexAs( + idx, static_cast( + g_modulelist_properties[idx].default_uint_value)); +} + FileSpec ModuleListProperties::GetClangModulesCachePath() const { const uint32_t idx = ePropertyClangModulesCachePath; return GetPropertyAtIndexAs(idx, {}); diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 4828de4fdfa37..825ca5babe28e 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -639,7 +639,18 @@ void Symbol::SynthesizeNameIfNeeded() const { // breakpoints on them. llvm::SmallString<256> name; llvm::raw_svector_ostream os(name); -os << GetSyntheticSymbolPrefix() << GetID(); +os << GetSyntheticSymbolPrefix(); +switch (ModuleList::GetGlobalModuleListProperties() +.GetSyntheticSymbolsNameStyle()) { +case eSyntheticSymbolsNameStyleIndex: + os << GetID(); + break; +case eSyntheticSymbolsNameStyleFileAddress: + os << "_" + << llvm::format_hex_no_prefix( +m_addr_range.GetBaseAddress().GetFileAddress(), 0); + break; +} m_mangled.SetD
[Lldb-commits] [lldb] [llvm] [lldb-dap] Migrating breakpointLocations request to use typed RequestHandler (PR #137426)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/137426 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] add settings to control how synthetic symbol names are generated (PR #137512)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/137512 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] migrate set breakpoint requests (PR #137448)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137448 >From dc8388b0027c75dba465c72009ac0c25750ae877 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sat, 26 Apr 2025 10:25:21 +0200 Subject: [PATCH] adding breakpoints protocol types add all breakpoint requests JSON types decouple JSON from DAP Breakpoint classes forgor exception breakpoint response migrating breakpoint requests migrate breakpoints requests handler implementations remove CreateBreakpoint data breakpoint requests serialization fix GetFrame fix data breakpoint return exception breakpoints list restore exception breakpoints --- lldb/tools/lldb-dap/Breakpoint.cpp| 22 +- lldb/tools/lldb-dap/Breakpoint.h | 6 +- lldb/tools/lldb-dap/BreakpointBase.cpp| 12 +- lldb/tools/lldb-dap/BreakpointBase.h | 8 +- lldb/tools/lldb-dap/DAP.cpp | 11 +- lldb/tools/lldb-dap/DAP.h | 1 + lldb/tools/lldb-dap/FunctionBreakpoint.cpp| 8 +- lldb/tools/lldb-dap/FunctionBreakpoint.h | 3 +- .../DataBreakpointInfoRequestHandler.cpp | 175 -- .../Handler/InitializeRequestHandler.cpp | 2 +- lldb/tools/lldb-dap/Handler/RequestHandler.h | 51 ++-- .../Handler/SetBreakpointsRequestHandler.cpp | 180 +++--- .../SetDataBreakpointsRequestHandler.cpp | 98 ++-- .../SetFunctionBreakpointsRequestHandler.cpp | 115 ++--- ...etInstructionBreakpointsRequestHandler.cpp | 223 ++ ...TestGetTargetBreakpointsRequestHandler.cpp | 2 +- lldb/tools/lldb-dap/InstructionBreakpoint.cpp | 15 +- lldb/tools/lldb-dap/InstructionBreakpoint.h | 4 +- lldb/tools/lldb-dap/JSONUtils.cpp | 161 + lldb/tools/lldb-dap/JSONUtils.h | 67 +- .../lldb-dap/Protocol/ProtocolRequests.cpp| 70 ++ .../lldb-dap/Protocol/ProtocolRequests.h | 147 .../tools/lldb-dap/Protocol/ProtocolTypes.cpp | 127 ++ lldb/tools/lldb-dap/Protocol/ProtocolTypes.h | 181 ++ lldb/tools/lldb-dap/SourceBreakpoint.cpp | 13 +- lldb/tools/lldb-dap/SourceBreakpoint.h| 3 +- lldb/tools/lldb-dap/Watchpoint.cpp| 26 +- lldb/tools/lldb-dap/Watchpoint.h | 6 +- llvm/include/llvm/Support/JSON.h | 8 + 29 files changed, 790 insertions(+), 955 deletions(-) diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp b/lldb/tools/lldb-dap/Breakpoint.cpp index 5679fd545d53f..26d633d1d172e 100644 --- a/lldb/tools/lldb-dap/Breakpoint.cpp +++ b/lldb/tools/lldb-dap/Breakpoint.cpp @@ -14,7 +14,6 @@ #include "lldb/API/SBLineEntry.h" #include "lldb/API/SBMutex.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/Support/JSON.h" #include #include #include @@ -30,13 +29,16 @@ void Breakpoint::SetHitCondition() { m_bp.SetIgnoreCount(hitCount - 1); } -void Breakpoint::CreateJsonObject(llvm::json::Object &object) { +protocol::Breakpoint Breakpoint::ToProtocolBreakpoint() { + protocol::Breakpoint breakpoint; + // Each breakpoint location is treated as a separate breakpoint for VS code. // They don't have the notion of a single breakpoint with multiple locations. if (!m_bp.IsValid()) -return; - object.try_emplace("verified", m_bp.GetNumResolvedLocations() > 0); - object.try_emplace("id", m_bp.GetID()); +return breakpoint; + + breakpoint.verified = m_bp.GetNumResolvedLocations() > 0; + breakpoint.id = m_bp.GetID(); // VS Code DAP doesn't currently allow one breakpoint to have multiple // locations so we just report the first one. If we report all locations // then the IDE starts showing the wrong line numbers and locations for @@ -60,16 +62,18 @@ void Breakpoint::CreateJsonObject(llvm::json::Object &object) { if (bp_addr.IsValid()) { std::string formatted_addr = "0x" + llvm::utohexstr(bp_addr.GetLoadAddress(m_bp.GetTarget())); -object.try_emplace("instructionReference", formatted_addr); +breakpoint.instructionReference = formatted_addr; auto line_entry = bp_addr.GetLineEntry(); const auto line = line_entry.GetLine(); if (line != UINT32_MAX) - object.try_emplace("line", line); + breakpoint.line = line; const auto column = line_entry.GetColumn(); if (column != 0) - object.try_emplace("column", column); -object.try_emplace("source", CreateSource(line_entry)); + breakpoint.column = column; +breakpoint.source = CreateSource(line_entry); } + + return breakpoint; } bool Breakpoint::MatchesName(const char *name) { diff --git a/lldb/tools/lldb-dap/Breakpoint.h b/lldb/tools/lldb-dap/Breakpoint.h index 580017125af44..c4f1fa291f181 100644 --- a/lldb/tools/lldb-dap/Breakpoint.h +++ b/lldb/tools/lldb-dap/Breakpoint.h @@ -17,14 +17,16 @@ namespace lldb_dap { class Breakpoint : public BreakpointBase { public: - Breakpoint(DAP &d, const llvm::json::Object &obj) : BreakpointBase(d, obj)
[Lldb-commits] [lldb] [llvm] [lldb-dap] migrate set breakpoint requests (PR #137448)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137448 >From d0d8c7e24fd7ee37f4a3678537df1e28c8318d04 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sat, 26 Apr 2025 10:25:21 +0200 Subject: [PATCH 1/4] adding breakpoints protocol types --- lldb/tools/lldb-dap/Protocol/ProtocolTypes.h | 178 +++ llvm/include/llvm/Support/JSON.h | 8 + 2 files changed, 186 insertions(+) diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h index 54941f24efbd9..8b193287acc19 100644 --- a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h +++ b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h @@ -322,6 +322,184 @@ enum SteppingGranularity : unsigned { bool fromJSON(const llvm::json::Value &, SteppingGranularity &, llvm::json::Path); +/// Information about a breakpoint created in `setBreakpoints`, `setFunctionBreakpoints`, `setInstructionBreakpoints`, or `setDataBreakpoints` requests. +struct Breakpoint { + /// A machine-readable explanation of why a breakpoint may not be verified. + enum class Reason : unsigned { +/// Indicates a breakpoint might be verified in the future, but +/// the adapter cannot verify it in the current state. +eBreakpointReasonPending, +/// Indicates a breakpoint was not able to be verified, and the +/// adapter does not believe it can be verified without intervention. +eBreakpointReasonFailed, + }; + + /// The identifier for the breakpoint. It is needed if breakpoint events are + /// used to update or remove breakpoints. + std::optional id; + + /// If true, the breakpoint could be set (but not necessarily at the desired + /// location). + bool verified; + + /// A message about the state of the breakpoint. + /// This is shown to the user and can be used to explain why a breakpoint could + /// not be verified. + std::optional message; + + /// The source where the breakpoint is located. + std::optional source; + + /// The start line of the actual range covered by the breakpoint. + std::optional line; + + /// Start position of the source range covered by the breakpoint. It is + /// measured in UTF-16 code units and the client capability `columnsStartAt1` + /// determines whether it is 0- or 1-based. + std::optional column; + + /// The end line of the actual range covered by the breakpoint. + std::optional endLine; + + /// End position of the source range covered by the breakpoint. It is measured + /// in UTF-16 code units and the client capability `columnsStartAt1` determines + /// whether it is 0- or 1-based. + /// If no end line is given, then the end column is assumed to be in the start + /// line. + std::optional endColumn; + + /// A memory reference to where the breakpoint is set. + std::optional instructionReference; + + /// The offset from the instruction reference. + /// This can be negative. + std::optional offset; + + /// A machine-readable explanation of why a breakpoint may not be verified. If + /// a breakpoint is verified or a specific reason is not known, the adapter + /// should omit this property. + std::optional reason; +}; +llvm::json::Value toJSON(const Breakpoint &); + +/// Properties of a breakpoint or logpoint passed to the `setBreakpoints` request +struct SourceBreakpoint { + /// The source line of the breakpoint or logpoint. + uint32_t line; + + /// Start position within source line of the breakpoint or logpoint. It is + /// measured in UTF-16 code units and the client capability `columnsStartAt1` + /// determines whether it is 0- or 1-based. + std::optional column; + + /// The expression for conditional breakpoints. + /// It is only honored by a debug adapter if the corresponding capability + /// `supportsConditionalBreakpoints` is true. + std::optional condition; + + /// The expression that controls how many hits of the breakpoint are ignored. + /// The debug adapter is expected to interpret the expression as needed. + /// The attribute is only honored by a debug adapter if the corresponding + /// capability `supportsHitConditionalBreakpoints` is true. + /// If both this property and `condition` are specified, `hitCondition` should + /// be evaluated only if the `condition` is met, and the debug adapter should + /// stop only if both conditions are met. + std::optional hitCondition; + + /// If this attribute exists and is non-empty, the debug adapter must not + /// 'break' (stop) + /// but log the message instead. Expressions within `{}` are interpolated. + /// The attribute is only honored by a debug adapter if the corresponding + /// capability `supportsLogPoints` is true. + /// If either `hitCondition` or `condition` is specified, then the message + /// should only be logged if those conditions are met. + std::optional logMessage; + + /// The mode of this breakpoint. If defined, this must be one of the + /// `breakpointModes` the debug adapter advertised i
[Lldb-commits] [lldb] [llvm] [lldb-dap] migrate set breakpoint requests (PR #137448)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/137448 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Lldb dap migrate set breakpoint requests (PR #137448)
https://github.com/eronnen created https://github.com/llvm/llvm-project/pull/137448 None >From d0d8c7e24fd7ee37f4a3678537df1e28c8318d04 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sat, 26 Apr 2025 10:25:21 +0200 Subject: [PATCH 1/2] adding breakpoints protocol types --- lldb/tools/lldb-dap/Protocol/ProtocolTypes.h | 178 +++ llvm/include/llvm/Support/JSON.h | 8 + 2 files changed, 186 insertions(+) diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h index 54941f24efbd9..8b193287acc19 100644 --- a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h +++ b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h @@ -322,6 +322,184 @@ enum SteppingGranularity : unsigned { bool fromJSON(const llvm::json::Value &, SteppingGranularity &, llvm::json::Path); +/// Information about a breakpoint created in `setBreakpoints`, `setFunctionBreakpoints`, `setInstructionBreakpoints`, or `setDataBreakpoints` requests. +struct Breakpoint { + /// A machine-readable explanation of why a breakpoint may not be verified. + enum class Reason : unsigned { +/// Indicates a breakpoint might be verified in the future, but +/// the adapter cannot verify it in the current state. +eBreakpointReasonPending, +/// Indicates a breakpoint was not able to be verified, and the +/// adapter does not believe it can be verified without intervention. +eBreakpointReasonFailed, + }; + + /// The identifier for the breakpoint. It is needed if breakpoint events are + /// used to update or remove breakpoints. + std::optional id; + + /// If true, the breakpoint could be set (but not necessarily at the desired + /// location). + bool verified; + + /// A message about the state of the breakpoint. + /// This is shown to the user and can be used to explain why a breakpoint could + /// not be verified. + std::optional message; + + /// The source where the breakpoint is located. + std::optional source; + + /// The start line of the actual range covered by the breakpoint. + std::optional line; + + /// Start position of the source range covered by the breakpoint. It is + /// measured in UTF-16 code units and the client capability `columnsStartAt1` + /// determines whether it is 0- or 1-based. + std::optional column; + + /// The end line of the actual range covered by the breakpoint. + std::optional endLine; + + /// End position of the source range covered by the breakpoint. It is measured + /// in UTF-16 code units and the client capability `columnsStartAt1` determines + /// whether it is 0- or 1-based. + /// If no end line is given, then the end column is assumed to be in the start + /// line. + std::optional endColumn; + + /// A memory reference to where the breakpoint is set. + std::optional instructionReference; + + /// The offset from the instruction reference. + /// This can be negative. + std::optional offset; + + /// A machine-readable explanation of why a breakpoint may not be verified. If + /// a breakpoint is verified or a specific reason is not known, the adapter + /// should omit this property. + std::optional reason; +}; +llvm::json::Value toJSON(const Breakpoint &); + +/// Properties of a breakpoint or logpoint passed to the `setBreakpoints` request +struct SourceBreakpoint { + /// The source line of the breakpoint or logpoint. + uint32_t line; + + /// Start position within source line of the breakpoint or logpoint. It is + /// measured in UTF-16 code units and the client capability `columnsStartAt1` + /// determines whether it is 0- or 1-based. + std::optional column; + + /// The expression for conditional breakpoints. + /// It is only honored by a debug adapter if the corresponding capability + /// `supportsConditionalBreakpoints` is true. + std::optional condition; + + /// The expression that controls how many hits of the breakpoint are ignored. + /// The debug adapter is expected to interpret the expression as needed. + /// The attribute is only honored by a debug adapter if the corresponding + /// capability `supportsHitConditionalBreakpoints` is true. + /// If both this property and `condition` are specified, `hitCondition` should + /// be evaluated only if the `condition` is met, and the debug adapter should + /// stop only if both conditions are met. + std::optional hitCondition; + + /// If this attribute exists and is non-empty, the debug adapter must not + /// 'break' (stop) + /// but log the message instead. Expressions within `{}` are interpolated. + /// The attribute is only honored by a debug adapter if the corresponding + /// capability `supportsLogPoints` is true. + /// If either `hitCondition` or `condition` is specified, then the message + /// should only be logged if those conditions are met. + std::optional logMessage; + + /// The mode of this breakpoint. If defined, this must be one of the + /// `breakpointModes` the debug adapter advert
[Lldb-commits] [lldb] [llvm] [lldb-dap] migrate set breakpoint requests (PR #137448)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/137448 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] migrate set breakpoint requests (PR #137448)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/137448 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] Migrating breakpointLocations request to use typed RequestHandler (PR #137426)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137426 >From 85c1e0de0a5cb8dd09b6f84b2514c7eb06aadac2 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sat, 26 Apr 2025 01:22:05 +0200 Subject: [PATCH] Migrating breakpointLocations request to use typed RequestHandler --- .../Handler/BreakpointLocationsHandler.cpp| 156 ++ lldb/tools/lldb-dap/Handler/RequestHandler.h | 10 +- .../lldb-dap/Protocol/ProtocolRequests.cpp| 17 ++ .../lldb-dap/Protocol/ProtocolRequests.h | 38 + .../tools/lldb-dap/Protocol/ProtocolTypes.cpp | 14 ++ lldb/tools/lldb-dap/Protocol/ProtocolTypes.h | 21 +++ llvm/include/llvm/Support/JSON.h | 8 + 7 files changed, 122 insertions(+), 142 deletions(-) diff --git a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp index 7a477f3e97875..537f1e7b76f1d 100644 --- a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp @@ -9,136 +9,24 @@ #include "DAP.h" #include "JSONUtils.h" #include "RequestHandler.h" +#include namespace lldb_dap { -// "BreakpointLocationsRequest": { -// "allOf": [ { "$ref": "#/definitions/Request" }, { -// "type": "object", -// "description": "The `breakpointLocations` request returns all possible -// locations for source breakpoints in a given range.\nClients should only -// call this request if the corresponding capability -// `supportsBreakpointLocationsRequest` is true.", -// "properties": { -// "command": { -// "type": "string", -// "enum": [ "breakpointLocations" ] -// }, -// "arguments": { -// "$ref": "#/definitions/BreakpointLocationsArguments" -// } -// }, -// "required": [ "command" ] -// }] -// }, -// "BreakpointLocationsArguments": { -// "type": "object", -// "description": "Arguments for `breakpointLocations` request.", -// "properties": { -// "source": { -// "$ref": "#/definitions/Source", -// "description": "The source location of the breakpoints; either -// `source.path` or `source.sourceReference` must be specified." -// }, -// "line": { -// "type": "integer", -// "description": "Start line of range to search possible breakpoint -// locations in. If only the line is specified, the request returns all -// possible locations in that line." -// }, -// "column": { -// "type": "integer", -// "description": "Start position within `line` to search possible -// breakpoint locations in. It is measured in UTF-16 code units and the -// client capability `columnsStartAt1` determines whether it is 0- or -// 1-based. If no column is given, the first position in the start line is -// assumed." -// }, -// "endLine": { -// "type": "integer", -// "description": "End line of range to search possible breakpoint -// locations in. If no end line is given, then the end line is assumed to -// be the start line." -// }, -// "endColumn": { -// "type": "integer", -// "description": "End position within `endLine` to search possible -// breakpoint locations in. It is measured in UTF-16 code units and the -// client capability `columnsStartAt1` determines whether it is 0- or -// 1-based. If no end column is given, the last position in the end line -// is assumed." -// } -// }, -// "required": [ "source", "line" ] -// }, -// "BreakpointLocationsResponse": { -// "allOf": [ { "$ref": "#/definitions/Response" }, { -// "type": "object", -// "description": "Response to `breakpointLocations` request.\nContains -// possible locations for source breakpoints.", -// "properties": { -// "body": { -// "type": "object", -// "properties": { -// "breakpoints": { -// "type": "array", -// "items": { -// "$ref": "#/definitions/BreakpointLocation" -// }, -// "description": "Sorted set of possible breakpoint locations." -// } -// }, -// "required": [ "breakpoints" ] -// } -// }, -// "required": [ "body" ] -// }] -// }, -// "BreakpointLocation": { -// "type": "object", -// "description": "Properties of a breakpoint location returned from the -// `breakpointLocations` request.", -// "properties": { -// "line": { -// "type": "integer", -// "description": "Start line of breakpoint location." -// }, -// "column": { -// "type": "integer", -// "description": "The start position of a breakpoint location. Position -// is measured in UTF-16 code units and the client capability -// `columnsStartAt1` determines whether it is 0- or 1-based." -// }, -// "endLine": { -// "type": "integer", -//
[Lldb-commits] [lldb] [llvm] [lldb-dap] Migrating breakpointLocations request to use typed RequestHandler (PR #137426)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137426 >From 1cc60c125a69c4a84c263db6845714f1c320b696 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sat, 26 Apr 2025 01:22:05 +0200 Subject: [PATCH] Migrating breakpointLocations request to use typed RequestHandler --- .../Handler/BreakpointLocationsHandler.cpp| 156 +++--- lldb/tools/lldb-dap/Handler/RequestHandler.h | 10 +- .../lldb-dap/Protocol/ProtocolRequests.cpp| 17 ++ .../lldb-dap/Protocol/ProtocolRequests.h | 38 + .../tools/lldb-dap/Protocol/ProtocolTypes.cpp | 14 ++ lldb/tools/lldb-dap/Protocol/ProtocolTypes.h | 21 +++ llvm/include/llvm/Support/JSON.h | 8 + 7 files changed, 125 insertions(+), 139 deletions(-) diff --git a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp index 7a477f3e97875..2ac886c3a5d2c 100644 --- a/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/BreakpointLocationsHandler.cpp @@ -9,136 +9,22 @@ #include "DAP.h" #include "JSONUtils.h" #include "RequestHandler.h" +#include namespace lldb_dap { -// "BreakpointLocationsRequest": { -// "allOf": [ { "$ref": "#/definitions/Request" }, { -// "type": "object", -// "description": "The `breakpointLocations` request returns all possible -// locations for source breakpoints in a given range.\nClients should only -// call this request if the corresponding capability -// `supportsBreakpointLocationsRequest` is true.", -// "properties": { -// "command": { -// "type": "string", -// "enum": [ "breakpointLocations" ] -// }, -// "arguments": { -// "$ref": "#/definitions/BreakpointLocationsArguments" -// } -// }, -// "required": [ "command" ] -// }] -// }, -// "BreakpointLocationsArguments": { -// "type": "object", -// "description": "Arguments for `breakpointLocations` request.", -// "properties": { -// "source": { -// "$ref": "#/definitions/Source", -// "description": "The source location of the breakpoints; either -// `source.path` or `source.sourceReference` must be specified." -// }, -// "line": { -// "type": "integer", -// "description": "Start line of range to search possible breakpoint -// locations in. If only the line is specified, the request returns all -// possible locations in that line." -// }, -// "column": { -// "type": "integer", -// "description": "Start position within `line` to search possible -// breakpoint locations in. It is measured in UTF-16 code units and the -// client capability `columnsStartAt1` determines whether it is 0- or -// 1-based. If no column is given, the first position in the start line is -// assumed." -// }, -// "endLine": { -// "type": "integer", -// "description": "End line of range to search possible breakpoint -// locations in. If no end line is given, then the end line is assumed to -// be the start line." -// }, -// "endColumn": { -// "type": "integer", -// "description": "End position within `endLine` to search possible -// breakpoint locations in. It is measured in UTF-16 code units and the -// client capability `columnsStartAt1` determines whether it is 0- or -// 1-based. If no end column is given, the last position in the end line -// is assumed." -// } -// }, -// "required": [ "source", "line" ] -// }, -// "BreakpointLocationsResponse": { -// "allOf": [ { "$ref": "#/definitions/Response" }, { -// "type": "object", -// "description": "Response to `breakpointLocations` request.\nContains -// possible locations for source breakpoints.", -// "properties": { -// "body": { -// "type": "object", -// "properties": { -// "breakpoints": { -// "type": "array", -// "items": { -// "$ref": "#/definitions/BreakpointLocation" -// }, -// "description": "Sorted set of possible breakpoint locations." -// } -// }, -// "required": [ "breakpoints" ] -// } -// }, -// "required": [ "body" ] -// }] -// }, -// "BreakpointLocation": { -// "type": "object", -// "description": "Properties of a breakpoint location returned from the -// `breakpointLocations` request.", -// "properties": { -// "line": { -// "type": "integer", -// "description": "Start line of breakpoint location." -// }, -// "column": { -// "type": "integer", -// "description": "The start position of a breakpoint location. Position -// is measured in UTF-16 code units and the client capability -// `columnsStartAt1` determines whether it is 0- or 1-based." -// }, -// "endLine": { -// "type": "integer", -//
[Lldb-commits] [lldb] [llvm] [lldb-dap] migrate set breakpoint requests (PR #137448)
https://github.com/eronnen ready_for_review https://github.com/llvm/llvm-project/pull/137448 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] migrate set breakpoint requests (PR #137448)
eronnen wrote: CC @ashgti https://github.com/llvm/llvm-project/pull/137448 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb-dap] migrate set breakpoint requests (PR #137448)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/137448 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] add settings to control how synthetic symbol names are generated (PR #137512)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137512 >From fd74de70151567d402eb7c0326a6234a21cb2db7 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 27 Apr 2025 13:48:45 +0200 Subject: [PATCH 1/3] [lldb] add settings to control how synthetic symbol names are generated --- lldb/include/lldb/Core/ModuleList.h | 15 +++ lldb/include/lldb/lldb-enumerations.h | 6 ++ lldb/source/Core/CoreProperties.td| 5 + lldb/source/Core/ModuleList.cpp | 8 lldb/source/Symbol/Symbol.cpp | 13 - 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index 909ee08f9ba62..baed175be5313 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -67,6 +67,20 @@ static constexpr OptionEnumValueElement g_auto_download_enum_values[] = { }, }; +static constexpr OptionEnumValueElement +g_synthetic_symbols_name_style_values[] = { +{ +lldb::eSyntheticSymbolsNameStyleIndex, +"index", +"Function index style", +}, +{ +lldb::eSyntheticSymbolsNameStyleFileAddress, +"file-address", +"Function file address in module style", +}, +}; + class ModuleListProperties : public Properties { mutable llvm::sys::RWMutex m_symlink_paths_mutex; PathMappingList m_symlink_paths; @@ -91,6 +105,7 @@ class ModuleListProperties : public Properties { bool GetLoadSymbolOnDemand(); lldb::SymbolDownload GetSymbolAutoDownload() const; + lldb::SyntheticSymbolsNameStyle GetSyntheticSymbolsNameStyle() const; PathMappingList GetSymlinkMappings() const; }; diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 6d10cc8bcffcb..26e83cefbe571 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -1391,6 +1391,12 @@ enum StopDisassemblyType { eStopDisassemblyTypeAlways }; +/// Format to use for unknown symbols. +enum SyntheticSymbolsNameStyle { + eSyntheticSymbolsNameStyleIndex = 0, + eSyntheticSymbolsNameStyleFileAddress = 1, +}; + } // namespace lldb #endif // LLDB_LLDB_ENUMERATIONS_H diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index a1a4e994c3b9c..7eaecb729c36d 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -46,6 +46,11 @@ let Definition = "modulelist" in { Global, DefaultFalse, Desc<"Enable on demand symbol loading in LLDB. LLDB will load debug info on demand for each module based on various conditions (e.g. matched breakpoint, resolved stack frame addresses and matched global variables/function symbols in symbol table) to improve performance. Please refer to docs/use/ondemand.rst for details.">; + def SyntheticSymbolsNameStyle: Property<"synthetic-symbols-name-style", "Enum">, +Global, +DefaultEnumValue<"eSyntheticSymbolsNameStyleIndex">, +EnumValues<"OptionEnumValues(g_synthetic_symbols_name_style_values)">, +Desc<"Determines the way synthetic symbol names are generated for unknown symbols">; } let Definition = "debugger" in { diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 6052cc151744d..c48c5bbfb5e92 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -115,6 +115,14 @@ SymbolDownload ModuleListProperties::GetSymbolAutoDownload() const { g_modulelist_properties[idx].default_uint_value)); } +lldb::SyntheticSymbolsNameStyle +ModuleListProperties::GetSyntheticSymbolsNameStyle() const { + const uint32_t idx = ePropertySyntheticSymbolsNameStyle; + return GetPropertyAtIndexAs( + idx, static_cast( + g_modulelist_properties[idx].default_uint_value)); +} + FileSpec ModuleListProperties::GetClangModulesCachePath() const { const uint32_t idx = ePropertyClangModulesCachePath; return GetPropertyAtIndexAs(idx, {}); diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 4828de4fdfa37..825ca5babe28e 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -639,7 +639,18 @@ void Symbol::SynthesizeNameIfNeeded() const { // breakpoints on them. llvm::SmallString<256> name; llvm::raw_svector_ostream os(name); -os << GetSyntheticSymbolPrefix() << GetID(); +os << GetSyntheticSymbolPrefix(); +switch (ModuleList::GetGlobalModuleListProperties() +.GetSyntheticSymbolsNameStyle()) { +case eSyntheticSymbolsNameStyleIndex: + os << GetID(); + break; +case eSyntheticSymbolsNameStyleFileAddress: + os << "_" + << llvm::format_hex_no_prefix( +m_addr_range.GetBaseAddress().GetFileAddress(), 0); + break; +} m_mangled.SetDemangledName(ConstString(os.str()));
[Lldb-commits] [lldb] [lldb] Change synthetic symbol names to have file address (PR #137512)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/137512 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] add settings to control how synthetic symbol names are generated (PR #137512)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/137512 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Change synthetic symbol names to have file address (PR #137512)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137512 >From fd74de70151567d402eb7c0326a6234a21cb2db7 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 27 Apr 2025 13:48:45 +0200 Subject: [PATCH 1/6] [lldb] add settings to control how synthetic symbol names are generated --- lldb/include/lldb/Core/ModuleList.h | 15 +++ lldb/include/lldb/lldb-enumerations.h | 6 ++ lldb/source/Core/CoreProperties.td| 5 + lldb/source/Core/ModuleList.cpp | 8 lldb/source/Symbol/Symbol.cpp | 13 - 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index 909ee08f9ba62..baed175be5313 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -67,6 +67,20 @@ static constexpr OptionEnumValueElement g_auto_download_enum_values[] = { }, }; +static constexpr OptionEnumValueElement +g_synthetic_symbols_name_style_values[] = { +{ +lldb::eSyntheticSymbolsNameStyleIndex, +"index", +"Function index style", +}, +{ +lldb::eSyntheticSymbolsNameStyleFileAddress, +"file-address", +"Function file address in module style", +}, +}; + class ModuleListProperties : public Properties { mutable llvm::sys::RWMutex m_symlink_paths_mutex; PathMappingList m_symlink_paths; @@ -91,6 +105,7 @@ class ModuleListProperties : public Properties { bool GetLoadSymbolOnDemand(); lldb::SymbolDownload GetSymbolAutoDownload() const; + lldb::SyntheticSymbolsNameStyle GetSyntheticSymbolsNameStyle() const; PathMappingList GetSymlinkMappings() const; }; diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 6d10cc8bcffcb..26e83cefbe571 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -1391,6 +1391,12 @@ enum StopDisassemblyType { eStopDisassemblyTypeAlways }; +/// Format to use for unknown symbols. +enum SyntheticSymbolsNameStyle { + eSyntheticSymbolsNameStyleIndex = 0, + eSyntheticSymbolsNameStyleFileAddress = 1, +}; + } // namespace lldb #endif // LLDB_LLDB_ENUMERATIONS_H diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index a1a4e994c3b9c..7eaecb729c36d 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -46,6 +46,11 @@ let Definition = "modulelist" in { Global, DefaultFalse, Desc<"Enable on demand symbol loading in LLDB. LLDB will load debug info on demand for each module based on various conditions (e.g. matched breakpoint, resolved stack frame addresses and matched global variables/function symbols in symbol table) to improve performance. Please refer to docs/use/ondemand.rst for details.">; + def SyntheticSymbolsNameStyle: Property<"synthetic-symbols-name-style", "Enum">, +Global, +DefaultEnumValue<"eSyntheticSymbolsNameStyleIndex">, +EnumValues<"OptionEnumValues(g_synthetic_symbols_name_style_values)">, +Desc<"Determines the way synthetic symbol names are generated for unknown symbols">; } let Definition = "debugger" in { diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 6052cc151744d..c48c5bbfb5e92 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -115,6 +115,14 @@ SymbolDownload ModuleListProperties::GetSymbolAutoDownload() const { g_modulelist_properties[idx].default_uint_value)); } +lldb::SyntheticSymbolsNameStyle +ModuleListProperties::GetSyntheticSymbolsNameStyle() const { + const uint32_t idx = ePropertySyntheticSymbolsNameStyle; + return GetPropertyAtIndexAs( + idx, static_cast( + g_modulelist_properties[idx].default_uint_value)); +} + FileSpec ModuleListProperties::GetClangModulesCachePath() const { const uint32_t idx = ePropertyClangModulesCachePath; return GetPropertyAtIndexAs(idx, {}); diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 4828de4fdfa37..825ca5babe28e 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -639,7 +639,18 @@ void Symbol::SynthesizeNameIfNeeded() const { // breakpoints on them. llvm::SmallString<256> name; llvm::raw_svector_ostream os(name); -os << GetSyntheticSymbolPrefix() << GetID(); +os << GetSyntheticSymbolPrefix(); +switch (ModuleList::GetGlobalModuleListProperties() +.GetSyntheticSymbolsNameStyle()) { +case eSyntheticSymbolsNameStyleIndex: + os << GetID(); + break; +case eSyntheticSymbolsNameStyleFileAddress: + os << "_" + << llvm::format_hex_no_prefix( +m_addr_range.GetBaseAddress().GetFileAddress(), 0); + break; +} m_mangled.SetDemangledName(ConstString(os.str()));
[Lldb-commits] [lldb] [lldb] add settings to control how synthetic symbol names are generated (PR #137512)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137512 >From fd74de70151567d402eb7c0326a6234a21cb2db7 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 27 Apr 2025 13:48:45 +0200 Subject: [PATCH 1/2] [lldb] add settings to control how synthetic symbol names are generated --- lldb/include/lldb/Core/ModuleList.h | 15 +++ lldb/include/lldb/lldb-enumerations.h | 6 ++ lldb/source/Core/CoreProperties.td| 5 + lldb/source/Core/ModuleList.cpp | 8 lldb/source/Symbol/Symbol.cpp | 13 - 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index 909ee08f9ba62..baed175be5313 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -67,6 +67,20 @@ static constexpr OptionEnumValueElement g_auto_download_enum_values[] = { }, }; +static constexpr OptionEnumValueElement +g_synthetic_symbols_name_style_values[] = { +{ +lldb::eSyntheticSymbolsNameStyleIndex, +"index", +"Function index style", +}, +{ +lldb::eSyntheticSymbolsNameStyleFileAddress, +"file-address", +"Function file address in module style", +}, +}; + class ModuleListProperties : public Properties { mutable llvm::sys::RWMutex m_symlink_paths_mutex; PathMappingList m_symlink_paths; @@ -91,6 +105,7 @@ class ModuleListProperties : public Properties { bool GetLoadSymbolOnDemand(); lldb::SymbolDownload GetSymbolAutoDownload() const; + lldb::SyntheticSymbolsNameStyle GetSyntheticSymbolsNameStyle() const; PathMappingList GetSymlinkMappings() const; }; diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 6d10cc8bcffcb..26e83cefbe571 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -1391,6 +1391,12 @@ enum StopDisassemblyType { eStopDisassemblyTypeAlways }; +/// Format to use for unknown symbols. +enum SyntheticSymbolsNameStyle { + eSyntheticSymbolsNameStyleIndex = 0, + eSyntheticSymbolsNameStyleFileAddress = 1, +}; + } // namespace lldb #endif // LLDB_LLDB_ENUMERATIONS_H diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index a1a4e994c3b9c..7eaecb729c36d 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -46,6 +46,11 @@ let Definition = "modulelist" in { Global, DefaultFalse, Desc<"Enable on demand symbol loading in LLDB. LLDB will load debug info on demand for each module based on various conditions (e.g. matched breakpoint, resolved stack frame addresses and matched global variables/function symbols in symbol table) to improve performance. Please refer to docs/use/ondemand.rst for details.">; + def SyntheticSymbolsNameStyle: Property<"synthetic-symbols-name-style", "Enum">, +Global, +DefaultEnumValue<"eSyntheticSymbolsNameStyleIndex">, +EnumValues<"OptionEnumValues(g_synthetic_symbols_name_style_values)">, +Desc<"Determines the way synthetic symbol names are generated for unknown symbols">; } let Definition = "debugger" in { diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 6052cc151744d..c48c5bbfb5e92 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -115,6 +115,14 @@ SymbolDownload ModuleListProperties::GetSymbolAutoDownload() const { g_modulelist_properties[idx].default_uint_value)); } +lldb::SyntheticSymbolsNameStyle +ModuleListProperties::GetSyntheticSymbolsNameStyle() const { + const uint32_t idx = ePropertySyntheticSymbolsNameStyle; + return GetPropertyAtIndexAs( + idx, static_cast( + g_modulelist_properties[idx].default_uint_value)); +} + FileSpec ModuleListProperties::GetClangModulesCachePath() const { const uint32_t idx = ePropertyClangModulesCachePath; return GetPropertyAtIndexAs(idx, {}); diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 4828de4fdfa37..825ca5babe28e 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -639,7 +639,18 @@ void Symbol::SynthesizeNameIfNeeded() const { // breakpoints on them. llvm::SmallString<256> name; llvm::raw_svector_ostream os(name); -os << GetSyntheticSymbolPrefix() << GetID(); +os << GetSyntheticSymbolPrefix(); +switch (ModuleList::GetGlobalModuleListProperties() +.GetSyntheticSymbolsNameStyle()) { +case eSyntheticSymbolsNameStyleIndex: + os << GetID(); + break; +case eSyntheticSymbolsNameStyleFileAddress: + os << "_" + << llvm::format_hex_no_prefix( +m_addr_range.GetBaseAddress().GetFileAddress(), 0); + break; +} m_mangled.SetDemangledName(ConstString(os.str()));
[Lldb-commits] [lldb] [lldb] Expose QueueThreadPlanForStepSingleInstruction function to SBThreadPlan (PR #137904)
https://github.com/eronnen deleted https://github.com/llvm/llvm-project/pull/137904 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Expose QueueThreadPlanForStepSingleInstruction function to SBThreadPlan (PR #137904)
@@ -44,6 +44,34 @@ def step_out_with_scripted_plan(self, name): stop_desc = thread.GetStopDescription(1000) self.assertIn("Stepping out from", stop_desc, "Got right description") +def test_step_single_instruction(self): +self.build() +(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( +self, "Break on foo call", self.main_source_file +) + +err = thread.StepUsingScriptedThreadPlan("Steps.StepSingleInstruction") +self.assertSuccess(err) + +# Verify that stepping a single instruction after "foo();" steps into `foo` +frame = thread.GetFrameAtIndex(0) +self.assertEqual("foo", frame.GetFunctionName()) eronnen wrote: I think that testing a branch is more powerful though, because in a case of a non branch instruction both `stepi` and `nexti` would step into the same instruction https://github.com/llvm/llvm-project/pull/137904 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Expose QueueThreadPlanForStepSingleInstruction function to SBThreadPlan (PR #137904)
@@ -44,6 +44,34 @@ def step_out_with_scripted_plan(self, name): stop_desc = thread.GetStopDescription(1000) self.assertIn("Stepping out from", stop_desc, "Got right description") +def test_step_single_instruction(self): +self.build() +(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( +self, "Break on foo call", self.main_source_file +) + +err = thread.StepUsingScriptedThreadPlan("Steps.StepSingleInstruction") +self.assertSuccess(err) + +# Verify that stepping a single instruction after "foo();" steps into `foo` +frame = thread.GetFrameAtIndex(0) +self.assertEqual("foo", frame.GetFunctionName()) + +def test_step_single_instruction_with_step_over(self): +self.build() +(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( +self, "Break on foo call", self.main_source_file +) + +err = thread.StepUsingScriptedThreadPlan( +"Steps.StepSingleInstructionWithStepOver" +) +self.assertSuccess(err) + +# Verify that stepping over an instruction doesn't step into `foo` +frame = thread.GetFrameAtIndex(0) +self.assertEqual("main", frame.GetFunctionName()) eronnen wrote: makes sense, I didn't have any other straightfoward idea for a 100% way to break on a branch instruction but adding a check is a good idea https://github.com/llvm/llvm-project/pull/137904 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Change synthetic symbol names to have file address (PR #137512)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137512 >From fd74de70151567d402eb7c0326a6234a21cb2db7 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 27 Apr 2025 13:48:45 +0200 Subject: [PATCH 1/4] [lldb] add settings to control how synthetic symbol names are generated --- lldb/include/lldb/Core/ModuleList.h | 15 +++ lldb/include/lldb/lldb-enumerations.h | 6 ++ lldb/source/Core/CoreProperties.td| 5 + lldb/source/Core/ModuleList.cpp | 8 lldb/source/Symbol/Symbol.cpp | 13 - 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index 909ee08f9ba62..baed175be5313 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -67,6 +67,20 @@ static constexpr OptionEnumValueElement g_auto_download_enum_values[] = { }, }; +static constexpr OptionEnumValueElement +g_synthetic_symbols_name_style_values[] = { +{ +lldb::eSyntheticSymbolsNameStyleIndex, +"index", +"Function index style", +}, +{ +lldb::eSyntheticSymbolsNameStyleFileAddress, +"file-address", +"Function file address in module style", +}, +}; + class ModuleListProperties : public Properties { mutable llvm::sys::RWMutex m_symlink_paths_mutex; PathMappingList m_symlink_paths; @@ -91,6 +105,7 @@ class ModuleListProperties : public Properties { bool GetLoadSymbolOnDemand(); lldb::SymbolDownload GetSymbolAutoDownload() const; + lldb::SyntheticSymbolsNameStyle GetSyntheticSymbolsNameStyle() const; PathMappingList GetSymlinkMappings() const; }; diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 6d10cc8bcffcb..26e83cefbe571 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -1391,6 +1391,12 @@ enum StopDisassemblyType { eStopDisassemblyTypeAlways }; +/// Format to use for unknown symbols. +enum SyntheticSymbolsNameStyle { + eSyntheticSymbolsNameStyleIndex = 0, + eSyntheticSymbolsNameStyleFileAddress = 1, +}; + } // namespace lldb #endif // LLDB_LLDB_ENUMERATIONS_H diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index a1a4e994c3b9c..7eaecb729c36d 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -46,6 +46,11 @@ let Definition = "modulelist" in { Global, DefaultFalse, Desc<"Enable on demand symbol loading in LLDB. LLDB will load debug info on demand for each module based on various conditions (e.g. matched breakpoint, resolved stack frame addresses and matched global variables/function symbols in symbol table) to improve performance. Please refer to docs/use/ondemand.rst for details.">; + def SyntheticSymbolsNameStyle: Property<"synthetic-symbols-name-style", "Enum">, +Global, +DefaultEnumValue<"eSyntheticSymbolsNameStyleIndex">, +EnumValues<"OptionEnumValues(g_synthetic_symbols_name_style_values)">, +Desc<"Determines the way synthetic symbol names are generated for unknown symbols">; } let Definition = "debugger" in { diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 6052cc151744d..c48c5bbfb5e92 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -115,6 +115,14 @@ SymbolDownload ModuleListProperties::GetSymbolAutoDownload() const { g_modulelist_properties[idx].default_uint_value)); } +lldb::SyntheticSymbolsNameStyle +ModuleListProperties::GetSyntheticSymbolsNameStyle() const { + const uint32_t idx = ePropertySyntheticSymbolsNameStyle; + return GetPropertyAtIndexAs( + idx, static_cast( + g_modulelist_properties[idx].default_uint_value)); +} + FileSpec ModuleListProperties::GetClangModulesCachePath() const { const uint32_t idx = ePropertyClangModulesCachePath; return GetPropertyAtIndexAs(idx, {}); diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 4828de4fdfa37..825ca5babe28e 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -639,7 +639,18 @@ void Symbol::SynthesizeNameIfNeeded() const { // breakpoints on them. llvm::SmallString<256> name; llvm::raw_svector_ostream os(name); -os << GetSyntheticSymbolPrefix() << GetID(); +os << GetSyntheticSymbolPrefix(); +switch (ModuleList::GetGlobalModuleListProperties() +.GetSyntheticSymbolsNameStyle()) { +case eSyntheticSymbolsNameStyleIndex: + os << GetID(); + break; +case eSyntheticSymbolsNameStyleFileAddress: + os << "_" + << llvm::format_hex_no_prefix( +m_addr_range.GetBaseAddress().GetFileAddress(), 0); + break; +} m_mangled.SetDemangledName(ConstString(os.str()));
[Lldb-commits] [lldb] [lldb] Change synthetic symbol names to have file address (PR #137512)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137512 >From fd74de70151567d402eb7c0326a6234a21cb2db7 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 27 Apr 2025 13:48:45 +0200 Subject: [PATCH 1/5] [lldb] add settings to control how synthetic symbol names are generated --- lldb/include/lldb/Core/ModuleList.h | 15 +++ lldb/include/lldb/lldb-enumerations.h | 6 ++ lldb/source/Core/CoreProperties.td| 5 + lldb/source/Core/ModuleList.cpp | 8 lldb/source/Symbol/Symbol.cpp | 13 - 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index 909ee08f9ba62..baed175be5313 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -67,6 +67,20 @@ static constexpr OptionEnumValueElement g_auto_download_enum_values[] = { }, }; +static constexpr OptionEnumValueElement +g_synthetic_symbols_name_style_values[] = { +{ +lldb::eSyntheticSymbolsNameStyleIndex, +"index", +"Function index style", +}, +{ +lldb::eSyntheticSymbolsNameStyleFileAddress, +"file-address", +"Function file address in module style", +}, +}; + class ModuleListProperties : public Properties { mutable llvm::sys::RWMutex m_symlink_paths_mutex; PathMappingList m_symlink_paths; @@ -91,6 +105,7 @@ class ModuleListProperties : public Properties { bool GetLoadSymbolOnDemand(); lldb::SymbolDownload GetSymbolAutoDownload() const; + lldb::SyntheticSymbolsNameStyle GetSyntheticSymbolsNameStyle() const; PathMappingList GetSymlinkMappings() const; }; diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 6d10cc8bcffcb..26e83cefbe571 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -1391,6 +1391,12 @@ enum StopDisassemblyType { eStopDisassemblyTypeAlways }; +/// Format to use for unknown symbols. +enum SyntheticSymbolsNameStyle { + eSyntheticSymbolsNameStyleIndex = 0, + eSyntheticSymbolsNameStyleFileAddress = 1, +}; + } // namespace lldb #endif // LLDB_LLDB_ENUMERATIONS_H diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index a1a4e994c3b9c..7eaecb729c36d 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -46,6 +46,11 @@ let Definition = "modulelist" in { Global, DefaultFalse, Desc<"Enable on demand symbol loading in LLDB. LLDB will load debug info on demand for each module based on various conditions (e.g. matched breakpoint, resolved stack frame addresses and matched global variables/function symbols in symbol table) to improve performance. Please refer to docs/use/ondemand.rst for details.">; + def SyntheticSymbolsNameStyle: Property<"synthetic-symbols-name-style", "Enum">, +Global, +DefaultEnumValue<"eSyntheticSymbolsNameStyleIndex">, +EnumValues<"OptionEnumValues(g_synthetic_symbols_name_style_values)">, +Desc<"Determines the way synthetic symbol names are generated for unknown symbols">; } let Definition = "debugger" in { diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 6052cc151744d..c48c5bbfb5e92 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -115,6 +115,14 @@ SymbolDownload ModuleListProperties::GetSymbolAutoDownload() const { g_modulelist_properties[idx].default_uint_value)); } +lldb::SyntheticSymbolsNameStyle +ModuleListProperties::GetSyntheticSymbolsNameStyle() const { + const uint32_t idx = ePropertySyntheticSymbolsNameStyle; + return GetPropertyAtIndexAs( + idx, static_cast( + g_modulelist_properties[idx].default_uint_value)); +} + FileSpec ModuleListProperties::GetClangModulesCachePath() const { const uint32_t idx = ePropertyClangModulesCachePath; return GetPropertyAtIndexAs(idx, {}); diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 4828de4fdfa37..825ca5babe28e 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -639,7 +639,18 @@ void Symbol::SynthesizeNameIfNeeded() const { // breakpoints on them. llvm::SmallString<256> name; llvm::raw_svector_ostream os(name); -os << GetSyntheticSymbolPrefix() << GetID(); +os << GetSyntheticSymbolPrefix(); +switch (ModuleList::GetGlobalModuleListProperties() +.GetSyntheticSymbolsNameStyle()) { +case eSyntheticSymbolsNameStyleIndex: + os << GetID(); + break; +case eSyntheticSymbolsNameStyleFileAddress: + os << "_" + << llvm::format_hex_no_prefix( +m_addr_range.GetBaseAddress().GetFileAddress(), 0); + break; +} m_mangled.SetDemangledName(ConstString(os.str()));
[Lldb-commits] [lldb] [lldb] Change synthetic symbol names to have file address (PR #137512)
eronnen wrote: Cool, changed the patch to have it by default https://github.com/llvm/llvm-project/pull/137512 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Expose QueueThreadPlanForStepSingleInstruction function to SBThreadPlan (PR #137904)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137904 >From b901b71abbaac768e67913cdbc15da2337c8bb03 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Wed, 30 Apr 2025 02:00:44 +0200 Subject: [PATCH 1/3] Expose QueueThreadPlanForStepSingleInstruction function to SBThreadPlan --- lldb/include/lldb/API/SBThreadPlan.h | 4 lldb/source/API/SBThreadPlan.cpp | 31 2 files changed, 35 insertions(+) diff --git a/lldb/include/lldb/API/SBThreadPlan.h b/lldb/include/lldb/API/SBThreadPlan.h index d02ab80f76a76..ce1a1078d69b9 100644 --- a/lldb/include/lldb/API/SBThreadPlan.h +++ b/lldb/include/lldb/API/SBThreadPlan.h @@ -105,6 +105,10 @@ class LLDB_API SBThreadPlan { SBThreadPlan QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, bool first_insn, SBError &error); + SBThreadPlan QueueThreadPlanForStepSingleInstruction(bool step_over); + SBThreadPlan QueueThreadPlanForStepSingleInstruction(bool step_over, + SBError &error); + SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address); SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address, SBError &error); diff --git a/lldb/source/API/SBThreadPlan.cpp b/lldb/source/API/SBThreadPlan.cpp index 083a050de8a38..a85afbb043875 100644 --- a/lldb/source/API/SBThreadPlan.cpp +++ b/lldb/source/API/SBThreadPlan.cpp @@ -325,6 +325,37 @@ SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, return SBThreadPlan(); } +SBThreadPlan +SBThreadPlan::QueueThreadPlanForStepSingleInstruction(bool step_over) { + LLDB_INSTRUMENT_VA(this, step_over); + + SBError error; + return QueueThreadPlanForStepSingleInstruction(step_over, error); +} + +SBThreadPlan +SBThreadPlan::QueueThreadPlanForStepSingleInstruction(bool step_over, + SBError &error) { + LLDB_INSTRUMENT_VA(this, step_over, error); + + ThreadPlanSP thread_plan_sp(GetSP()); + if (thread_plan_sp) { +Status plan_status; +SBThreadPlan plan( +thread_plan_sp->GetThread().QueueThreadPlanForStepSingleInstruction( +step_over, false, false, plan_status)); + +if (plan_status.Fail()) + error.SetErrorString(plan_status.AsCString()); +else + plan.GetSP()->SetPrivate(true); + +return plan; + } + + return SBThreadPlan(); +} + SBThreadPlan SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address) { LLDB_INSTRUMENT_VA(this, sb_address); >From 8d8f4d7edbff13de7f07853700ab717ef275e3da Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Wed, 30 Apr 2025 09:37:32 +0200 Subject: [PATCH 2/3] Add API tests for QueueThreadPlanForStepSingleInstruction --- .../functionalities/step_scripted/Steps.py| 16 +++ .../step_scripted/TestStepScripted.py | 28 +++ .../API/functionalities/step_scripted/main.c | 2 +- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/lldb/test/API/functionalities/step_scripted/Steps.py b/lldb/test/API/functionalities/step_scripted/Steps.py index 3325dba753657..e9e0fae1b14be 100644 --- a/lldb/test/API/functionalities/step_scripted/Steps.py +++ b/lldb/test/API/functionalities/step_scripted/Steps.py @@ -45,6 +45,22 @@ def queue_child_thread_plan(self): return self.thread_plan.QueueThreadPlanForStepScripted("Steps.StepOut") +class StepSingleInstruction(StepWithChild): +def __init__(self, thread_plan, dict): +super().__init__(thread_plan) + +def queue_child_thread_plan(self): +return self.thread_plan.QueueThreadPlanForStepSingleInstruction(False) + + +class StepSingleInstructionWithStepOver(StepWithChild): +def __init__(self, thread_plan, dict): +super().__init__(thread_plan) + +def queue_child_thread_plan(self): +return self.thread_plan.QueueThreadPlanForStepSingleInstruction(True) + + # This plan does a step-over until a variable changes value. class StepUntil(StepWithChild): def __init__(self, thread_plan, args_data): diff --git a/lldb/test/API/functionalities/step_scripted/TestStepScripted.py b/lldb/test/API/functionalities/step_scripted/TestStepScripted.py index 53901718019f9..f65c366a09e87 100644 --- a/lldb/test/API/functionalities/step_scripted/TestStepScripted.py +++ b/lldb/test/API/functionalities/step_scripted/TestStepScripted.py @@ -44,6 +44,34 @@ def step_out_with_scripted_plan(self, name): stop_desc = thread.GetStopDescription(1000) self.assertIn("Stepping out from", stop_desc, "Got right description") +def test_step_single_instruction(self): +self.build() +(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( +self, "Break on foo call", self.main_source_file +) + +err = thread.StepUsingScriptedThreadPlan("Steps.StepSingleInstruction") +se
[Lldb-commits] [lldb] [lldb] Change synthetic symbol names to have file address (PR #137512)
eronnen wrote: Currently not, waiting for https://github.com/llvm/llvm-project/issues/137382 https://github.com/llvm/llvm-project/pull/137512 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] returning command completions up to a maximum (PR #135565)
https://github.com/eronnen created https://github.com/llvm/llvm-project/pull/135565 - Adding `max_return_elements` field to `CompletionRequest`. - adding maximum checks to `SymbolCompleter` and `SourceFileCompleter`. Fixes #135553 >From 1b45ab684446f2ff67c8ab89d00422ffcf2f7734 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 13 Apr 2025 20:46:56 +0200 Subject: [PATCH] [lldb] returning command completions up to a maximum - Adding `max_return_elements` field to `CompletionRequest`. - adding maximum checks to `SymbolCompleter` and `SourceFileCompleter`. --- lldb/include/lldb/Utility/CompletionRequest.h | 38 +++ lldb/source/API/SBCommandInterpreter.cpp | 6 ++- lldb/source/Commands/CommandCompletions.cpp | 14 +-- lldb/source/Utility/CompletionRequest.cpp | 9 - 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/lldb/include/lldb/Utility/CompletionRequest.h b/lldb/include/lldb/Utility/CompletionRequest.h index 865d6db576298..ae35c6a015649 100644 --- a/lldb/include/lldb/Utility/CompletionRequest.h +++ b/lldb/include/lldb/Utility/CompletionRequest.h @@ -115,6 +115,25 @@ class CompletionRequest { CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos, CompletionResult &result); + /// Constructs a completion request. + /// + /// \param [in] command_line + /// The command line the user has typed at this point. + /// + /// \param [in] raw_cursor_pos + /// The position of the cursor in the command line string. Index 0 means + /// the cursor is at the start of the line. The completion starts from + /// this cursor position. + /// + /// \param [in] max_return_elements + /// The maximum number of completions that should be returned. + /// + /// \param [out] result + /// The CompletionResult that will be filled with the results after this + /// request has been handled. + CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos, +size_t max_return_elements, CompletionResult &result); + /// Returns the raw user input used to create this CompletionRequest cut off /// at the cursor position. The cursor will be at the end of the raw line. llvm::StringRef GetRawLine() const { @@ -157,6 +176,23 @@ class CompletionRequest { size_t GetCursorIndex() const { return m_cursor_index; } + size_t GetMaxReturnElements() const { return m_max_return_elements; } + + /// Returns true if the maximum number of completions has been reached + /// already. + bool ShouldStopAddingResults() const { +return m_result.GetNumberOfResults() >= m_max_return_elements; + } + + /// Returns the maximum number of completions that need to be added + /// until reaching the maximum + size_t GetMaxNumberOfResultsToAdd() const { +const size_t number_of_results = m_result.GetNumberOfResults(); +if (number_of_results >= m_max_return_elements) + return 0; +return m_max_return_elements - number_of_results; + } + /// Adds a possible completion string. If the completion was already /// suggested before, it will not be added to the list of results. A copy of /// the suggested completion is stored, so the given string can be free'd @@ -231,6 +267,8 @@ class CompletionRequest { size_t m_cursor_index; /// The cursor position in the argument indexed by m_cursor_index. size_t m_cursor_char_position; + /// The maximum number of completions that should be returned. + size_t m_max_return_elements; /// The result this request is supposed to fill out. /// We keep this object private to ensure that no backend can in any way diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp index de22a9dd96bd8..6baf214f75b2d 100644 --- a/lldb/source/API/SBCommandInterpreter.cpp +++ b/lldb/source/API/SBCommandInterpreter.cpp @@ -263,9 +263,13 @@ int SBCommandInterpreter::HandleCompletionWithDescriptions( if (!IsValid()) return 0; + if (0 >= max_return_elements) +return 0; + lldb_private::StringList lldb_matches, lldb_descriptions; CompletionResult result; - CompletionRequest request(current_line, cursor - current_line, result); + CompletionRequest request(current_line, cursor - current_line, +static_cast(max_return_elements), result); m_opaque_ptr->HandleCompletion(request); result.GetMatches(lldb_matches); result.GetDescriptions(lldb_descriptions); diff --git a/lldb/source/Commands/CommandCompletions.cpp b/lldb/source/Commands/CommandCompletions.cpp index 216aaf9abce6c..11cb94d4eda15 100644 --- a/lldb/source/Commands/CommandCompletions.cpp +++ b/lldb/source/Commands/CommandCompletions.cpp @@ -91,7 +91,7 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks( nullptr} // This one has to be last in the list. }; - for (int i = 0;; i++) { + for (int i = 0; !request.ShouldStopAddingResults(); i++) { if (common_compl
[Lldb-commits] [lldb] [lldb] returning command completions up to a maximum (PR #135565)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/135565 >From 66333e243f22ca68e85dea1fe3c26b02203df975 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 13 Apr 2025 20:46:56 +0200 Subject: [PATCH] [lldb] returning command completions up to a maximum - Adding `max_return_elements` field to `CompletionRequest`. - adding maximum checks to `SymbolCompleter` and `SourceFileCompleter`. --- lldb/include/lldb/Utility/CompletionRequest.h | 24 +++ lldb/source/API/SBCommandInterpreter.cpp | 2 ++ lldb/source/Commands/CommandCompletions.cpp | 14 --- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/lldb/include/lldb/Utility/CompletionRequest.h b/lldb/include/lldb/Utility/CompletionRequest.h index 865d6db576298..2d3f0a8a44a0a 100644 --- a/lldb/include/lldb/Utility/CompletionRequest.h +++ b/lldb/include/lldb/Utility/CompletionRequest.h @@ -115,6 +115,11 @@ class CompletionRequest { CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos, CompletionResult &result); + /// Sets the maximum number of completions that should be returned. + void SetMaxReturnElements(size_t max_return_elements) { +m_max_return_elements = max_return_elements; + } + /// Returns the raw user input used to create this CompletionRequest cut off /// at the cursor position. The cursor will be at the end of the raw line. llvm::StringRef GetRawLine() const { @@ -157,6 +162,23 @@ class CompletionRequest { size_t GetCursorIndex() const { return m_cursor_index; } + size_t GetMaxReturnElements() const { return m_max_return_elements; } + + /// Returns true if the maximum number of completions has been reached + /// already. + bool ShouldStopAddingResults() const { +return m_result.GetNumberOfResults() >= m_max_return_elements; + } + + /// Returns the maximum number of completions that need to be added + /// until reaching the maximum + size_t GetMaxNumberOfResultsToAdd() const { +const size_t number_of_results = m_result.GetNumberOfResults(); +if (number_of_results >= m_max_return_elements) + return 0; +return m_max_return_elements - number_of_results; + } + /// Adds a possible completion string. If the completion was already /// suggested before, it will not be added to the list of results. A copy of /// the suggested completion is stored, so the given string can be free'd @@ -231,6 +253,8 @@ class CompletionRequest { size_t m_cursor_index; /// The cursor position in the argument indexed by m_cursor_index. size_t m_cursor_char_position; + /// The maximum number of completions that should be returned. + size_t m_max_return_elements = SIZE_MAX; /// The result this request is supposed to fill out. /// We keep this object private to ensure that no backend can in any way diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp index de22a9dd96bd8..ad3cc3c556fd4 100644 --- a/lldb/source/API/SBCommandInterpreter.cpp +++ b/lldb/source/API/SBCommandInterpreter.cpp @@ -266,6 +266,8 @@ int SBCommandInterpreter::HandleCompletionWithDescriptions( lldb_private::StringList lldb_matches, lldb_descriptions; CompletionResult result; CompletionRequest request(current_line, cursor - current_line, result); + if (max_return_elements >= 0) +request.SetMaxReturnElements(max_return_elements); m_opaque_ptr->HandleCompletion(request); result.GetMatches(lldb_matches); result.GetDescriptions(lldb_descriptions); diff --git a/lldb/source/Commands/CommandCompletions.cpp b/lldb/source/Commands/CommandCompletions.cpp index 216aaf9abce6c..11cb94d4eda15 100644 --- a/lldb/source/Commands/CommandCompletions.cpp +++ b/lldb/source/Commands/CommandCompletions.cpp @@ -91,7 +91,7 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks( nullptr} // This one has to be last in the list. }; - for (int i = 0;; i++) { + for (int i = 0; !request.ShouldStopAddingResults(); i++) { if (common_completions[i].type == lldb::eTerminatorCompletion) break; else if ((common_completions[i].type & completion_mask) == @@ -167,7 +167,9 @@ class SourceFileCompleter : public Completer { m_matching_files.AppendIfUnique(context.comp_unit->GetPrimaryFile()); } } -return Searcher::eCallbackReturnContinue; +return m_matching_files.GetSize() >= m_request.GetMaxNumberOfResultsToAdd() + ? Searcher::eCallbackReturnStop + : Searcher::eCallbackReturnContinue; } void DoCompletion(SearchFilter *filter) override { @@ -230,6 +232,10 @@ class SymbolCompleter : public Completer { // Now add the functions & symbols to the list - only add if unique: for (const SymbolContext &sc : sc_list) { +if (m_match_set.size() >= m_request.GetMaxNumberOfResultsToAdd()) { + break; +} + ConstString func_name = sc.GetFunctionName(Mangled:
[Lldb-commits] [lldb] [lldb] Change synthetic symbol names to have file address (PR #138416)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/138416 Rate limit · GitHub body { background-color: #f6f8fa; color: #24292e; font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; font-size: 14px; line-height: 1.5; margin: 0; } .container { margin: 50px auto; max-width: 600px; text-align: center; padding: 0 24px; } a { color: #0366d6; text-decoration: none; } a:hover { text-decoration: underline; } h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; text-shadow: 0 1px 0 #fff; } p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; } ul { list-style: none; margin: 25px 0; padding: 0; } li { display: table-cell; font-weight: bold; width: 1%; } .logo { display: inline-block; margin-top: 35px; } .logo-img-2x { display: none; } @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( -o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) { .logo-img-1x { display: none; } .logo-img-2x { display: inline-block; } } #suggestions { margin-top: 35px; color: #ccc; } #suggestions a { color: #66; font-weight: 200; font-size: 14px; margin: 0 10px; } Whoa there! You have exceeded a secondary rate limit. Please wait a few minutes before you try again; in some cases this may take up to an hour. https://support.github.com/contact";>Contact Support — https://githubstatus.com";>GitHub Status — https://twitter.com/githubstatus";>@githubstatus ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Expose QueueThreadPlanForStepSingleInstruction function to SBThreadPlan (PR #137904)
eronnen wrote: Added branch instructions asserts to the tests https://github.com/llvm/llvm-project/pull/137904 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Change synthetic symbol names to have file address (PR #137512)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/137512 >From 032d43184321737b4dcbb9ba7313a22ae59494f6 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 27 Apr 2025 13:48:45 +0200 Subject: [PATCH] Change ___lldb_unnamed_symbol generated names to have the file address --- lldb/source/Symbol/Symbol.cpp | 4 +++- lldb/test/Shell/ObjectFile/ELF/eh_frame-symbols.yaml | 4 ++-- .../test/Shell/SymbolFile/Breakpad/symtab-sorted-by-size.test | 2 +- lldb/test/Shell/SymbolFile/Breakpad/symtab.test | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 4828de4fdfa37..da74707c75e13 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -639,7 +639,9 @@ void Symbol::SynthesizeNameIfNeeded() const { // breakpoints on them. llvm::SmallString<256> name; llvm::raw_svector_ostream os(name); -os << GetSyntheticSymbolPrefix() << GetID(); +os << GetSyntheticSymbolPrefix() << "_" + << llvm::format_hex_no_prefix( + m_addr_range.GetBaseAddress().GetFileAddress(), 0); m_mangled.SetDemangledName(ConstString(os.str())); } } diff --git a/lldb/test/Shell/ObjectFile/ELF/eh_frame-symbols.yaml b/lldb/test/Shell/ObjectFile/ELF/eh_frame-symbols.yaml index 0dcc9fb76bd4f..709c37e79d878 100644 --- a/lldb/test/Shell/ObjectFile/ELF/eh_frame-symbols.yaml +++ b/lldb/test/Shell/ObjectFile/ELF/eh_frame-symbols.yaml @@ -3,8 +3,8 @@ # CHECK: Index UserID DSX TypeFile Address/Value Load Address Size Flags Name # CHECK: [0] 1 SourceFile 0x 0x 0x0004 - -# CHECK: [1] 2 SX Code0x00201180 0x0010 0x ___lldb_unnamed_symbol{{[0-9]*}} -# CHECK: [2] 3 SX Code0x00201190 0x0006 0x ___lldb_unnamed_symbol{{[0-9]*}} +# CHECK: [1] 2 SX Code0x00201180 0x0010 0x ___lldb_unnamed_symbol_{{[0-9a-f]*}} +# CHECK: [2] 3 SX Code0x00201190 0x0006 0x ___lldb_unnamed_symbol_{{[0-9a-f]*}} --- !ELF FileHeader: diff --git a/lldb/test/Shell/SymbolFile/Breakpad/symtab-sorted-by-size.test b/lldb/test/Shell/SymbolFile/Breakpad/symtab-sorted-by-size.test index 98052ea20bedd..00e04eb39a98e 100644 --- a/lldb/test/Shell/SymbolFile/Breakpad/symtab-sorted-by-size.test +++ b/lldb/test/Shell/SymbolFile/Breakpad/symtab-sorted-by-size.test @@ -3,7 +3,7 @@ # RUN: -s %s | FileCheck %s # CHECK: num_symbols = 4 (sorted by size): -# CHECK: [0] 0 SX Code0x0040 0x00b0 0x ___lldb_unnamed_symbol0 +# CHECK: [0] 0 SX Code0x0040 0x00b0 0x ___lldb_unnamed_symbol_40 # CHECK: [1] 0 X Code0x004000d0 0x0022 0x _start # CHECK: [2] 0 X Code0x004000b0 0x0010 0x f1 # CHECK: [3] 0 X Code0x004000c0 0x0010 0x f2 diff --git a/lldb/test/Shell/SymbolFile/Breakpad/symtab.test b/lldb/test/Shell/SymbolFile/Breakpad/symtab.test index ef41bb3bea955..a32eb5808426f 100644 --- a/lldb/test/Shell/SymbolFile/Breakpad/symtab.test +++ b/lldb/test/Shell/SymbolFile/Breakpad/symtab.test @@ -5,7 +5,7 @@ # CHECK-LABEL: (lldb) image dump symtab symtab.out # CHECK: Symtab, file = {{.*}}symtab.out, num_symbols = 4: # CHECK: Index UserID DSX TypeFile Address/Value Load Address Size Flags Name -# CHECK: [0] 0 SX Code0x0040 0x00b0 0x ___lldb_unnamed_symbol{{[0-9]*}} +# CHECK: [0] 0 SX Code0x0040 0x00b0 0x ___lldb_unnamed_symbol_{{[0-9a-f]*}} # CHECK: [1] 0 X Code0x004000b0 0x0010 0x f1 # CHECK: [2] 0 X Code0x004000c0 0x0010 0x f2 # CHECK: [3] 0 X Code0x004000d0 0x0022 0x _start ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Change synthetic symbol names to have file address (PR #137512)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/137512 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Change synthetic symbol names to have file address (PR #137512)
eronnen wrote: Changed the commit message and the title I don't mind if you merge now, I have no idea how long my merge access request is going to take :) https://github.com/llvm/llvm-project/pull/137512 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136494 >From 9bb3be7a7fe315cda2e63dd10d90b161e6677263 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 17:07:09 +0200 Subject: [PATCH 1/6] fallback to assembly when source code is not available --- lldb/tools/lldb-dap/JSONUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..1a44df7740639 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -750,9 +750,10 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, EmplaceSafeString(object, "name", frame_name); auto line_entry = frame.GetLineEntry(); + auto file_spec = line_entry.GetFileSpec(); // A line entry of 0 indicates the line is compiler generated i.e. no source // file is associated with the frame. - if (line_entry.GetFileSpec().IsValid() && + if (file_spec.IsValid() && file_spec.Exists() && (line_entry.GetLine() != 0 || line_entry.GetLine() != LLDB_INVALID_LINE_NUMBER)) { object.try_emplace("source", CreateSource(line_entry)); >From 87426fea3817fb4b54cf2a25560edfed763fe999 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:03:02 +0200 Subject: [PATCH 2/6] fix TestDAP_coreFile.py with source maps --- .../API/tools/lldb-dap/coreFile/TestDAP_coreFile.py| 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index 1896acea15a99..ce54133a61f3e 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py +++ b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py @@ -19,7 +19,9 @@ def test_core_file(self): core_file = os.path.join(current_dir, "linux-x86_64.core") self.create_debug_adapter() -self.attach(exe_file, coreFile=core_file) + +source_map = [["/home/labath/test", current_dir]] +self.attach(exe_file, coreFile=core_file, sourceMap=source_map) expected_frames = [ { @@ -27,7 +29,7 @@ def test_core_file(self): "id": 524288, "line": 4, "name": "bar", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40011C", }, { @@ -35,7 +37,7 @@ def test_core_file(self): "id": 524289, "line": 10, "name": "foo", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x400142", }, { @@ -43,7 +45,7 @@ def test_core_file(self): "id": 524290, "line": 16, "name": "_start", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40015F", }, ] >From e9043dc00010c603553ae067d5ff1e30aba0985e Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:04:46 +0200 Subject: [PATCH 3/6] use stop-disassembly-display setting to determine when to show disassembly --- .../lldb-dap/coreFile/TestDAP_coreFile.py | 10 +- .../stackTraceDisassemblyDisplay/Makefile | 3 + .../TestDAP_stackTraceDisassemblyDisplay.py | 195 ++ .../stackTraceDisassemblyDisplay/main.c | 10 + lldb/tools/lldb-dap/DAP.h | 4 + .../lldb-dap/Handler/AttachRequestHandler.cpp | 1 + .../lldb-dap/Handler/LaunchRequestHandler.cpp | 1 + .../tools/lldb-dap/Handler/RequestHandler.cpp | 4 + lldb/tools/lldb-dap/Handler/RequestHandler.h | 3 + .../Handler/StackTraceRequestHandler.cpp | 3 +- lldb/tools/lldb-dap/JSONUtils.cpp | 34 ++- lldb/tools/lldb-dap/JSONUtils.h | 21 +- lldb/tools/lldb-dap/LLDBUtils.cpp | 19 ++ lldb/tools/lldb-dap/LLDBUtils.h | 9 + 14 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/main.c diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index ce54133a61f3e..1896acea15a99 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP
[Lldb-commits] [lldb] [lldb-dap] Handle stack frames without a module (PR #136777)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136777 >From e513345b74d5dac5b80fcddebcd52ff1aa2ea4dd Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Wed, 23 Apr 2025 00:06:28 +0200 Subject: [PATCH 1/2] [lldb-dap] handle stack frames without a module --- .../lldb-dap/stackTraceMissingModule/Makefile | 2 + .../TestDAP_stackTraceMissingModule.py| 54 +++ .../lldb-dap/stackTraceMissingModule/main.c | 37 + .../lldb-dap/Handler/SourceRequestHandler.cpp | 14 - lldb/tools/lldb-dap/JSONUtils.cpp | 10 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c diff --git a/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile new file mode 100644 index 0..c9319d6e6888a --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile @@ -0,0 +1,2 @@ +C_SOURCES := main.c +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py new file mode 100644 index 0..1eb00f9935a22 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py @@ -0,0 +1,54 @@ +""" +Test lldb-dap stack trace when module is missing +""" + +from lldbsuite.test.decorators import skipUnlessPlatform +from lldbsuite.test.lldbtest import line_number +import lldbdap_testcase +import re + + +class TestDAP_stackTraceMissingModule(lldbdap_testcase.DAPTestCaseBase): +@skipUnlessPlatform(["linux"]) +def test_missingModule(self): +""" +Test that the stack frame without a module still has assembly source. +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program, commandEscapePrefix="") + +source = "main.c" +self.set_source_breakpoints( +source, +[line_number(source, "// Break here")], +) +self.continue_to_next_stop() + +# Evaluate expr -- func +expr_result = self.dap_server.request_evaluate( +expression="expr -f pointer -- func", +context="repl", +) + +expr_result_address = re.search( +r"0x[0-9a-fA-F]+", expr_result["body"]["result"] +) +self.assertIsNotNone( +expr_result_address, "Failed to get address of dynamic allocated func" +) +func_address = expr_result_address.group(0) + +self.dap_server.request_evaluate( +expression=f"breakpoint set --address {func_address}", +context="repl", +) + +self.continue_to_next_stop() + +frame_without_module = self.get_stackFrames()[0] + +self.assertIn("line", frame_without_module, "Line number missing.") +self.assertIn("column", frame_without_module, "Column number missing.") +self.assertIn("source", frame_without_module, "Source location missing.") +source = frame_without_module["source"] +self.assertIn("sourceReference", source, "Source reference missing.") diff --git a/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c new file mode 100644 index 0..d706231fbd5c2 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include + +extern uint8_t __start_target_section[]; +extern uint8_t __stop_target_section[]; + +__attribute__((used, section("target_section"))) int target_function(void) { + return 42; +} + +typedef int (*target_function_t)(void); + +int main(void) { + size_t target_function_size = __stop_target_section - __start_target_section; + size_t page_size = sysconf(_SC_PAGESIZE); + size_t page_aligned_size = + (target_function_size + page_size - 1) & ~(page_size - 1); + + void *executable_memory = + mmap(NULL, page_aligned_size, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (executable_memory == MAP_FAILED) { +perror("mmap"); +return 1; + } + + memcpy(executable_memory, __start_target_section, target_function_size); + + target_function_t func = (target_function_t)executable_memory; + int result = func(); // Break here + printf("Result from target function: %d\n", result); + + return 0; +} diff --git a/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp index 327198bab0395..fa80eb10877bf 100644 --- a/lldb/tools/lldb-dap/
[Lldb-commits] [lldb] [lldb-dap] Handle stack frames without a module (PR #136777)
@@ -783,6 +783,16 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, // Line numbers are 1-based. object.try_emplace("line", inst_line + 1); object.try_emplace("column", 1); + } else { +// No valid line entry or symbol +llvm::json::Object source; +EmplaceSafeString(source, "name", frame_name); +source.try_emplace("sourceReference", MakeDAPFrameID(frame)); +EmplaceSafeString(source, "presentationHint", "deemphasize"); +object.try_emplace("source", std::move(source)); + +object.try_emplace("line", 1); +object.try_emplace("column", 1); eronnen wrote: it still needs to be 1, this way it will be possible to debug the code in the IDE: [Screencast From 2025-04-24 08-48-53.webm](https://github.com/user-attachments/assets/c05692c6-a966-4db2-874b-0815a6563427) The only annoying thing is that each step removes the previous assembly lines, but I couldn't think of a straightforward way to tackle it because the frame changes too in every step https://github.com/llvm/llvm-project/pull/136777 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
@@ -1383,6 +1383,14 @@ enum CommandReturnObjectCallbackResult { eCommandReturnObjectPrintCallbackHandled = 1, }; +// Used to determine when to show disassembly eronnen wrote: :100: https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136494 >From 9bb3be7a7fe315cda2e63dd10d90b161e6677263 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 17:07:09 +0200 Subject: [PATCH 1/6] fallback to assembly when source code is not available --- lldb/tools/lldb-dap/JSONUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..1a44df7740639 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -750,9 +750,10 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, EmplaceSafeString(object, "name", frame_name); auto line_entry = frame.GetLineEntry(); + auto file_spec = line_entry.GetFileSpec(); // A line entry of 0 indicates the line is compiler generated i.e. no source // file is associated with the frame. - if (line_entry.GetFileSpec().IsValid() && + if (file_spec.IsValid() && file_spec.Exists() && (line_entry.GetLine() != 0 || line_entry.GetLine() != LLDB_INVALID_LINE_NUMBER)) { object.try_emplace("source", CreateSource(line_entry)); >From 87426fea3817fb4b54cf2a25560edfed763fe999 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:03:02 +0200 Subject: [PATCH 2/6] fix TestDAP_coreFile.py with source maps --- .../API/tools/lldb-dap/coreFile/TestDAP_coreFile.py| 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index 1896acea15a99..ce54133a61f3e 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py +++ b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py @@ -19,7 +19,9 @@ def test_core_file(self): core_file = os.path.join(current_dir, "linux-x86_64.core") self.create_debug_adapter() -self.attach(exe_file, coreFile=core_file) + +source_map = [["/home/labath/test", current_dir]] +self.attach(exe_file, coreFile=core_file, sourceMap=source_map) expected_frames = [ { @@ -27,7 +29,7 @@ def test_core_file(self): "id": 524288, "line": 4, "name": "bar", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40011C", }, { @@ -35,7 +37,7 @@ def test_core_file(self): "id": 524289, "line": 10, "name": "foo", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x400142", }, { @@ -43,7 +45,7 @@ def test_core_file(self): "id": 524290, "line": 16, "name": "_start", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40015F", }, ] >From e9043dc00010c603553ae067d5ff1e30aba0985e Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:04:46 +0200 Subject: [PATCH 3/6] use stop-disassembly-display setting to determine when to show disassembly --- .../lldb-dap/coreFile/TestDAP_coreFile.py | 10 +- .../stackTraceDisassemblyDisplay/Makefile | 3 + .../TestDAP_stackTraceDisassemblyDisplay.py | 195 ++ .../stackTraceDisassemblyDisplay/main.c | 10 + lldb/tools/lldb-dap/DAP.h | 4 + .../lldb-dap/Handler/AttachRequestHandler.cpp | 1 + .../lldb-dap/Handler/LaunchRequestHandler.cpp | 1 + .../tools/lldb-dap/Handler/RequestHandler.cpp | 4 + lldb/tools/lldb-dap/Handler/RequestHandler.h | 3 + .../Handler/StackTraceRequestHandler.cpp | 3 +- lldb/tools/lldb-dap/JSONUtils.cpp | 34 ++- lldb/tools/lldb-dap/JSONUtils.h | 21 +- lldb/tools/lldb-dap/LLDBUtils.cpp | 19 ++ lldb/tools/lldb-dap/LLDBUtils.h | 9 + 14 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/main.c diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index ce54133a61f3e..1896acea15a99 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136494 >From 05d605e3add0461b12ddfbb24349e20be4259060 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 17:07:09 +0200 Subject: [PATCH 1/6] fallback to assembly when source code is not available --- lldb/tools/lldb-dap/JSONUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..1a44df7740639 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -750,9 +750,10 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, EmplaceSafeString(object, "name", frame_name); auto line_entry = frame.GetLineEntry(); + auto file_spec = line_entry.GetFileSpec(); // A line entry of 0 indicates the line is compiler generated i.e. no source // file is associated with the frame. - if (line_entry.GetFileSpec().IsValid() && + if (file_spec.IsValid() && file_spec.Exists() && (line_entry.GetLine() != 0 || line_entry.GetLine() != LLDB_INVALID_LINE_NUMBER)) { object.try_emplace("source", CreateSource(line_entry)); >From 589c70284a97092d76d626cb1ed68c36e8191ee0 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:03:02 +0200 Subject: [PATCH 2/6] fix TestDAP_coreFile.py with source maps --- .../API/tools/lldb-dap/coreFile/TestDAP_coreFile.py| 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index 1896acea15a99..ce54133a61f3e 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py +++ b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py @@ -19,7 +19,9 @@ def test_core_file(self): core_file = os.path.join(current_dir, "linux-x86_64.core") self.create_debug_adapter() -self.attach(exe_file, coreFile=core_file) + +source_map = [["/home/labath/test", current_dir]] +self.attach(exe_file, coreFile=core_file, sourceMap=source_map) expected_frames = [ { @@ -27,7 +29,7 @@ def test_core_file(self): "id": 524288, "line": 4, "name": "bar", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40011C", }, { @@ -35,7 +37,7 @@ def test_core_file(self): "id": 524289, "line": 10, "name": "foo", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x400142", }, { @@ -43,7 +45,7 @@ def test_core_file(self): "id": 524290, "line": 16, "name": "_start", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40015F", }, ] >From 51167c8a5f2bc61105934bff66f353ce36aa6710 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:04:46 +0200 Subject: [PATCH 3/6] use stop-disassembly-display setting to determine when to show disassembly --- .../lldb-dap/coreFile/TestDAP_coreFile.py | 10 +- .../stackTraceDisassemblyDisplay/Makefile | 3 + .../TestDAP_stackTraceDisassemblyDisplay.py | 195 ++ .../stackTraceDisassemblyDisplay/main.c | 10 + lldb/tools/lldb-dap/DAP.h | 4 + .../lldb-dap/Handler/AttachRequestHandler.cpp | 1 + .../lldb-dap/Handler/LaunchRequestHandler.cpp | 1 + .../tools/lldb-dap/Handler/RequestHandler.cpp | 4 + lldb/tools/lldb-dap/Handler/RequestHandler.h | 3 + .../Handler/StackTraceRequestHandler.cpp | 3 +- lldb/tools/lldb-dap/JSONUtils.cpp | 34 ++- lldb/tools/lldb-dap/JSONUtils.h | 21 +- lldb/tools/lldb-dap/LLDBUtils.cpp | 19 ++ lldb/tools/lldb-dap/LLDBUtils.h | 9 + 14 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/main.c diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index ce54133a61f3e..1896acea15a99 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
eronnen wrote: @JDevlieghere Fixed comments and conflicts with `main`, from my part it's ready to merge https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
@@ -0,0 +1,195 @@ +""" +Test lldb-dap stack trace when some of the source paths are missing +""" + +from lldbsuite.test.decorators import skipIfWindows +from lldbsuite.test.lldbtest import line_number +import lldbdap_testcase +from contextlib import contextmanager +import os + + +OTHER_C_SOURCE_CODE = """ +int fibonacci(int n) { +if (n < 0) return -1; +if (n == 0) return 0; +if (n == 1) return 1; +int a = 0, b = 1, c; +for (int i = 2; i <= n; ++i) { +c = a + b; +a = b; +b = c; +} + +return b; // Break here +} +""" + + +@contextmanager +def delete_file_on_exit(path): +try: +yield path +finally: +if os.path.exists(path): +os.remove(path) + + +class TestDAP_stackTraceMissingSourcePath(lldbdap_testcase.DAPTestCaseBase): +def build_and_run_until_breakpoint(self, stop_disassembly_display: str): +""" +Build the program and run until the breakpoint is hit, and return the stack frames. +""" +other_source_file = "other.c" +with delete_file_on_exit(other_source_file): +with open(other_source_file, "w") as f: +f.write(OTHER_C_SOURCE_CODE) + +breakpoint_line = line_number(other_source_file, "// Break here") + +program = self.getBuildArtifact("a.out") +init_commands = [ +f"settings set stop-disassembly-display {stop_disassembly_display}" +] +self.build_and_launch(program, initCommands=init_commands) + +breakpoint_ids = self.set_source_breakpoints( +other_source_file, [breakpoint_line] +) +self.assertEqual( +len(breakpoint_ids), 1, "expect correct number of breakpoints" +) + +self.continue_to_breakpoints(breakpoint_ids) + +frames = self.get_stackFrames() +self.assertLessEqual(2, len(frames), "expect at least 2 frames") + +self.assertIn( +"path", +frames[0]["source"], +"Expect source path to always be in frame (other.c)", +) +self.assertIn( +"path", +frames[1]["source"], +"Expect source path in always be in frame (main.c)", +) + +return frames + +@skipIfWindows +def test_stopDisassemblyDispay_noSource(self): +""" +Test that with with stop-disassembly-display = no-source - frames without source available give assembly code. +""" +frames = self.build_and_run_until_breakpoint("no-source") + +self.assertNotIn( +"other.c", +frames[0]["source"]["path"], +"Expect original source path to not be in unavailable source frame (other.c)", +) +self.assertIn( +"sourceReference", +frames[0]["source"], +"Expect sourceReference source path in to be in unavailable source frame (other.c)", +) + +self.assertIn( +"main.c", +frames[1]["source"]["path"], +"Expect original source path to be in source code frame (main.c)", +) +self.assertNotIn( +"sourceReference", +frames[1]["source"], +"Expect no sourceReference in source code frame (main.c)", +) + +@skipIfWindows eronnen wrote: Not sure too but I've seen it in a lot of other tests in lldb-dap, maybe building the executables from `make` doesn't work on the windows tester? https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
eronnen wrote: @JDevlieghere any chance to merge? https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show load addresses in disassembly (PR #136755)
eronnen wrote: @JDevlieghere I don't have write access, fee free to merge this PR if possible (I don't know how the procedures of LLVM work in order to merge) https://github.com/llvm/llvm-project/pull/136755 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136494 >From 9bb3be7a7fe315cda2e63dd10d90b161e6677263 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 17:07:09 +0200 Subject: [PATCH 1/5] fallback to assembly when source code is not available --- lldb/tools/lldb-dap/JSONUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..1a44df7740639 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -750,9 +750,10 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, EmplaceSafeString(object, "name", frame_name); auto line_entry = frame.GetLineEntry(); + auto file_spec = line_entry.GetFileSpec(); // A line entry of 0 indicates the line is compiler generated i.e. no source // file is associated with the frame. - if (line_entry.GetFileSpec().IsValid() && + if (file_spec.IsValid() && file_spec.Exists() && (line_entry.GetLine() != 0 || line_entry.GetLine() != LLDB_INVALID_LINE_NUMBER)) { object.try_emplace("source", CreateSource(line_entry)); >From 87426fea3817fb4b54cf2a25560edfed763fe999 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:03:02 +0200 Subject: [PATCH 2/5] fix TestDAP_coreFile.py with source maps --- .../API/tools/lldb-dap/coreFile/TestDAP_coreFile.py| 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index 1896acea15a99..ce54133a61f3e 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py +++ b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py @@ -19,7 +19,9 @@ def test_core_file(self): core_file = os.path.join(current_dir, "linux-x86_64.core") self.create_debug_adapter() -self.attach(exe_file, coreFile=core_file) + +source_map = [["/home/labath/test", current_dir]] +self.attach(exe_file, coreFile=core_file, sourceMap=source_map) expected_frames = [ { @@ -27,7 +29,7 @@ def test_core_file(self): "id": 524288, "line": 4, "name": "bar", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40011C", }, { @@ -35,7 +37,7 @@ def test_core_file(self): "id": 524289, "line": 10, "name": "foo", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x400142", }, { @@ -43,7 +45,7 @@ def test_core_file(self): "id": 524290, "line": 16, "name": "_start", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40015F", }, ] >From e9043dc00010c603553ae067d5ff1e30aba0985e Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:04:46 +0200 Subject: [PATCH 3/5] use stop-disassembly-display setting to determine when to show disassembly --- .../lldb-dap/coreFile/TestDAP_coreFile.py | 10 +- .../stackTraceDisassemblyDisplay/Makefile | 3 + .../TestDAP_stackTraceDisassemblyDisplay.py | 195 ++ .../stackTraceDisassemblyDisplay/main.c | 10 + lldb/tools/lldb-dap/DAP.h | 4 + .../lldb-dap/Handler/AttachRequestHandler.cpp | 1 + .../lldb-dap/Handler/LaunchRequestHandler.cpp | 1 + .../tools/lldb-dap/Handler/RequestHandler.cpp | 4 + lldb/tools/lldb-dap/Handler/RequestHandler.h | 3 + .../Handler/StackTraceRequestHandler.cpp | 3 +- lldb/tools/lldb-dap/JSONUtils.cpp | 34 ++- lldb/tools/lldb-dap/JSONUtils.h | 21 +- lldb/tools/lldb-dap/LLDBUtils.cpp | 19 ++ lldb/tools/lldb-dap/LLDBUtils.h | 9 + 14 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/main.c diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index ce54133a61f3e..1896acea15a99 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
@@ -37,6 +37,18 @@ void OptionValueEnumeration::DumpValue(const ExecutionContext *exe_ctx, } } +llvm::json::Value +OptionValueEnumeration::ToJSON(const ExecutionContext *exe_ctx) { + const size_t count = m_enumerations.GetSize(); + for (size_t i = 0; i < count; ++i) { +if (m_enumerations.GetValueAtIndexUnchecked(i).value == m_current_value) { + return m_enumerations.GetCStringAtIndex(i).GetStringRef(); +} eronnen wrote: :100: https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
@@ -202,6 +202,10 @@ struct DAP { lldb::SBFormat frame_format; lldb::SBFormat thread_format; + + /// The value of stop-disassembly-display setting in LLDB. + std::string stop_disassembly_display; eronnen wrote: Agree, changed it https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
@@ -163,6 +163,19 @@ GetEnvironmentFromArguments(const llvm::json::Object &arguments) { return envs; } +std::string GetStopDisassemblyDisplay(lldb::SBDebugger &debugger) { + lldb::SBStructuredData result = + debugger.GetSetting("stop-disassembly-display"); + const size_t result_length = result.GetStringValue(nullptr, 0); + if (result_length > 0) { +std::string result_string(result_length, '\0'); +result.GetStringValue(result_string.data(), result_length + 1); +return result_string; + } + + return "no-debuginfo"; eronnen wrote: anyway I moved the enum to `lldb-enumerations.h` https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] fix wrong assembly line number x64 (PR #136486)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136486 >From 5cb1442b1df0befbc55806aee6c9dea4edd68816 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 14:27:53 +0200 Subject: [PATCH 1/2] fix wrong assembly line number when debugging assembly with different sized instructions --- lldb/tools/lldb-dap/JSONUtils.cpp | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..8447b3f87fb80 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -19,6 +19,7 @@ #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBFrame.h" #include "lldb/API/SBFunction.h" +#include "lldb/API/SBInstructionList.h" #include "lldb/API/SBLineEntry.h" #include "lldb/API/SBModule.h" #include "lldb/API/SBQueue.h" @@ -776,10 +777,11 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, // Calculate the line of the current PC from the start of the current // symbol. -lldb::addr_t inst_offset = frame.GetPCAddress().GetOffset() - - frame.GetSymbol().GetStartAddress().GetOffset(); -lldb::addr_t inst_line = -inst_offset / (frame.GetThread().GetProcess().GetAddressByteSize() / 2); +lldb::SBTarget target = frame.GetThread().GetProcess().GetTarget(); +lldb::SBInstructionList inst_list = target.ReadInstructions( +frame.GetSymbol().GetStartAddress(), frame.GetPCAddress(), nullptr); +size_t inst_line = inst_list.GetSize(); + // Line numbers are 1-based. object.try_emplace("line", inst_line + 1); object.try_emplace("column", 1); >From 9f285f8a43dbc025f884f71da177c002dc05e1c1 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Thu, 24 Apr 2025 01:24:21 +0200 Subject: [PATCH 2/2] add x86 tests that verifies lldb-dap steps correctly through assembly --- .../tools/lldb-dap/stackTrace-x86/Makefile| 3 + .../stackTrace-x86/TestDAP_source_x86.py | 64 +++ .../API/tools/lldb-dap/stackTrace-x86/main.c | 29 + 3 files changed, 96 insertions(+) create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace-x86/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace-x86/TestDAP_source_x86.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace-x86/main.c diff --git a/lldb/test/API/tools/lldb-dap/stackTrace-x86/Makefile b/lldb/test/API/tools/lldb-dap/stackTrace-x86/Makefile new file mode 100644 index 0..10495940055b6 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTrace-x86/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/stackTrace-x86/TestDAP_source_x86.py b/lldb/test/API/tools/lldb-dap/stackTrace-x86/TestDAP_source_x86.py new file mode 100644 index 0..5594a1977915e --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTrace-x86/TestDAP_source_x86.py @@ -0,0 +1,64 @@ +""" +Test lldb-dap stack trace containing x86 assembly +""" + +import lldbdap_testcase +from lldbsuite.test.decorators import skipUnlessArch, skipUnlessPlatform +from lldbsuite.test.lldbtest import line_number + + +class TestDAP_stacktrace_x86(lldbdap_testcase.DAPTestCaseBase): +@skipUnlessArch("x86_64") +@skipUnlessPlatform(["linux"]) +def test_stacktrace_x86(self): +""" +Tests that lldb-dap steps through correctly and the source lines are correct in x86 assembly. +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch( +program, +initCommands=[ +"settings set target.process.thread.step-in-avoid-nodebug false" +], +) + +source = "main.c" +breakpoint_ids = self.set_source_breakpoints( +source, +[line_number(source, "// Break here")], +) +self.continue_to_breakpoints(breakpoint_ids) +self.stepIn() + +frame = self.get_stackFrames()[0] +self.assertEqual( +frame["name"], +"no_branch_func", +"verify we are in the no_branch_func function", +) + +self.assertEqual(frame["line"], 1, "verify we are at the start of the function") +minimum_assembly_lines = ( +line_number(source, "Assembly end") +- line_number(source, "Assembly start") ++ 1 +) +self.assertLessEqual( +10, +minimum_assembly_lines, +"verify we have a reasonable number of assembly lines", +) + +for i in range(2, minimum_assembly_lines): +self.stepIn() +frame = self.get_stackFrames()[0] +self.assertEqual( +frame["name"], +"no_branch_func", +"verify we are still in the no_branch_func function", +) +self.assertEqual( +
[Lldb-commits] [lldb] [lldb-dap] fix wrong assembly line number x64 (PR #136486)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136486 >From 5cb1442b1df0befbc55806aee6c9dea4edd68816 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 14:27:53 +0200 Subject: [PATCH 1/2] fix wrong assembly line number when debugging assembly with different sized instructions --- lldb/tools/lldb-dap/JSONUtils.cpp | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..8447b3f87fb80 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -19,6 +19,7 @@ #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBFrame.h" #include "lldb/API/SBFunction.h" +#include "lldb/API/SBInstructionList.h" #include "lldb/API/SBLineEntry.h" #include "lldb/API/SBModule.h" #include "lldb/API/SBQueue.h" @@ -776,10 +777,11 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, // Calculate the line of the current PC from the start of the current // symbol. -lldb::addr_t inst_offset = frame.GetPCAddress().GetOffset() - - frame.GetSymbol().GetStartAddress().GetOffset(); -lldb::addr_t inst_line = -inst_offset / (frame.GetThread().GetProcess().GetAddressByteSize() / 2); +lldb::SBTarget target = frame.GetThread().GetProcess().GetTarget(); +lldb::SBInstructionList inst_list = target.ReadInstructions( +frame.GetSymbol().GetStartAddress(), frame.GetPCAddress(), nullptr); +size_t inst_line = inst_list.GetSize(); + // Line numbers are 1-based. object.try_emplace("line", inst_line + 1); object.try_emplace("column", 1); >From c00226094a8889da7732f31a0f8baf62ed04477d Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Thu, 24 Apr 2025 01:24:21 +0200 Subject: [PATCH 2/2] add x86 tests that verifies lldb-dap steps correctly through assembly --- .../tools/lldb-dap/stackTrace-x86/Makefile| 3 + .../stackTrace-x86/TestDAP_source_x86.py | 59 +++ .../API/tools/lldb-dap/stackTrace-x86/main.c | 29 + 3 files changed, 91 insertions(+) create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace-x86/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace-x86/TestDAP_source_x86.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace-x86/main.c diff --git a/lldb/test/API/tools/lldb-dap/stackTrace-x86/Makefile b/lldb/test/API/tools/lldb-dap/stackTrace-x86/Makefile new file mode 100644 index 0..10495940055b6 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTrace-x86/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/stackTrace-x86/TestDAP_source_x86.py b/lldb/test/API/tools/lldb-dap/stackTrace-x86/TestDAP_source_x86.py new file mode 100644 index 0..4e96a69aa7fe9 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTrace-x86/TestDAP_source_x86.py @@ -0,0 +1,59 @@ +""" +Test lldb-dap stack trace containing x86 assembly +""" + +import lldbdap_testcase +from lldbsuite.test.decorators import skipUnlessArch, skipUnlessPlatform +from lldbsuite.test.lldbtest import line_number + + +class TestDAP_stacktrace_x86(lldbdap_testcase.DAPTestCaseBase): +@skipUnlessArch("x86_64") +@skipUnlessPlatform(["linux"]) +def test_stacktrace_x86(self): +""" +Tests that lldb-dap steps through correctly and the source lines are correct in x86 assembly. +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch( +program, +initCommands=[ +"settings set target.process.thread.step-in-avoid-nodebug false" +], +) + +source = "main.c" +breakpoint_ids = self.set_source_breakpoints( +source, +[line_number(source, "// Break here")], +) +self.continue_to_breakpoints(breakpoint_ids) +self.stepIn() + +frame = self.get_stackFrames()[0] +self.assertEqual( +frame["name"], +"no_branch_func", +"verify we are in the no_branch_func function", +) + +self.assertEqual(frame["line"], 1, "verify we are at the start of the function") +minimum_assembly_lines = ( +line_number(source, "Assembly end") +- line_number(source, "Assembly start") ++ 1 +) + +for i in range(2, minimum_assembly_lines): +self.stepIn() +frame = self.get_stackFrames()[0] +self.assertEqual( +frame["name"], +"no_branch_func", +"verify we are still in the no_branch_func function", +) +self.assertEqual( +frame["line"], +i, +f"step in should advance a single line in the function to {i}", +) diff --git a/lldb/test/API/tools
[Lldb-commits] [lldb] [lldb-dap] fix wrong assembly line number x64 (PR #136486)
eronnen wrote: @JDevlieghere added a test that checks that `line` increments by exactly 1 each step https://github.com/llvm/llvm-project/pull/136486 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] fix wrong assembly line number x64 (PR #136486)
@@ -0,0 +1,64 @@ +""" +Test lldb-dap stack trace containing x86 assembly +""" + +import lldbdap_testcase +from lldbsuite.test.decorators import skipUnlessArch, skipUnlessPlatform +from lldbsuite.test.lldbtest import line_number + + +class TestDAP_stacktrace_x86(lldbdap_testcase.DAPTestCaseBase): +@skipUnlessArch("x86_64") +@skipUnlessPlatform(["linux"]) eronnen wrote: seems like it should work, changing https://github.com/llvm/llvm-project/pull/136486 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] fix wrong assembly line number x64 (PR #136486)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136486 >From 5cb1442b1df0befbc55806aee6c9dea4edd68816 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 14:27:53 +0200 Subject: [PATCH 1/3] fix wrong assembly line number when debugging assembly with different sized instructions --- lldb/tools/lldb-dap/JSONUtils.cpp | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..8447b3f87fb80 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -19,6 +19,7 @@ #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBFrame.h" #include "lldb/API/SBFunction.h" +#include "lldb/API/SBInstructionList.h" #include "lldb/API/SBLineEntry.h" #include "lldb/API/SBModule.h" #include "lldb/API/SBQueue.h" @@ -776,10 +777,11 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, // Calculate the line of the current PC from the start of the current // symbol. -lldb::addr_t inst_offset = frame.GetPCAddress().GetOffset() - - frame.GetSymbol().GetStartAddress().GetOffset(); -lldb::addr_t inst_line = -inst_offset / (frame.GetThread().GetProcess().GetAddressByteSize() / 2); +lldb::SBTarget target = frame.GetThread().GetProcess().GetTarget(); +lldb::SBInstructionList inst_list = target.ReadInstructions( +frame.GetSymbol().GetStartAddress(), frame.GetPCAddress(), nullptr); +size_t inst_line = inst_list.GetSize(); + // Line numbers are 1-based. object.try_emplace("line", inst_line + 1); object.try_emplace("column", 1); >From 9f285f8a43dbc025f884f71da177c002dc05e1c1 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Thu, 24 Apr 2025 01:24:21 +0200 Subject: [PATCH 2/3] add x86 tests that verifies lldb-dap steps correctly through assembly --- .../tools/lldb-dap/stackTrace-x86/Makefile| 3 + .../stackTrace-x86/TestDAP_source_x86.py | 64 +++ .../API/tools/lldb-dap/stackTrace-x86/main.c | 29 + 3 files changed, 96 insertions(+) create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace-x86/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace-x86/TestDAP_source_x86.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace-x86/main.c diff --git a/lldb/test/API/tools/lldb-dap/stackTrace-x86/Makefile b/lldb/test/API/tools/lldb-dap/stackTrace-x86/Makefile new file mode 100644 index 0..10495940055b6 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTrace-x86/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/stackTrace-x86/TestDAP_source_x86.py b/lldb/test/API/tools/lldb-dap/stackTrace-x86/TestDAP_source_x86.py new file mode 100644 index 0..5594a1977915e --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTrace-x86/TestDAP_source_x86.py @@ -0,0 +1,64 @@ +""" +Test lldb-dap stack trace containing x86 assembly +""" + +import lldbdap_testcase +from lldbsuite.test.decorators import skipUnlessArch, skipUnlessPlatform +from lldbsuite.test.lldbtest import line_number + + +class TestDAP_stacktrace_x86(lldbdap_testcase.DAPTestCaseBase): +@skipUnlessArch("x86_64") +@skipUnlessPlatform(["linux"]) +def test_stacktrace_x86(self): +""" +Tests that lldb-dap steps through correctly and the source lines are correct in x86 assembly. +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch( +program, +initCommands=[ +"settings set target.process.thread.step-in-avoid-nodebug false" +], +) + +source = "main.c" +breakpoint_ids = self.set_source_breakpoints( +source, +[line_number(source, "// Break here")], +) +self.continue_to_breakpoints(breakpoint_ids) +self.stepIn() + +frame = self.get_stackFrames()[0] +self.assertEqual( +frame["name"], +"no_branch_func", +"verify we are in the no_branch_func function", +) + +self.assertEqual(frame["line"], 1, "verify we are at the start of the function") +minimum_assembly_lines = ( +line_number(source, "Assembly end") +- line_number(source, "Assembly start") ++ 1 +) +self.assertLessEqual( +10, +minimum_assembly_lines, +"verify we have a reasonable number of assembly lines", +) + +for i in range(2, minimum_assembly_lines): +self.stepIn() +frame = self.get_stackFrames()[0] +self.assertEqual( +frame["name"], +"no_branch_func", +"verify we are still in the no_branch_func function", +) +self.assertEqual( +
[Lldb-commits] [lldb] [lldb-dap] Handle stack frames without a module (PR #136777)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136777 >From e513345b74d5dac5b80fcddebcd52ff1aa2ea4dd Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Wed, 23 Apr 2025 00:06:28 +0200 Subject: [PATCH] [lldb-dap] handle stack frames without a module --- .../lldb-dap/stackTraceMissingModule/Makefile | 2 + .../TestDAP_stackTraceMissingModule.py| 54 +++ .../lldb-dap/stackTraceMissingModule/main.c | 37 + .../lldb-dap/Handler/SourceRequestHandler.cpp | 14 - lldb/tools/lldb-dap/JSONUtils.cpp | 10 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c diff --git a/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile new file mode 100644 index 0..c9319d6e6888a --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/Makefile @@ -0,0 +1,2 @@ +C_SOURCES := main.c +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py new file mode 100644 index 0..1eb00f9935a22 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/TestDAP_stackTraceMissingModule.py @@ -0,0 +1,54 @@ +""" +Test lldb-dap stack trace when module is missing +""" + +from lldbsuite.test.decorators import skipUnlessPlatform +from lldbsuite.test.lldbtest import line_number +import lldbdap_testcase +import re + + +class TestDAP_stackTraceMissingModule(lldbdap_testcase.DAPTestCaseBase): +@skipUnlessPlatform(["linux"]) +def test_missingModule(self): +""" +Test that the stack frame without a module still has assembly source. +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program, commandEscapePrefix="") + +source = "main.c" +self.set_source_breakpoints( +source, +[line_number(source, "// Break here")], +) +self.continue_to_next_stop() + +# Evaluate expr -- func +expr_result = self.dap_server.request_evaluate( +expression="expr -f pointer -- func", +context="repl", +) + +expr_result_address = re.search( +r"0x[0-9a-fA-F]+", expr_result["body"]["result"] +) +self.assertIsNotNone( +expr_result_address, "Failed to get address of dynamic allocated func" +) +func_address = expr_result_address.group(0) + +self.dap_server.request_evaluate( +expression=f"breakpoint set --address {func_address}", +context="repl", +) + +self.continue_to_next_stop() + +frame_without_module = self.get_stackFrames()[0] + +self.assertIn("line", frame_without_module, "Line number missing.") +self.assertIn("column", frame_without_module, "Column number missing.") +self.assertIn("source", frame_without_module, "Source location missing.") +source = frame_without_module["source"] +self.assertIn("sourceReference", source, "Source reference missing.") diff --git a/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c new file mode 100644 index 0..d706231fbd5c2 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTraceMissingModule/main.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include + +extern uint8_t __start_target_section[]; +extern uint8_t __stop_target_section[]; + +__attribute__((used, section("target_section"))) int target_function(void) { + return 42; +} + +typedef int (*target_function_t)(void); + +int main(void) { + size_t target_function_size = __stop_target_section - __start_target_section; + size_t page_size = sysconf(_SC_PAGESIZE); + size_t page_aligned_size = + (target_function_size + page_size - 1) & ~(page_size - 1); + + void *executable_memory = + mmap(NULL, page_aligned_size, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (executable_memory == MAP_FAILED) { +perror("mmap"); +return 1; + } + + memcpy(executable_memory, __start_target_section, target_function_size); + + target_function_t func = (target_function_t)executable_memory; + int result = func(); // Break here + printf("Result from target function: %d\n", result); + + return 0; +} diff --git a/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp index 327198bab0395..fa80eb10877bf 100644 --- a/lldb/tools/lldb-dap/Hand
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136494 >From 05d605e3add0461b12ddfbb24349e20be4259060 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 17:07:09 +0200 Subject: [PATCH 1/8] fallback to assembly when source code is not available --- lldb/tools/lldb-dap/JSONUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..1a44df7740639 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -750,9 +750,10 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, EmplaceSafeString(object, "name", frame_name); auto line_entry = frame.GetLineEntry(); + auto file_spec = line_entry.GetFileSpec(); // A line entry of 0 indicates the line is compiler generated i.e. no source // file is associated with the frame. - if (line_entry.GetFileSpec().IsValid() && + if (file_spec.IsValid() && file_spec.Exists() && (line_entry.GetLine() != 0 || line_entry.GetLine() != LLDB_INVALID_LINE_NUMBER)) { object.try_emplace("source", CreateSource(line_entry)); >From 589c70284a97092d76d626cb1ed68c36e8191ee0 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:03:02 +0200 Subject: [PATCH 2/8] fix TestDAP_coreFile.py with source maps --- .../API/tools/lldb-dap/coreFile/TestDAP_coreFile.py| 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index 1896acea15a99..ce54133a61f3e 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py +++ b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py @@ -19,7 +19,9 @@ def test_core_file(self): core_file = os.path.join(current_dir, "linux-x86_64.core") self.create_debug_adapter() -self.attach(exe_file, coreFile=core_file) + +source_map = [["/home/labath/test", current_dir]] +self.attach(exe_file, coreFile=core_file, sourceMap=source_map) expected_frames = [ { @@ -27,7 +29,7 @@ def test_core_file(self): "id": 524288, "line": 4, "name": "bar", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40011C", }, { @@ -35,7 +37,7 @@ def test_core_file(self): "id": 524289, "line": 10, "name": "foo", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x400142", }, { @@ -43,7 +45,7 @@ def test_core_file(self): "id": 524290, "line": 16, "name": "_start", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40015F", }, ] >From 51167c8a5f2bc61105934bff66f353ce36aa6710 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:04:46 +0200 Subject: [PATCH 3/8] use stop-disassembly-display setting to determine when to show disassembly --- .../lldb-dap/coreFile/TestDAP_coreFile.py | 10 +- .../stackTraceDisassemblyDisplay/Makefile | 3 + .../TestDAP_stackTraceDisassemblyDisplay.py | 195 ++ .../stackTraceDisassemblyDisplay/main.c | 10 + lldb/tools/lldb-dap/DAP.h | 4 + .../lldb-dap/Handler/AttachRequestHandler.cpp | 1 + .../lldb-dap/Handler/LaunchRequestHandler.cpp | 1 + .../tools/lldb-dap/Handler/RequestHandler.cpp | 4 + lldb/tools/lldb-dap/Handler/RequestHandler.h | 3 + .../Handler/StackTraceRequestHandler.cpp | 3 +- lldb/tools/lldb-dap/JSONUtils.cpp | 34 ++- lldb/tools/lldb-dap/JSONUtils.h | 21 +- lldb/tools/lldb-dap/LLDBUtils.cpp | 19 ++ lldb/tools/lldb-dap/LLDBUtils.h | 9 + 14 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/main.c diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index ce54133a61f3e..1896acea15a99 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
@@ -0,0 +1,195 @@ +""" +Test lldb-dap stack trace when some of the source paths are missing +""" + +from lldbsuite.test.decorators import skipIfWindows +from lldbsuite.test.lldbtest import line_number +import lldbdap_testcase +from contextlib import contextmanager +import os + + +OTHER_C_SOURCE_CODE = """ +int fibonacci(int n) { +if (n < 0) return -1; +if (n == 0) return 0; +if (n == 1) return 1; +int a = 0, b = 1, c; +for (int i = 2; i <= n; ++i) { +c = a + b; +a = b; +b = c; +} + +return b; // Break here +} +""" + + +@contextmanager +def delete_file_on_exit(path): +try: +yield path +finally: +if os.path.exists(path): +os.remove(path) + + +class TestDAP_stackTraceMissingSourcePath(lldbdap_testcase.DAPTestCaseBase): +def build_and_run_until_breakpoint(self, stop_disassembly_display: str): +""" +Build the program and run until the breakpoint is hit, and return the stack frames. +""" +other_source_file = "other.c" +with delete_file_on_exit(other_source_file): +with open(other_source_file, "w") as f: +f.write(OTHER_C_SOURCE_CODE) + +breakpoint_line = line_number(other_source_file, "// Break here") + +program = self.getBuildArtifact("a.out") +init_commands = [ +f"settings set stop-disassembly-display {stop_disassembly_display}" +] +self.build_and_launch(program, initCommands=init_commands) + +breakpoint_ids = self.set_source_breakpoints( +other_source_file, [breakpoint_line] +) +self.assertEqual( +len(breakpoint_ids), 1, "expect correct number of breakpoints" +) + +self.continue_to_breakpoints(breakpoint_ids) + +frames = self.get_stackFrames() +self.assertLessEqual(2, len(frames), "expect at least 2 frames") + +self.assertIn( +"path", +frames[0]["source"], +"Expect source path to always be in frame (other.c)", +) +self.assertIn( +"path", +frames[1]["source"], +"Expect source path in always be in frame (main.c)", +) + +return frames + +@skipIfWindows +def test_stopDisassemblyDispay_noSource(self): +""" +Test that with with stop-disassembly-display = no-source - frames without source available give assembly code. +""" +frames = self.build_and_run_until_breakpoint("no-source") + +self.assertNotIn( +"other.c", +frames[0]["source"]["path"], +"Expect original source path to not be in unavailable source frame (other.c)", +) +self.assertIn( +"sourceReference", +frames[0]["source"], +"Expect sourceReference source path in to be in unavailable source frame (other.c)", +) + +self.assertIn( +"main.c", +frames[1]["source"]["path"], +"Expect original source path to be in source code frame (main.c)", +) +self.assertNotIn( +"sourceReference", +frames[1]["source"], +"Expect no sourceReference in source code frame (main.c)", +) + +@skipIfWindows eronnen wrote: removed :100: https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
@@ -0,0 +1,195 @@ +""" +Test lldb-dap stack trace when some of the source paths are missing +""" + +from lldbsuite.test.decorators import skipIfWindows +from lldbsuite.test.lldbtest import line_number +import lldbdap_testcase +from contextlib import contextmanager +import os + + +OTHER_C_SOURCE_CODE = """ +int fibonacci(int n) { +if (n < 0) return -1; +if (n == 0) return 0; +if (n == 1) return 1; +int a = 0, b = 1, c; +for (int i = 2; i <= n; ++i) { +c = a + b; +a = b; +b = c; +} + +return b; // Break here +} +""" + + +@contextmanager +def delete_file_on_exit(path): +try: +yield path +finally: +if os.path.exists(path): +os.remove(path) + + +class TestDAP_stackTraceMissingSourcePath(lldbdap_testcase.DAPTestCaseBase): +def build_and_run_until_breakpoint(self, stop_disassembly_display: str): +""" +Build the program and run until the breakpoint is hit, and return the stack frames. +""" +other_source_file = "other.c" +with delete_file_on_exit(other_source_file): +with open(other_source_file, "w") as f: +f.write(OTHER_C_SOURCE_CODE) + +breakpoint_line = line_number(other_source_file, "// Break here") + +program = self.getBuildArtifact("a.out") +init_commands = [ +f"settings set stop-disassembly-display {stop_disassembly_display}" +] +self.build_and_launch(program, initCommands=init_commands) + +breakpoint_ids = self.set_source_breakpoints( +other_source_file, [breakpoint_line] +) +self.assertEqual( +len(breakpoint_ids), 1, "expect correct number of breakpoints" +) + +self.continue_to_breakpoints(breakpoint_ids) + +frames = self.get_stackFrames() +self.assertLessEqual(2, len(frames), "expect at least 2 frames") + +self.assertIn( +"path", +frames[0]["source"], +"Expect source path to always be in frame (other.c)", +) +self.assertIn( +"path", +frames[1]["source"], +"Expect source path in always be in frame (main.c)", +) + +return frames + +@skipIfWindows +def test_stopDisassemblyDispay_noSource(self): eronnen wrote: :100: https://github.com/llvm/llvm-project/pull/136494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] fix wrong assembly line number x64 (PR #136486)
https://github.com/eronnen edited https://github.com/llvm/llvm-project/pull/136486 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
https://github.com/eronnen updated https://github.com/llvm/llvm-project/pull/136494 >From 05d605e3add0461b12ddfbb24349e20be4259060 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 17:07:09 +0200 Subject: [PATCH 1/7] fallback to assembly when source code is not available --- lldb/tools/lldb-dap/JSONUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index 33f10c93d2ada..1a44df7740639 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -750,9 +750,10 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, EmplaceSafeString(object, "name", frame_name); auto line_entry = frame.GetLineEntry(); + auto file_spec = line_entry.GetFileSpec(); // A line entry of 0 indicates the line is compiler generated i.e. no source // file is associated with the frame. - if (line_entry.GetFileSpec().IsValid() && + if (file_spec.IsValid() && file_spec.Exists() && (line_entry.GetLine() != 0 || line_entry.GetLine() != LLDB_INVALID_LINE_NUMBER)) { object.try_emplace("source", CreateSource(line_entry)); >From 589c70284a97092d76d626cb1ed68c36e8191ee0 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:03:02 +0200 Subject: [PATCH 2/7] fix TestDAP_coreFile.py with source maps --- .../API/tools/lldb-dap/coreFile/TestDAP_coreFile.py| 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index 1896acea15a99..ce54133a61f3e 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py +++ b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py @@ -19,7 +19,9 @@ def test_core_file(self): core_file = os.path.join(current_dir, "linux-x86_64.core") self.create_debug_adapter() -self.attach(exe_file, coreFile=core_file) + +source_map = [["/home/labath/test", current_dir]] +self.attach(exe_file, coreFile=core_file, sourceMap=source_map) expected_frames = [ { @@ -27,7 +29,7 @@ def test_core_file(self): "id": 524288, "line": 4, "name": "bar", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40011C", }, { @@ -35,7 +37,7 @@ def test_core_file(self): "id": 524289, "line": 10, "name": "foo", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x400142", }, { @@ -43,7 +45,7 @@ def test_core_file(self): "id": 524290, "line": 16, "name": "_start", -"source": {"name": "main.c", "path": "/home/labath/test/main.c"}, +"source": {"name": "main.c", "path": os.path.join(current_dir, "main.c")}, "instructionPointerReference": "0x40015F", }, ] >From 51167c8a5f2bc61105934bff66f353ce36aa6710 Mon Sep 17 00:00:00 2001 From: Ely Ronnen Date: Sun, 20 Apr 2025 21:04:46 +0200 Subject: [PATCH 3/7] use stop-disassembly-display setting to determine when to show disassembly --- .../lldb-dap/coreFile/TestDAP_coreFile.py | 10 +- .../stackTraceDisassemblyDisplay/Makefile | 3 + .../TestDAP_stackTraceDisassemblyDisplay.py | 195 ++ .../stackTraceDisassemblyDisplay/main.c | 10 + lldb/tools/lldb-dap/DAP.h | 4 + .../lldb-dap/Handler/AttachRequestHandler.cpp | 1 + .../lldb-dap/Handler/LaunchRequestHandler.cpp | 1 + .../tools/lldb-dap/Handler/RequestHandler.cpp | 4 + lldb/tools/lldb-dap/Handler/RequestHandler.h | 3 + .../Handler/StackTraceRequestHandler.cpp | 3 +- lldb/tools/lldb-dap/JSONUtils.cpp | 34 ++- lldb/tools/lldb-dap/JSONUtils.h | 21 +- lldb/tools/lldb-dap/LLDBUtils.cpp | 19 ++ lldb/tools/lldb-dap/LLDBUtils.h | 9 + 14 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/main.c diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py index ce54133a61f3e..1896acea15a99 100644 --- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP
[Lldb-commits] [lldb] [lldb-dap] Show assembly depending on `stop-disassembly-display` settings (PR #136494)
@@ -0,0 +1,195 @@ +""" +Test lldb-dap stack trace when some of the source paths are missing +""" + +from lldbsuite.test.decorators import skipIfWindows +from lldbsuite.test.lldbtest import line_number +import lldbdap_testcase +from contextlib import contextmanager +import os + + +OTHER_C_SOURCE_CODE = """ +int fibonacci(int n) { +if (n < 0) return -1; +if (n == 0) return 0; +if (n == 1) return 1; +int a = 0, b = 1, c; +for (int i = 2; i <= n; ++i) { +c = a + b; +a = b; +b = c; +} + +return b; // Break here +} +""" + + +@contextmanager +def delete_file_on_exit(path): +try: +yield path +finally: +if os.path.exists(path): +os.remove(path) + + +class TestDAP_stackTraceMissingSourcePath(lldbdap_testcase.DAPTestCaseBase): +def build_and_run_until_breakpoint(self, stop_disassembly_display: str): +""" +Build the program and run until the breakpoint is hit, and return the stack frames. +""" +other_source_file = "other.c" +with delete_file_on_exit(other_source_file): +with open(other_source_file, "w") as f: +f.write(OTHER_C_SOURCE_CODE) + +breakpoint_line = line_number(other_source_file, "// Break here") + +program = self.getBuildArtifact("a.out") +init_commands = [ +f"settings set stop-disassembly-display {stop_disassembly_display}" +] +self.build_and_launch(program, initCommands=init_commands) + +breakpoint_ids = self.set_source_breakpoints( +other_source_file, [breakpoint_line] +) +self.assertEqual( +len(breakpoint_ids), 1, "expect correct number of breakpoints" +) + +self.continue_to_breakpoints(breakpoint_ids) + +frames = self.get_stackFrames() +self.assertLessEqual(2, len(frames), "expect at least 2 frames") + +self.assertIn( +"path", +frames[0]["source"], +"Expect source path to always be in frame (other.c)", +) +self.assertIn( +"path", +frames[1]["source"], +"Expect source path in always be in frame (main.c)", +) + +return frames + +@skipIfWindows +def test_stopDisassemblyDispay_noSource(self): +""" +Test that with with stop-disassembly-display = no-source - frames without source available give assembly code. +""" +frames = self.build_and_run_until_breakpoint("no-source") + +self.assertNotIn( +"other.c", +frames[0]["source"]["path"], +"Expect original source path to not be in unavailable source frame (other.c)", +) +self.assertIn( +"sourceReference", +frames[0]["source"], +"Expect sourceReference source path in to be in unavailable source frame (other.c)", +) + +self.assertIn( +"main.c", +frames[1]["source"]["path"], +"Expect original source path to be in source code frame (main.c)", +) +self.assertNotIn( +"sourceReference", +frames[1]["source"], +"Expect no sourceReference in source code frame (main.c)", +) + +@skipIfWindows +def test_stopDisassemblyDispay_noDebuginfo(self): +""" +Test that with with stop-disassembly-display = no-debuginfo - all frames give source code even when source not available. +""" +frames = self.build_and_run_until_breakpoint("no-debuginfo") + +self.assertIn( +"other.c", +frames[0]["source"]["path"], +"Expect original source path to be in unavailable source frame (other.c)", +) +self.assertNotIn( +"sourceReference", +frames[0]["source"], +"Expect sourceReference source path in to be in unavailable source frame (other.c)", +) + +self.assertIn( +"main.c", +frames[1]["source"]["path"], +"Expect original source path to be in source code frame (main.c)", +) +self.assertNotIn( +"sourceReference", +frames[1]["source"], +"Expect no sourceReference in source code frame (main.c)", +) + +@skipIfWindows +def test_stopDisassemblyDispay_never(self): +""" +Test that with with stop-disassembly-display = never - all frames don't give assembly code. +""" +frames = self.build_and_run_until_breakpoint("never") + +self.assertIn( +"other.c", +frames[0]["source"]["path"], +"Expect original source path to be in unavailable source frame (other.c)", +) +self.assertNotIn( +"sourceReference", +frames[0]["source"], +