[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)
vogelsgesang wrote: > I am not sure if it possible to use a dict for sourceMaps since a source can > map to multiple destination see test Interestingly, CodeLLDB also uses an object, see https://github.com/vadimcn/codelldb/blob/v1.10.0/MANUAL.md#source-path-remapping. Probably they just don't support mapping a path to multiple source paths. I guess we want to stay with the "array-of-array" configuration, then. What do you think, @JDevlieghere https://github.com/llvm/llvm-project/pull/106919 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)
@@ -1831,7 +1831,13 @@ lldb::SBError LaunchProcess(const llvm::json::Object &request) { launch_info.SetArguments(MakeArgv(args).data(), true); // Pass any environment variables along that the user specified. - auto envs = GetStrings(arguments, "env"); + auto envMap = GetStringMap(*arguments, "env"); + std::vector envs; + envs.reserve(envMap.size()); + for (const auto &[key, value] : envMap) { +envs.emplace_back(key + '=' + value); + } + if (!envs.empty()) launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true); vogelsgesang wrote: instead of setting concatenated strings, I think we should use `SBLaunchInfo::SetEnvironment` and `SBEnvironment::Set` https://github.com/llvm/llvm-project/pull/106919 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)
@@ -151,6 +152,26 @@ bool ObjectContainsKey(const llvm::json::Object &obj, llvm::StringRef key); /// strings, numbers or booleans. std::vector GetStrings(const llvm::json::Object *obj, llvm::StringRef key); +/// Extract an object of key value strings for the specified key from an object. +/// +/// String values in the array will be extracted without any quotes vogelsgesang wrote: ```suggestion /// String values in the object will be extracted without any quotes ``` https://github.com/llvm/llvm-project/pull/106919 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)
@@ -194,9 +199,14 @@ "description": "Specify a source path to remap \"./\" to allow full paths to be used when setting breakpoints in binaries that have relative source paths." }, "sourceMap": { -"type": "array", -"description": "Specify an array of path remappings; each element must itself be a two element array containing a source and destination path name. Overrides sourcePath.", -"default": [] +"type": "object", +"description": "Specify an object of path remappings; each entry has a key containing the source path and a value containing the destination path. E.g { \"/the/source/path\": \"/the/destination/path\" } Overrides sourcePath.", vogelsgesang wrote: ```suggestion "description": "Specify an object of path remappings; each entry has a key containing the source path and a value containing the destination path. E.g `{ \"/the/source/path\": \"/the/destination/path\" }`. Overrides sourcePath.", ``` https://github.com/llvm/llvm-project/pull/106919 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)
@@ -151,6 +152,26 @@ bool ObjectContainsKey(const llvm::json::Object &obj, llvm::StringRef key); /// strings, numbers or booleans. std::vector GetStrings(const llvm::json::Object *obj, llvm::StringRef key); +/// Extract an object of key value strings for the specified key from an object. +/// +/// String values in the array will be extracted without any quotes +/// around them. Numbers and Booleans will be converted into +/// strings. Any NULL, array or objects values in the array will be +/// ignored. +/// +/// \param[in] obj +/// A JSON object that we will attempt to extract the array from +/// +/// \param[in] key +/// The key to use when extracting the value +/// +/// \return +/// An object of key value strings for the specified \a key, or +/// \a fail_value if there is no key that matches or if the +/// value is not an object or key and values in the object are not +/// strings, numbers or booleans. +std::unordered_map +GetStringObject(const llvm::json::Object &obj, llvm::StringRef key); vogelsgesang wrote: Feels slightly more self-explanatory to me: ```suggestion GetStringMap(const llvm::json::Object &obj, llvm::StringRef key); ``` https://github.com/llvm/llvm-project/pull/106919 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)
@@ -299,9 +309,14 @@ "description": "Specify a source path to remap \"./\" to allow full paths to be used when setting breakpoints in binaries that have relative source paths." }, "sourceMap": { -"type": "array", -"description": "Specify an array of path remappings; each element must itself be a two element array containing a source and destination path name. Overrides sourcePath.", -"default": [] +"type": "object", +"description": "Specify an object of path remappings; each entry has a key containing the source path and a value containing the destination path. E.g { \"/the/source/path\": \"/the/destination/path\" } Overrides sourcePath.", vogelsgesang wrote: ```suggestion "description": "Specify an object of path remappings; each entry has a key containing the source path and a value containing the destination path. E.g `{ \"/the/source/path\": \"/the/destination/path\" }`. Overrides sourcePath.", ``` https://github.com/llvm/llvm-project/pull/106919 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)
@@ -160,9 +160,14 @@ "default": "${workspaceRoot}" }, "env": { -"type": "array", -"description": "Additional environment variables to set when launching the program. This is an array of strings that contains the variable name followed by an optional '=' character and the environment variable's value.", -"default": [] +"type": "object", +"description": "Additional environment variables to set when launching the program. eg { \"FOO\": \"1\" }", vogelsgesang wrote: ```suggestion "description": "Additional environment variables to set when launching the program. E.g. `{ \"FOO\": \"1\" }`", ``` https://github.com/llvm/llvm-project/pull/106919 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)
@@ -151,6 +152,26 @@ bool ObjectContainsKey(const llvm::json::Object &obj, llvm::StringRef key); /// strings, numbers or booleans. std::vector GetStrings(const llvm::json::Object *obj, llvm::StringRef key); +/// Extract an object of key value strings for the specified key from an object. vogelsgesang wrote: missing empty lines ```suggestion llvm::StringRef key); /// Extract an object of key value strings for the specified key from an object. ``` https://github.com/llvm/llvm-project/pull/106919 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix test expectation in `TestFrameRecognizer.py` (PR #106281)
https://github.com/vogelsgesang closed https://github.com/llvm/llvm-project/pull/106281 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix test expectation in `TestFrameRecognizer.py` (PR #106281)
vogelsgesang wrote: @adrian-prantl It seems I overlooked this test expectation. This hopefully fixes the build issue in https://green.lab.llvm.org/job/llvm.org/view/LLDB/job/as-lldb-cmake/10463/ . Unfortunately, i was not able to run this test locally, it is marked as "unsupported" for some reason https://github.com/llvm/llvm-project/pull/106281 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix test expectation in `TestFrameRecognizer.py` (PR #106281)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/106281 >From b32e85a07ab0e6dc55d28706d50eb84345575bc6 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Tue, 27 Aug 2024 20:14:36 + Subject: [PATCH] [lldb] Fix test expectation in `TestFrameRecognizer.py` --- .../test/API/commands/frame/recognizer/TestFrameRecognizer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py b/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py index e25df2b6cdc245..24d6a67c0ccd48 100644 --- a/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py +++ b/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py @@ -58,7 +58,7 @@ def test_frame_recognizer_1(self): self.expect( "frame recognizer list", substrs=[ -"1: recognizer.MyOtherFrameRecognizer, module a.out, demangled symbol bar (regexp)" +"1: recognizer.MyOtherFrameRecognizer, module a.out, demangled symbol regex bar" ], ) self.expect( @@ -81,7 +81,7 @@ def test_frame_recognizer_1(self): self.expect( "frame recognizer list", substrs=[ -"1: recognizer.MyOtherFrameRecognizer, module a.out, demangled symbol regexp bar" +"1: recognizer.MyOtherFrameRecognizer, module a.out, demangled symbol regex bar" ], ) self.expect( ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
vogelsgesang wrote: fixed in #106281 https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix test expectation in `TestFrameRecognizer.py` (PR #106281)
https://github.com/vogelsgesang created https://github.com/llvm/llvm-project/pull/106281 None >From 2fdc99f2e42ac7bc12449e420ff653fb963cee24 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Tue, 27 Aug 2024 20:14:36 + Subject: [PATCH] [lldb] Fix test expectation in `TestFrameRecognizer.py` --- lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py b/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py index e25df2b6cdc245..0621fdbc669193 100644 --- a/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py +++ b/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py @@ -58,7 +58,7 @@ def test_frame_recognizer_1(self): self.expect( "frame recognizer list", substrs=[ -"1: recognizer.MyOtherFrameRecognizer, module a.out, demangled symbol bar (regexp)" +"1: recognizer.MyOtherFrameRecognizer, module a.out, demangled symbol regex bar" ], ) self.expect( ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang closed https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From e90463e8967c2019e220b063ed4ce73cd0172bf3 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/7] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index 1e4a2cbb1133f7..6d446a099efc78 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From e90463e8967c2019e220b063ed4ce73cd0172bf3 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/7] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index 1e4a2cbb1133f7..6d446a099efc78 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
@@ -305,7 +307,9 @@ def test_frame_recognizer_target_specific(self): self.expect( "frame recognizer list", -substrs=["recognizer.MyFrameRecognizer, module a.out, symbol bar"], +substrs=[ +"recognizer.MyFrameRecognizer, module a.out, demangled symbol bar" +], vogelsgesang wrote: Unfortunately, I was not able to write such a test case. Note that the `frame recognizer add` command does not yet expose a way to match on anything else than demangled names. I agree that we should be adding test cases here, as soon as `frame recognizer add` supports choosing the symbol mangling. @adrian-prantl Are you planning to extend `frame recognizer add` accordingly? https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From e90463e8967c2019e220b063ed4ce73cd0172bf3 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/6] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index 1e4a2cbb1133f7..6d446a099efc78 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From e90463e8967c2019e220b063ed4ce73cd0172bf3 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/5] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index 1e4a2cbb1133f7..6d446a099efc78 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
@@ -196,8 +197,8 @@ AbortWithPayloadFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) { abort_dict_sp->AddStringItem(reason_key, reason_string); abort_dict_sp->AddIntegerItem(flags_key, flags_val); - // This will overwrite the abort_with_payload information in the dictionary - // already. But we can only crash on abort_with_payload once, so that + // This will overwrite the abort_with_payload information in the dictionary + // already. But we can only crash on abort_with_payload once, so that vogelsgesang wrote: My editor auto-formats the whole file on save. This tends to be rather useful in other projects, but apparently not in LLVM https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
@@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public StackFrameRecognizer { public: LibCXXFrameRecognizer() - : m_hidden_function_regex( -R"(^std::__1::(__function.*::operator\(\)|__invoke))" -R"((\[.*\])?)"// ABI tag. -R"(( const)?$)"), // const. + : m_hidden_regex{ +// internal implementation details of std::function +//std::__1::__function::__alloc_func, void ()>::operator()[abi:ne20] +//std::__1::__function::__func, void ()>::operator() +//std::__1::__function::__value_func::operator()[abi:ne20]() const +RegularExpression{"" + R"(^std::__[0-9]*::)" // Namespace. + R"(__function::.*::operator\(\))" + R"((\[.*\])?)"// ABI tag. + R"(( const)?$)"}, // const. +// internal implementation details of std::invoke +// std::__1::__invoke[abi:ne20] +RegularExpression{ + R"(^std::__[0-9]*::)" // Namespace. + R"(__invoke)" vogelsgesang wrote: right. I posted this comment before I saw your fix on `main`. By now, the commit contains `^std::__[^:]*::* https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Extend frame recognizers to hide frames from backtraces (PR #104523)
vogelsgesang wrote: I updated https://github.com/llvm/llvm-project/pull/105695 and locally verified that it now fixes the test case for libc++ ABI v2 https://github.com/llvm/llvm-project/pull/104523 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From e90463e8967c2019e220b063ed4ce73cd0172bf3 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/4] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index 1e4a2cbb1133f7..6d446a099efc78 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From e90463e8967c2019e220b063ed4ce73cd0172bf3 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/3] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index 1e4a2cbb1133f7..6d446a099efc78 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From e90463e8967c2019e220b063ed4ce73cd0172bf3 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/3] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index 1e4a2cbb1133f7..6d446a099efc78 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang edited https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Extend frame recognizers to hide frames from backtraces (PR #104523)
vogelsgesang wrote: Would be interesting if this is fixed by #105695. How can I run the test cases against libc++'s unstable ABI locally? https://github.com/llvm/llvm-project/pull/104523 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From e90463e8967c2019e220b063ed4ce73cd0172bf3 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/4] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index 1e4a2cbb1133f7..6d446a099efc78 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From 19b4370c240cfcf4a57a5c38a64c8ba933d8102c Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/5] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index c60200ab186d09..3665e1a4c77e55 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From 19b4370c240cfcf4a57a5c38a64c8ba933d8102c Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/4] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index c60200ab186d09..3665e1a4c77e55 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From 19b4370c240cfcf4a57a5c38a64c8ba933d8102c Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/4] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index c60200ab186d09..3665e1a4c77e55 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From 19b4370c240cfcf4a57a5c38a64c8ba933d8102c Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/4] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index c60200ab186d09..3665e1a4c77e55 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From 19b4370c240cfcf4a57a5c38a64c8ba933d8102c Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/4] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index c60200ab186d09..3665e1a4c77e55 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang edited https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang edited https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
@@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public StackFrameRecognizer { public: LibCXXFrameRecognizer() - : m_hidden_function_regex( -R"(^std::__1::(__function.*::operator\(\)|__invoke))" -R"((\[.*\])?)"// ABI tag. -R"(( const)?$)"), // const. + : m_hidden_regex{ +// internal implementation details of std::function +//std::__1::__function::__alloc_func, void ()>::operator()[abi:ne20] +//std::__1::__function::__func, void ()>::operator() +//std::__1::__function::__value_func::operator()[abi:ne20]() const +RegularExpression{"" + R"(^std::__[0-9]*::)" // Namespace. + R"(__function::.*::operator\(\))" + R"((\[.*\])?)"// ABI tag. + R"(( const)?$)"}, // const. +// internal implementation details of std::invoke +// std::__1::__invoke[abi:ne20] +RegularExpression{ + R"(^std::__[0-9]*::)" // Namespace. + R"(__invoke)" vogelsgesang wrote: I would like to defer switching to `^std::__[0-9]*::__.*` in a follow-up commit, if that's fine by you. I am pretty sure that this commit here works without unintended side effects, but I am not sure if `^std::__[0-9]*::__.*` would regress debugability in unforeseen ways https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
@@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; vogelsgesang wrote: I don't have direct push-access and piggy-backing it in this PR is less effort for me https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
@@ -145,6 +167,17 @@ StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) { if (!entry.module_regexp->Execute(module_name.GetStringRef())) continue; +ConstString function_name = [&]() { + switch (entry.mangling_preference) { + case Mangled::ePreferMangled: +return function_name_mangled; + case Mangled::ePreferDemangled: +return function_name_demangled; + case Mangled::ePreferDemangledWithoutArguments: +return function_name_noargs; + } +}(); vogelsgesang wrote: > @vogelsgesang I closed my PR, feel free to copy&paste what you find useful. I did copy over: * the improved comments in `StackFrameRecognizer.h` * the printing improvements to `frame recognizer list` (but I am using a slightly different format) However, I did not change the `VerboseTrapFrameRecognizer` and `AssertFrameRecognizer` to use the mangled names. I will leave this for a follow-up commit. https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From 19b4370c240cfcf4a57a5c38a64c8ba933d8102c Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/4] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index c60200ab186d09..3665e1a4c77e55 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
@@ -145,6 +167,17 @@ StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) { if (!entry.module_regexp->Execute(module_name.GetStringRef())) continue; +ConstString function_name = [&]() { + switch (entry.mangling_preference) { + case Mangled::ePreferMangled: +return function_name_mangled; + case Mangled::ePreferDemangled: +return function_name_demangled; + case Mangled::ePreferDemangledWithoutArguments: +return function_name_noargs; + } +}(); vogelsgesang wrote: > The demangling gets chached anyway (in the Mangled class). So wouldn't worry > about it ah, great! I didn't know this. I removed the additional caching from `StackFrameRecognizer` again https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From 19b4370c240cfcf4a57a5c38a64c8ba933d8102c Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH 1/3] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 8 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 175 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 2f5c5caa6a4561..fe25dbbde745d1 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,12 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation = 0; + std::unordered_set m_used_manglings; }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index c60200ab186d09..3665e1a4c77e55 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public Sta
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
@@ -145,6 +167,17 @@ StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) { if (!entry.module_regexp->Execute(module_name.GetStringRef())) continue; +ConstString function_name = [&]() { + switch (entry.mangling_preference) { + case Mangled::ePreferMangled: +return function_name_mangled; + case Mangled::ePreferDemangled: +return function_name_demangled; + case Mangled::ePreferDemangledWithoutArguments: +return function_name_noargs; + } +}(); vogelsgesang wrote: By the way: I don't think I will be merging this part of my commit in the end. https://github.com/llvm/llvm-project/pull/105756 is very similar, and I think I will just rebase on it, after it got merged https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
@@ -145,6 +167,17 @@ StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) { if (!entry.module_regexp->Execute(module_name.GetStringRef())) continue; +ConstString function_name = [&]() { + switch (entry.mangling_preference) { + case Mangled::ePreferMangled: +return function_name_mangled; + case Mangled::ePreferDemangled: +return function_name_demangled; + case Mangled::ePreferDemangledWithoutArguments: +return function_name_noargs; + } +}(); vogelsgesang wrote: I wasn't sure about performance here. The code previously computed the demanded name only once and then checked against all frame recognizers. I am not sure how expensive it is to demangle a name https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Support frame recognizer regexp on mangled names. (PR #105756)
https://github.com/vogelsgesang edited https://github.com/llvm/llvm-project/pull/105756 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Support frame recognizer regexp on mangled names. (PR #105756)
https://github.com/vogelsgesang edited https://github.com/llvm/llvm-project/pull/105756 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Support frame recognizer regexp on mangled names. (PR #105756)
@@ -92,11 +95,13 @@ void StackFrameRecognizerManager::ForEach( symbol_name = entry.symbol_regexp->GetText().str(); callback(entry.recognizer_id, entry.recognizer->GetName(), module_name, - llvm::ArrayRef(ConstString(symbol_name)), true); + llvm::ArrayRef(ConstString(symbol_name)), entry.symbol_mangling, + true); } else { callback(entry.recognizer_id, entry.recognizer->GetName(), - entry.module.GetCString(), entry.symbols, false); + entry.module.GetCString(), entry.symbols, entry.symbol_mangling, + false); } } } vogelsgesang wrote: Feel free to copy-paste / adjust whichever code from #105695 which you might find useful. I will rebase that commit later on, after your changes landed. (I cannot land #105695 before #104523 gets re-applied, anyway) https://github.com/llvm/llvm-project/pull/105756 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Support frame recognizer regexp on mangled names. (PR #105756)
@@ -92,11 +95,13 @@ void StackFrameRecognizerManager::ForEach( symbol_name = entry.symbol_regexp->GetText().str(); callback(entry.recognizer_id, entry.recognizer->GetName(), module_name, - llvm::ArrayRef(ConstString(symbol_name)), true); + llvm::ArrayRef(ConstString(symbol_name)), entry.symbol_mangling, + true); } else { callback(entry.recognizer_id, entry.recognizer->GetName(), - entry.module.GetCString(), entry.symbols, false); + entry.module.GetCString(), entry.symbols, entry.symbol_mangling, + false); } } } vogelsgesang wrote: afaict, this code is incomplete. The matching in `GetRecognizerForFrame` also needs to be adjusted. In https://github.com/llvm/llvm-project/pull/105695, you can find an implementation of pretty much the same idea. However, I implemented only `GetRecognizerForFrame` and skipped, e.g., `ForEach` https://github.com/llvm/llvm-project/pull/105756 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
@@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public StackFrameRecognizer { public: LibCXXFrameRecognizer() - : m_hidden_function_regex( -R"(^std::__1::(__function.*::operator\(\)|__invoke))" -R"((\[.*\])?)"// ABI tag. -R"(( const)?$)"), // const. + : m_hidden_regex{ +// internal implementation details of std::function +//std::__1::__function::__alloc_func, void ()>::operator()[abi:ne20] +//std::__1::__function::__func, void ()>::operator() +//std::__1::__function::__value_func::operator()[abi:ne20]() const +RegularExpression{"" + R"(^std::__[0-9]*::)" // Namespace. + R"(__function::.*::operator\(\))" + R"((\[.*\])?)"// ABI tag. + R"(( const)?$)"}, // const. +// internal implementation details of std::invoke +// std::__1::__invoke[abi:ne20] +RegularExpression{ + R"(^std::__[0-9]*::)" // Namespace. + R"(__invoke)" vogelsgesang wrote: I wonder if we should simply hide everything starting with `^std::__[0-9]*::__.*`. Or are there any `__` functions in libc++ which are not implementation details and should be shown in stacktraces by default? https://github.com/llvm/llvm-project/pull/105695 ___ 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 dialog when executable is not found (PR #104711)
vogelsgesang wrote: Looks good to me! Thanks again for fixing this! https://github.com/llvm/llvm-project/pull/104711 ___ 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 dialog when executable is not found (PR #104711)
https://github.com/vogelsgesang approved this pull request. https://github.com/llvm/llvm-project/pull/104711 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105695 >From c7cc7e9eed1ef4b95cabec5f662ebe10607b178e Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 9 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 31 .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 176 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 8acebc12c4b1dc..585f0b0bb59009 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,13 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation; + std::unordered_set m_used_manglings; + }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index c60200ab186d09..3665e1a4c77e55 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -7,6 +7,7 @@ //===--===// #include +#include #include @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0; /// A frame recognizer that is installed to hide libc++ implementation /// details from the backtrace. class LibCXXFrameRecognizer : public StackFrameRecognizer { - RegularExpression m_hidden_function_regex; + std::array m_hidden_regex; RecognizedStackFrameSP m_hidden_frame; struct LibCXXHiddenFrame : public RecognizedStackFrame { @@ -53,10 +54,32 @@ class LibCXXFrameRecognizer : public StackFram
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
vogelsgesang wrote: @mordante @ldionne FYI. Would be interested which other functions come to mind that should be hidden. See https://github.com/llvm/llvm-project/pull/105457#issuecomment-226404 for screenshots of how this looks from a user's perspective https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Enabling instruction breakpoint support to lldb-dap. (PR #105278)
@@ -4078,6 +4255,9 @@ void RegisterRequestCallbacks() { g_dap.RegisterRequestCallback("threads", request_threads); g_dap.RegisterRequestCallback("variables", request_variables); g_dap.RegisterRequestCallback("disassemble", request_disassemble); + // Instruction breapoint request vogelsgesang wrote: I don't really know about those differences on the gdb protocol. I was only reading https://microsoft.github.io/debug-adapter-protocol/specification#Requests_SetInstructionBreakpoints > When an instruction breakpoint is hit, a stopped event (with reason > `instruction breakpoint`) is generated. https://github.com/llvm/llvm-project/pull/105278 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang edited https://github.com/llvm/llvm-project/pull/105695 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add frame recognizers for libc++ `std::invoke` (PR #105695)
https://github.com/vogelsgesang created https://github.com/llvm/llvm-project/pull/105695 With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. >From 18365311d0cee76bced3ba26d1ed08d9f5c6cb28 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Thu, 22 Aug 2024 10:50:13 + Subject: [PATCH] [lldb-dap] Add frame recognizers for libc++ `std::invoke` With this commit, we also hide the implementation details of `std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more regular expressions. The regular expression passed into the `AddRecognizer` became problematic, as it was evaluated on the demangled name. Those names also included result types for C++ symbols. For `std::__invoke` the return type is a huge `decltype(...)`, making the regular expresison really hard to write. Instead, I added support for `AddRecognizer` to match on the demangled names without result type and argument types. By hiding the implementation details of `invoke`, also the back traces for `std::function` become even nicer, because `std::function` is using `__invoke` internally. --- .../lldb/Target/StackFrameRecognizer.h| 9 +++- lldb/source/Commands/Options.td | 2 +- .../CPlusPlus/CPPLanguageRuntime.cpp | 48 ++- lldb/source/Target/StackFrameRecognizer.cpp | 41 ++-- .../TestStdFunctionRecognizer.py | 21 +++- .../lang/cpp/std-invoke-recognizer/Makefile | 5 ++ .../TestStdInvokeRecognizer.py| 28 +++ .../lang/cpp/std-invoke-recognizer/main.cpp | 40 8 files changed, 173 insertions(+), 21 deletions(-) create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py create mode 100644 lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h index 8acebc12c4b1dc..585f0b0bb59009 100644 --- a/lldb/include/lldb/Target/StackFrameRecognizer.h +++ b/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -107,12 +107,14 @@ class StackFrameRecognizerManager { public: void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, ConstString module, llvm::ArrayRef symbols, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, lldb::RegularExpressionSP module, lldb::RegularExpressionSP symbol, - bool first_instruction_only = true); + bool first_instruction_only = true, + Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled); void ForEach(std::function< void(uint32_t recognizer_id, std::string recognizer_name, @@ -143,10 +145,13 @@ class StackFrameRecognizerManager { std::vector symbols; lldb::RegularExpressionSP symbol_regexp; bool first_instruction_only; +Mangled::NamePreference mangling_preference; }; std::deque m_recognizers; uint16_t m_generation; + std::unordered_set m_used_manglings; + }; /// \class ValueObjectRecognizerSynthesizedValue diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9c4dbed6939ba9..df906e9d7c808f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1049,7 +1049,7 @@ let Command = "thread backtrace" in { def thread_backtrace_extended : Option<"extended", "e">, Group<1>, Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>, - Desc<"Filter out frames according to installed frame recognizers">; + Desc<"Do not filter out frames according to installed frame recognizers">; } let Command = "thread step scope" in { diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index c60200ab186d09..3665e1a4c77e55 100644 --- a/lldb/sourc
[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)
@@ -0,0 +1,40 @@ +""" +Test lldb-dap locations request +""" + + +import dap_server +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import lldbdap_testcase +import os + + +class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase): +@skipIfWindows vogelsgesang wrote: @walter-erquinigo based on https://github.com/llvm/llvm-project/pull/105604, it seems that all DAP tests are in fact disabled for Windows. Should I reintroduce the `SkipIfWindows`? https://github.com/llvm/llvm-project/pull/102928 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)
vogelsgesang wrote: > This LGTM considering that the screenshot looks right and this passes all the > tests. Thanks! I assume you still want me to wait for @clayborg's review before merging? https://github.com/llvm/llvm-project/pull/102928 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)
vogelsgesang wrote: > I'll explain what I do [...] Thanks for that context! I don't currently have a LSP in mind. Let's see which UI VS-Code will be providing for this (if any). I hope it will not conflict with your existing UI https://github.com/llvm/llvm-project/pull/102928 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)
vogelsgesang wrote: > @vogelsgesang , can you show a screenshot of the variables pane after this > change? I want to make sure that simple types, like ints, are not displayed > as having children. **With this commit (and also with the changes from #104589)** https://github.com/user-attachments/assets/862b301c-6321-47dc-9243-bb27447b093b";> Current `main` https://github.com/user-attachments/assets/a6102469-a41a-4b0d-873a-ce8a1fee5b74";> As you can see, there are no differences re the absence / presence of the "expandable chevron" next to the variables. That being said, I do find it a bit surprising that function pointers apparently return `true` for `MightHaveChildren` https://github.com/llvm/llvm-project/pull/102928 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Implement value locations for function pointers (PR #104589)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/104589 >From 5bdcb821527bf67eead6c42825ea6e559ec749c3 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Sat, 10 Aug 2024 23:59:55 + Subject: [PATCH 1/3] [lldb-dap] Implement declaration locations This commit implements support for the "declaration location" recently added by microsoft/debug-adapter-protocol#494 to the debug adapter protocol. For the `declarationLocationReference` we need a variable ID similar to the the `variablesReference`. I decided to simply reuse the `variablesReference` here and renamed `Variables::expandable_variables` and friends accordingly. Given that almost all variables have a declaration location, we now assign those variable ids to all variables. While `declarationLocationReference` effectively supersedes `$__lldb_extensions.declaration`, I did not remove this extension, yet, since I assume that there are some closed-source extensions which rely on it. I tested this against VS-Code Insiders. However, VS-Code Insiders currently only supports `valueLoctionReference` and not `declarationLocationReference`, yet. Locally, I hence published the declaration locations as value locations, and VS Code Insiders navigated to the expected places. Looking forward to proper VS Code support for `declarationLocationReference`. --- .../test/tools/lldb-dap/dap_server.py | 11 ++ .../API/tools/lldb-dap/locations/Makefile | 3 + .../lldb-dap/locations/TestDAP_locations.py | 40 + lldb/test/API/tools/lldb-dap/locations/main.c | 5 + lldb/tools/lldb-dap/DAP.cpp | 17 +- lldb/tools/lldb-dap/DAP.h | 10 +- lldb/tools/lldb-dap/JSONUtils.cpp | 125 --- lldb/tools/lldb-dap/JSONUtils.h | 31 ++-- lldb/tools/lldb-dap/lldb-dap.cpp | 146 +++--- 9 files changed, 286 insertions(+), 102 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index 874383a13e2bb6..01ff79ee430902 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py @@ -1083,6 +1083,17 @@ def request_setVariable(self, containingVarRef, name, value, id=None): } return self.send_recv(command_dict) +def request_locations(self, locationReference): +args_dict = { +"locationReference": locationReference, +} +command_dict = { +"command": "locations", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + def request_testGetTargetBreakpoints(self): """A request packet used in the LLDB test suite to get all currently set breakpoint infos for all breakpoints currently set in the diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile b/lldb/test/API/tools/lldb-dap/locations/Makefile new file mode 100644 index 00..10495940055b63 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/locations/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py new file mode 100644 index 00..76d938d3908492 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py @@ -0,0 +1,40 @@ +""" +Test lldb-dap locations request +""" + + +import dap_server +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import lldbdap_testcase +import os + + +class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase): +@skipIfWindows +def test_locations(self): +""" +Tests the 'locations' request. +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.c" +self.source_path = os.path.join(os.getcwd(), source) +self.set_source_breakpoints( +source, +[line_number(source, "// BREAK HERE")], +) +self.continue_to_next_stop() + +locals = {l["name"]: l for l in self.dap_server.get_local_variables()} + +# var1 has a declarationLocation but no valueLocation +self.assertIn("declarationLocationReference", locals["var1"].keys()) +self.assertNotIn("valueLocationReference", locals["var1"].keys()) +loc_var1 = self.dap_server.request_locations( +locals["var1"]["declarationLocationReference"] +) +self.assertTrue(loc_var1["success"]) +sel
[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)
vogelsgesang wrote: > @vogelsgesang , the $__lldb_extensions.declaration is used by the Mojo > extension. Once this change gets it, I'll update the Mojo extension to use > the new declaration info and remove $__lldb_extensions.declaration. Is that extension's source code available? I wonder how you are currently using the declarationLocation in your frontend, and if your extension is based on `lldb-dap`. If so, would it make sense to upstream your UI integration to `lldb-dap`? Or maybe even to VS-Code itself? https://github.com/llvm/llvm-project/pull/102928 ___ 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 dialog when executable is not found (PR #104711)
@@ -14,10 +14,52 @@ export class LLDBDapDescriptorFactory this.lldbDapOptions = lldbDapOptions; } + public static async validateDebugAdapterPath(pathUri: vscode.Uri) { +try { + const fileStats = await vscode.workspace.fs.stat(pathUri); + if (!(fileStats.type & vscode.FileType.File)) { +this.showErrorMessage(pathUri.path); + } +} catch (err) { + this.showErrorMessage(pathUri.path); +} + } + async createDebugAdapterDescriptor( session: vscode.DebugSession, executable: vscode.DebugAdapterExecutable | undefined, ): Promise { +const config = vscode.workspace.getConfiguration( + "lldb-dap", + session.workspaceFolder, +); +const customPath = config.get("executable-path"); +const path: string = customPath ? customPath : executable!!.command; + +await LLDBDapDescriptorFactory.validateDebugAdapterPath( + vscode.Uri.file(path), +); return this.lldbDapOptions.createDapExecutableCommand(session, executable); } + + /** + * Shows a message box when the debug adapter's path is not found + */ + private static showErrorMessage(path: string) { +const openSettingsAction = "Open Settings"; +vscode.window + .showErrorMessage( +`Debug adapter path: ${path} is not a valid file`, +{ modal: false }, vogelsgesang wrote: we aren't using modals in the current code. I am just proposing to be less epxlicit here. And not set "modal: false" as this is the default in the VS Code API, anyway https://github.com/llvm/llvm-project/pull/104711 ___ 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 dialog when executable is not found (PR #104711)
@@ -14,10 +14,52 @@ export class LLDBDapDescriptorFactory this.lldbDapOptions = lldbDapOptions; } + public static async validateDebugAdapterPath(pathUri: vscode.Uri) { +try { + const fileStats = await vscode.workspace.fs.stat(pathUri); + if (!(fileStats.type & vscode.FileType.File)) { +this.showErrorMessage(pathUri.path); + } +} catch (err) { + this.showErrorMessage(pathUri.path); +} + } + async createDebugAdapterDescriptor( session: vscode.DebugSession, executable: vscode.DebugAdapterExecutable | undefined, ): Promise { +const config = vscode.workspace.getConfiguration( + "lldb-dap", + session.workspaceFolder, +); +const customPath = config.get("executable-path"); +const path: string = customPath ? customPath : executable!!.command; + +await LLDBDapDescriptorFactory.validateDebugAdapterPath( + vscode.Uri.file(path), +); return this.lldbDapOptions.createDapExecutableCommand(session, executable); } + + /** + * Shows a message box when the debug adapter's path is not found + */ + private static showErrorMessage(path: string) { vogelsgesang wrote: ```suggestion private static showLLdbDapNotFoundMessage(path: string) { ``` https://github.com/llvm/llvm-project/pull/104711 ___ 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 dialog when executable is not found (PR #104711)
@@ -14,10 +14,52 @@ export class LLDBDapDescriptorFactory this.lldbDapOptions = lldbDapOptions; } + public static async validateDebugAdapterPath(pathUri: vscode.Uri) { +try { + const fileStats = await vscode.workspace.fs.stat(pathUri); + if (!(fileStats.type & vscode.FileType.File)) { +this.showErrorMessage(pathUri.path); + } +} catch (err) { + this.showErrorMessage(pathUri.path); +} + } + async createDebugAdapterDescriptor( session: vscode.DebugSession, executable: vscode.DebugAdapterExecutable | undefined, ): Promise { +const config = vscode.workspace.getConfiguration( + "lldb-dap", + session.workspaceFolder, +); +const customPath = config.get("executable-path"); +const path: string = customPath ? customPath : executable!!.command; + +await LLDBDapDescriptorFactory.validateDebugAdapterPath( + vscode.Uri.file(path), +); return this.lldbDapOptions.createDapExecutableCommand(session, executable); } + + /** + * Shows a message box when the debug adapter's path is not found + */ + private static showErrorMessage(path: string) { +const openSettingsAction = "Open Settings"; +vscode.window + .showErrorMessage( +`Debug adapter path: ${path} is not a valid file`, +{ modal: false }, +openSettingsAction, + ) + .then((callBackValue) => { +if (openSettingsAction === callBackValue) { + vscode.commands.executeCommand( +"workbench.action.openSettings", +"lldb-dap.executable-path", + ); +} + }); + } vogelsgesang wrote: instead of `.then()` we should be able to use an `async` function here ```suggestion private static async showErrorMessage(path: string) { const openSettingsAction = "Open Settings"; const selection = await vscode.window .showErrorMessage( `Debug adapter path: ${path} is not a valid file`, { modal: false }, openSettingsAction, ); if (openSettingsAction === callBackValue) { vscode.commands.executeCommand( "workbench.action.openSettings", "lldb-dap.executable-path", ); } } ``` https://github.com/llvm/llvm-project/pull/104711 ___ 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 dialog when executable is not found (PR #104711)
@@ -14,10 +14,52 @@ export class LLDBDapDescriptorFactory this.lldbDapOptions = lldbDapOptions; } + public static async validateDebugAdapterPath(pathUri: vscode.Uri) { +try { + const fileStats = await vscode.workspace.fs.stat(pathUri); + if (!(fileStats.type & vscode.FileType.File)) { +this.showErrorMessage(pathUri.path); + } +} catch (err) { + this.showErrorMessage(pathUri.path); +} + } + async createDebugAdapterDescriptor( session: vscode.DebugSession, executable: vscode.DebugAdapterExecutable | undefined, ): Promise { +const config = vscode.workspace.getConfiguration( + "lldb-dap", + session.workspaceFolder, +); +const customPath = config.get("executable-path"); +const path: string = customPath ? customPath : executable!!.command; + +await LLDBDapDescriptorFactory.validateDebugAdapterPath( + vscode.Uri.file(path), +); return this.lldbDapOptions.createDapExecutableCommand(session, executable); } + + /** + * Shows a message box when the debug adapter's path is not found + */ + private static showErrorMessage(path: string) { +const openSettingsAction = "Open Settings"; +vscode.window + .showErrorMessage( +`Debug adapter path: ${path} is not a valid file`, +{ modal: false }, vogelsgesang wrote: Afaik, non-modal is the default anyway? ```suggestion ``` https://github.com/llvm/llvm-project/pull/104711 ___ 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 dialog when executable is not found (PR #104711)
https://github.com/vogelsgesang approved this pull request. Looks good to me! Thanks for this amazing usability improvement! If this would have existed the first time I tried this extension, it would have saved me a lot of time https://github.com/llvm/llvm-project/pull/104711 ___ 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 dialog when executable is not found (PR #104711)
https://github.com/vogelsgesang edited https://github.com/llvm/llvm-project/pull/104711 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/102928 >From 5bdcb821527bf67eead6c42825ea6e559ec749c3 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Sat, 10 Aug 2024 23:59:55 + Subject: [PATCH 1/2] [lldb-dap] Implement declaration locations This commit implements support for the "declaration location" recently added by microsoft/debug-adapter-protocol#494 to the debug adapter protocol. For the `declarationLocationReference` we need a variable ID similar to the the `variablesReference`. I decided to simply reuse the `variablesReference` here and renamed `Variables::expandable_variables` and friends accordingly. Given that almost all variables have a declaration location, we now assign those variable ids to all variables. While `declarationLocationReference` effectively supersedes `$__lldb_extensions.declaration`, I did not remove this extension, yet, since I assume that there are some closed-source extensions which rely on it. I tested this against VS-Code Insiders. However, VS-Code Insiders currently only supports `valueLoctionReference` and not `declarationLocationReference`, yet. Locally, I hence published the declaration locations as value locations, and VS Code Insiders navigated to the expected places. Looking forward to proper VS Code support for `declarationLocationReference`. --- .../test/tools/lldb-dap/dap_server.py | 11 ++ .../API/tools/lldb-dap/locations/Makefile | 3 + .../lldb-dap/locations/TestDAP_locations.py | 40 + lldb/test/API/tools/lldb-dap/locations/main.c | 5 + lldb/tools/lldb-dap/DAP.cpp | 17 +- lldb/tools/lldb-dap/DAP.h | 10 +- lldb/tools/lldb-dap/JSONUtils.cpp | 125 --- lldb/tools/lldb-dap/JSONUtils.h | 31 ++-- lldb/tools/lldb-dap/lldb-dap.cpp | 146 +++--- 9 files changed, 286 insertions(+), 102 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index 874383a13e2bb6..01ff79ee430902 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py @@ -1083,6 +1083,17 @@ def request_setVariable(self, containingVarRef, name, value, id=None): } return self.send_recv(command_dict) +def request_locations(self, locationReference): +args_dict = { +"locationReference": locationReference, +} +command_dict = { +"command": "locations", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + def request_testGetTargetBreakpoints(self): """A request packet used in the LLDB test suite to get all currently set breakpoint infos for all breakpoints currently set in the diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile b/lldb/test/API/tools/lldb-dap/locations/Makefile new file mode 100644 index 00..10495940055b63 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/locations/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py new file mode 100644 index 00..76d938d3908492 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py @@ -0,0 +1,40 @@ +""" +Test lldb-dap locations request +""" + + +import dap_server +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import lldbdap_testcase +import os + + +class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase): +@skipIfWindows +def test_locations(self): +""" +Tests the 'locations' request. +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.c" +self.source_path = os.path.join(os.getcwd(), source) +self.set_source_breakpoints( +source, +[line_number(source, "// BREAK HERE")], +) +self.continue_to_next_stop() + +locals = {l["name"]: l for l in self.dap_server.get_local_variables()} + +# var1 has a declarationLocation but no valueLocation +self.assertIn("declarationLocationReference", locals["var1"].keys()) +self.assertNotIn("valueLocationReference", locals["var1"].keys()) +loc_var1 = self.dap_server.request_locations( +locals["var1"]["declarationLocationReference"] +) +self.assertTrue(loc_var1["success"]) +sel
[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)
@@ -0,0 +1,40 @@ +""" +Test lldb-dap locations request +""" + + +import dap_server +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import lldbdap_testcase +import os + + +class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase): +@skipIfWindows vogelsgesang wrote: copy-paste error :/ https://github.com/llvm/llvm-project/pull/102928 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Enabling instruction breakpoint support to lldb-dap. (PR #105278)
@@ -4078,6 +4255,9 @@ void RegisterRequestCallbacks() { g_dap.RegisterRequestCallback("threads", request_threads); g_dap.RegisterRequestCallback("variables", request_variables); g_dap.RegisterRequestCallback("disassemble", request_disassemble); + // Instruction breapoint request vogelsgesang wrote: we also need to update the stopped event to use `reason: instruction breakpoint` instead of `reason: breakpoint` in case we hit one of those breakpoints https://github.com/llvm/llvm-project/pull/105278 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Enabling instruction breakpoint support to lldb-dap. (PR #105278)
@@ -4046,6 +4048,181 @@ void request__testGetTargetBreakpoints(const llvm::json::Object &request) { g_dap.SendJSON(llvm::json::Value(std::move(response))); } +// SetInstructionBreakpoints request; value of command field is +// 'setInstructionBreakpoints'. Replaces all existing instruction breakpoints. +// Typically, instruction breakpoints would be set from a disassembly window. To +// clear all instruction breakpoints, specify an empty array. When an +// instruction breakpoint is hit, a `stopped` event (with reason `instruction +// breakpoint`) is generated. Clients should only call this request if the +// corresponding capability `supportsInstructionBreakpoints` is true. interface +// SetInstructionBreakpointsRequest extends Request { +// command: 'setInstructionBreakpoints'; +// arguments: SetInstructionBreakpointsArguments; +// } +// interface SetInstructionBreakpointsArguments { +// The instruction references of the breakpoints +// breakpoints: InstructionBreakpoint[]; +// } +// "InstructionBreakpoint ": { +// "type": "object", +// "description": "Properties of a breakpoint passed to the +// setInstructionBreakpoints request.", "properties": { +// "instructionReference": { +// "type": "string", +// "description": "The instruction reference of the breakpoint. +// This should be a memory or instruction pointer reference from an +// EvaluateResponse, Variable, StackFrame, GotoTarget, or Breakpoint." +// }, +// "offset": { +// "type": "number", +// "description": "The offset from the instruction reference. +// This can be negative." +// }, +// "condition": { +// "type": "string", +// "description": "An expression for conditional breakpoints. +// It is only honored by a debug adapter if the corresponding capability +// supportsConditionalBreakpoints` is true." +// }, +// "hitCondition": { +// "type": "string", +// "description": "An 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." +// }, +// } +// interface SetInstructionBreakpointsResponse extends Response { +// body: { +// Information about the breakpoints. The array elements correspond to the +// elements of the `breakpoints` array. +// breakpoints: Breakpoint[]; +// }; +// } vogelsgesang wrote: we usually copy the JSON schema documentation into the comments, not the TypeScript interface. See https://github.com/microsoft/debug-adapter-protocol/blob/main/debugAdapterProtocol.json https://github.com/llvm/llvm-project/pull/105278 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Implement value locations for function pointers (PR #104589)
https://github.com/vogelsgesang edited https://github.com/llvm/llvm-project/pull/104589 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Implement value locations for function pointers (PR #104589)
@@ -0,0 +1,81 @@ +""" +Test lldb-dap locations request +""" + + +import dap_server +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import lldbdap_testcase +import os + + +class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase): +@skipIfWindows vogelsgesang wrote: this was a copy-paste mistake :/ https://github.com/llvm/llvm-project/pull/104589 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Mark hidden frames as "subtle" (PR #105457)
vogelsgesang wrote: @petrhosek this commit builds on top of #104523 and relies on the frame recognizer introduced as part of it. As soon as [your proposed solutions](https://github.com/llvm/llvm-project/pull/104523#issuecomment-2303287484) was addressed, the `subtleFrames` test case should also be passing. In case this turns out to be not the case, please ping me again https://github.com/llvm/llvm-project/pull/105457 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Implement value locations for function pointers (PR #104589)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/104589 >From 5bdcb821527bf67eead6c42825ea6e559ec749c3 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Sat, 10 Aug 2024 23:59:55 + Subject: [PATCH 1/2] [lldb-dap] Implement declaration locations This commit implements support for the "declaration location" recently added by microsoft/debug-adapter-protocol#494 to the debug adapter protocol. For the `declarationLocationReference` we need a variable ID similar to the the `variablesReference`. I decided to simply reuse the `variablesReference` here and renamed `Variables::expandable_variables` and friends accordingly. Given that almost all variables have a declaration location, we now assign those variable ids to all variables. While `declarationLocationReference` effectively supersedes `$__lldb_extensions.declaration`, I did not remove this extension, yet, since I assume that there are some closed-source extensions which rely on it. I tested this against VS-Code Insiders. However, VS-Code Insiders currently only supports `valueLoctionReference` and not `declarationLocationReference`, yet. Locally, I hence published the declaration locations as value locations, and VS Code Insiders navigated to the expected places. Looking forward to proper VS Code support for `declarationLocationReference`. --- .../test/tools/lldb-dap/dap_server.py | 11 ++ .../API/tools/lldb-dap/locations/Makefile | 3 + .../lldb-dap/locations/TestDAP_locations.py | 40 + lldb/test/API/tools/lldb-dap/locations/main.c | 5 + lldb/tools/lldb-dap/DAP.cpp | 17 +- lldb/tools/lldb-dap/DAP.h | 10 +- lldb/tools/lldb-dap/JSONUtils.cpp | 125 --- lldb/tools/lldb-dap/JSONUtils.h | 31 ++-- lldb/tools/lldb-dap/lldb-dap.cpp | 146 +++--- 9 files changed, 286 insertions(+), 102 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index 874383a13e2bb6..01ff79ee430902 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py @@ -1083,6 +1083,17 @@ def request_setVariable(self, containingVarRef, name, value, id=None): } return self.send_recv(command_dict) +def request_locations(self, locationReference): +args_dict = { +"locationReference": locationReference, +} +command_dict = { +"command": "locations", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + def request_testGetTargetBreakpoints(self): """A request packet used in the LLDB test suite to get all currently set breakpoint infos for all breakpoints currently set in the diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile b/lldb/test/API/tools/lldb-dap/locations/Makefile new file mode 100644 index 00..10495940055b63 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/locations/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py new file mode 100644 index 00..76d938d3908492 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py @@ -0,0 +1,40 @@ +""" +Test lldb-dap locations request +""" + + +import dap_server +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import lldbdap_testcase +import os + + +class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase): +@skipIfWindows +def test_locations(self): +""" +Tests the 'locations' request. +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.c" +self.source_path = os.path.join(os.getcwd(), source) +self.set_source_breakpoints( +source, +[line_number(source, "// BREAK HERE")], +) +self.continue_to_next_stop() + +locals = {l["name"]: l for l in self.dap_server.get_local_variables()} + +# var1 has a declarationLocation but no valueLocation +self.assertIn("declarationLocationReference", locals["var1"].keys()) +self.assertNotIn("valueLocationReference", locals["var1"].keys()) +loc_var1 = self.dap_server.request_locations( +locals["var1"]["declarationLocationReference"] +) +self.assertTrue(loc_var1["success"]) +sel
[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)
https://github.com/vogelsgesang edited https://github.com/llvm/llvm-project/pull/102928 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Provide `declarationLocation` for variables (PR #102928)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/102928 >From 5bdcb821527bf67eead6c42825ea6e559ec749c3 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Sat, 10 Aug 2024 23:59:55 + Subject: [PATCH] [lldb-dap] Implement declaration locations This commit implements support for the "declaration location" recently added by microsoft/debug-adapter-protocol#494 to the debug adapter protocol. For the `declarationLocationReference` we need a variable ID similar to the the `variablesReference`. I decided to simply reuse the `variablesReference` here and renamed `Variables::expandable_variables` and friends accordingly. Given that almost all variables have a declaration location, we now assign those variable ids to all variables. While `declarationLocationReference` effectively supersedes `$__lldb_extensions.declaration`, I did not remove this extension, yet, since I assume that there are some closed-source extensions which rely on it. I tested this against VS-Code Insiders. However, VS-Code Insiders currently only supports `valueLoctionReference` and not `declarationLocationReference`, yet. Locally, I hence published the declaration locations as value locations, and VS Code Insiders navigated to the expected places. Looking forward to proper VS Code support for `declarationLocationReference`. --- .../test/tools/lldb-dap/dap_server.py | 11 ++ .../API/tools/lldb-dap/locations/Makefile | 3 + .../lldb-dap/locations/TestDAP_locations.py | 40 + lldb/test/API/tools/lldb-dap/locations/main.c | 5 + lldb/tools/lldb-dap/DAP.cpp | 17 +- lldb/tools/lldb-dap/DAP.h | 10 +- lldb/tools/lldb-dap/JSONUtils.cpp | 125 --- lldb/tools/lldb-dap/JSONUtils.h | 31 ++-- lldb/tools/lldb-dap/lldb-dap.cpp | 146 +++--- 9 files changed, 286 insertions(+), 102 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index 874383a13e2bb6..01ff79ee430902 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py @@ -1083,6 +1083,17 @@ def request_setVariable(self, containingVarRef, name, value, id=None): } return self.send_recv(command_dict) +def request_locations(self, locationReference): +args_dict = { +"locationReference": locationReference, +} +command_dict = { +"command": "locations", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + def request_testGetTargetBreakpoints(self): """A request packet used in the LLDB test suite to get all currently set breakpoint infos for all breakpoints currently set in the diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile b/lldb/test/API/tools/lldb-dap/locations/Makefile new file mode 100644 index 00..10495940055b63 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/locations/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py new file mode 100644 index 00..76d938d3908492 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py @@ -0,0 +1,40 @@ +""" +Test lldb-dap locations request +""" + + +import dap_server +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import lldbdap_testcase +import os + + +class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase): +@skipIfWindows +def test_locations(self): +""" +Tests the 'locations' request. +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.c" +self.source_path = os.path.join(os.getcwd(), source) +self.set_source_breakpoints( +source, +[line_number(source, "// BREAK HERE")], +) +self.continue_to_next_stop() + +locals = {l["name"]: l for l in self.dap_server.get_local_variables()} + +# var1 has a declarationLocation but no valueLocation +self.assertIn("declarationLocationReference", locals["var1"].keys()) +self.assertNotIn("valueLocationReference", locals["var1"].keys()) +loc_var1 = self.dap_server.request_locations( +locals["var1"]["declarationLocationReference"] +) +self.assertTrue(loc_var1["success"]) +self.as
[Lldb-commits] [lldb] [lldb-dap] Implement `StepGranularity` for "next" and "step-in" (PR #105464)
https://github.com/vogelsgesang closed https://github.com/llvm/llvm-project/pull/105464 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Implement `StepGranularity` for "next" and "step-in" (PR #105464)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105464 >From c4178df5541103388e26343f62e96f8e2a65be86 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Mon, 12 Aug 2024 23:00:45 + Subject: [PATCH 1/3] [lldb-dap] Implement `StepGranularity` for "next" and "step-in" VS Code requests a `granularity` of `instruction` if the assembly view is currently focused. By implementing `StepGranularity`, we can hence properly through assembly code single-step through assembly code. --- .../test/tools/lldb-dap/dap_server.py | 8 ++--- .../test/tools/lldb-dap/lldbdap_testcase.py | 8 ++--- .../API/tools/lldb-dap/step/TestDAP_step.py | 9 ++ lldb/tools/lldb-dap/lldb-dap.cpp | 31 +-- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index a324af57b61df3..87ebc674f61df6 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py @@ -816,17 +816,17 @@ def request_launch( self.wait_for_event(filter=["process", "initialized"]) return response -def request_next(self, threadId): +def request_next(self, threadId, granularity="statement"): if self.exit_status is not None: raise ValueError("request_continue called after process exited") -args_dict = {"threadId": threadId} +args_dict = {"threadId": threadId, "granularity": granularity} command_dict = {"command": "next", "type": "request", "arguments": args_dict} return self.send_recv(command_dict) -def request_stepIn(self, threadId, targetId): +def request_stepIn(self, threadId, targetId, granularity="statement"): if self.exit_status is not None: raise ValueError("request_stepIn called after process exited") -args_dict = {"threadId": threadId, "targetId": targetId} +args_dict = {"threadId": threadId, "targetId": targetId, "granularity": granularity} command_dict = {"command": "stepIn", "type": "request", "arguments": args_dict} return self.send_recv(command_dict) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py index a312a88ebd7e58..3257bd14b16fed 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py @@ -222,14 +222,14 @@ def set_global(self, name, value, id=None): """Set a top level global variable only.""" return self.dap_server.request_setVariable(2, name, str(value), id=id) -def stepIn(self, threadId=None, targetId=None, waitForStop=True): -self.dap_server.request_stepIn(threadId=threadId, targetId=targetId) +def stepIn(self, threadId=None, targetId=None, waitForStop=True, granularity="statement"): +self.dap_server.request_stepIn(threadId=threadId, targetId=targetId, granularity=granularity) if waitForStop: return self.dap_server.wait_for_stopped() return None -def stepOver(self, threadId=None, waitForStop=True): -self.dap_server.request_next(threadId=threadId) +def stepOver(self, threadId=None, waitForStop=True, granularity="statement"): +self.dap_server.request_next(threadId=threadId, granularity=granularity) if waitForStop: return self.dap_server.wait_for_stopped() return None diff --git a/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py b/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py index 8a1bb76340be73..9c8e226827611e 100644 --- a/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py +++ b/lldb/test/API/tools/lldb-dap/step/TestDAP_step.py @@ -68,5 +68,14 @@ def test_step(self): self.assertEqual(x4, x3, "verify step over variable") self.assertGreater(line4, line3, "verify step over line") self.assertEqual(src1, src4, "verify step over source") + +# Step a single assembly instruction. +# Unfortunately, there is no portable way to verify the correct +# stepping behavior here, because the generated assembly code +# depends highly on the compiler, its version, the operating +# system, and many more factors. +self.stepOver(threadId=tid, waitForStop=True, granularity="instruction") +self.stepIn(threadId=tid, waitForStop=True, granularity="instruction") + # only step one thread that is at the breakpoint and stop break diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp inde
[Lldb-commits] [lldb] [lldb-dap] When sending a DAP Output Event break each message into separate lines. (PR #105456)
@@ -311,10 +309,22 @@ void DAP::SendOutput(OutputType o, const llvm::StringRef output) { category = "telemetry"; break; } - body.try_emplace("category", category); - EmplaceSafeString(body, "output", output.str()); - event.try_emplace("body", std::move(body)); - SendJSON(llvm::json::Value(std::move(event))); + + // Send each line of output as an individual event, including the newline if + // present. + ::size_t idx = 0; + do { +::size_t end = output.find('\n', idx); +if (end == llvm::StringRef::npos) + end = output.size() - 1; +llvm::json::Object event(CreateEventObject("output")); +llvm::json::Object body; +body.try_emplace("category", category); +EmplaceSafeString(body, "output", output.slice(idx, end + 1).str()); +event.try_emplace("body", std::move(body)); +SendJSON(llvm::json::Value(std::move(event))); +idx = end + 1; + } while (idx < output.size()); vogelsgesang wrote: Thanks for clarifying! https://github.com/llvm/llvm-project/pull/105456 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Implement `StepGranularity` for "next" and "step-in" (PR #105464)
@@ -3193,7 +3213,11 @@ void request_stackTrace(const llvm::json::Object &request) { // "targetId": { // "type": "integer", // "description": "Optional id of the target to step into." -// } +// }, +// "granularity": { +// "$ref": "#/definitions/SteppingGranularity", +// "description": "Stepping granularity. If no granularity is specified, a +// granularity of `statement` is assumed." // }, vogelsgesang wrote: missing closing `}` https://github.com/llvm/llvm-project/pull/105464 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Mark hidden frames as "subtle" (PR #105457)
vogelsgesang wrote: The included test case should be fine now, afaict https://github.com/llvm/llvm-project/pull/105457 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Mark hidden frames as "subtle" (PR #105457)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105457 >From 36fd54d51e8310d4d03b40019bd96e564f8d1171 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Wed, 21 Aug 2024 00:12:39 + Subject: [PATCH] [lldb-dap] Show hidden frames as "subtle" This commit takes advantage of the recently introduced `SBFrame::IsHidden` to show those hidden frames as "subtle" frames in the UI. E.g., VS Code renders such frames grayed out in the stack trace --- .../lldb-dap/stackTrace/subtleFrames/Makefile | 3 ++ .../subtleFrames/TestDAP_subtleFrames.py | 29 +++ .../lldb-dap/stackTrace/subtleFrames/main.cpp | 13 + lldb/tools/lldb-dap/JSONUtils.cpp | 3 ++ 4 files changed, 48 insertions(+) create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp diff --git a/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile new file mode 100644 index 00..8b20bcb050 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py new file mode 100644 index 00..1e41e841e39bc8 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py @@ -0,0 +1,29 @@ +""" +Test lldb-dap stack trace response +""" + + +import dap_server +from lldbsuite.test.decorators import * + +import lldbdap_testcase +from lldbsuite.test.lldbtest import * + + +class TestDAP_subtleFrames(lldbdap_testcase.DAPTestCaseBase): +@add_test_categories(["libc++"]) +def test_subtleFrames(self): +""" +Internal stack frames (such as the ones used by `std::function`) are marked as "subtle". +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.cpp" +self.set_source_breakpoints(source, [line_number(source, "BREAK HERE")]) +self.continue_to_next_stop() + +frames = self.get_stackFrames() +for f in frames: +if "__function" in f["name"]: +self.assertEqual(f["presentationHint"], "subtle") +self.assertTrue(any(f.get("presentationHint") == "subtle" for f in frames)) diff --git a/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp new file mode 100644 index 00..71944528441e38 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp @@ -0,0 +1,13 @@ +#include +#include + +void greet() { + // BREAK HERE + std::cout << "Hello\n"; +} + +int main() { + std::function func{greet}; + func(); + return 0; +} diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index a8b85f55939e17..c080fd395b7288 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -763,6 +763,9 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame) { object.try_emplace("instructionPointerReference", formatted_addr); } + if (frame.IsArtificial() || frame.IsHidden()) +object.try_emplace("presentationHint", "subtle"); + return llvm::json::Value(std::move(object)); } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Mark hidden frames as "subtle" (PR #105457)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/105457 >From bdd78f79c8eb1a439472c1aa5a1bb25e83494a79 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Wed, 21 Aug 2024 00:12:39 + Subject: [PATCH] [lldb-dap] Show hidden frames as "subtle" This commit takes advantage of the recently introduced `SBFrame::IsHidden` to show those hidden frames as "subtle" frames in the UI. E.g., VS Code renders such frames grayed out in the stack trace --- .../lldb-dap/stackTrace/subtleFrames/Makefile | 3 ++ .../subtleFrames/TestDAP_subtleFrames.py | 29 +++ .../lldb-dap/stackTrace/subtleFrames/main.cpp | 13 + lldb/tools/lldb-dap/JSONUtils.cpp | 3 ++ 4 files changed, 48 insertions(+) create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py create mode 100644 lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp diff --git a/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile new file mode 100644 index 00..a6ae713cf424ff --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py new file mode 100644 index 00..d4b28c35d08df2 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.py @@ -0,0 +1,29 @@ +""" +Test lldb-dap stack trace response +""" + + +import dap_server +from lldbsuite.test.decorators import * +import os + +import lldbdap_testcase +from lldbsuite.test import lldbtest, lldbutil + + +class TestDAP_subtleFrames(lldbdap_testcase.DAPTestCaseBase): +def test_subtleFrames(self): +""" +Test that internal stack frames (such as the ones used by `std::function`) +are marked as "subtle". +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.cpp" +self.set_source_breakpoints(source, [line_number(source, "BREAK HERE")]) +self.continue_to_next_stop() + +backtrace = self.get_stackFrames()[0] +for f in backtrace: +if "__function" in f["name"]: +self.assertEqual(f["presentationHint"], "subtle") diff --git a/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp new file mode 100644 index 00..71944528441e38 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/stackTrace/subtleFrames/main.cpp @@ -0,0 +1,13 @@ +#include +#include + +void greet() { + // BREAK HERE + std::cout << "Hello\n"; +} + +int main() { + std::function func{greet}; + func(); + return 0; +} diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp index a8b85f55939e17..c080fd395b7288 100644 --- a/lldb/tools/lldb-dap/JSONUtils.cpp +++ b/lldb/tools/lldb-dap/JSONUtils.cpp @@ -763,6 +763,9 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame) { object.try_emplace("instructionPointerReference", formatted_addr); } + if (frame.IsArtificial() || frame.IsHidden()) +object.try_emplace("presentationHint", "subtle"); + return llvm::json::Value(std::move(object)); } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Mark hidden frames as "subtle" (PR #105457)
vogelsgesang wrote: > This looks like a nice improvement! Can we add a test for this? Added. Is this the type of test case you had in mind? Also, do I need to do anything in addition? E.g., disable the test case for libstdc++, because the stack frame recognizer only works for libc++? How would I do so? (Not sure yet, if the test case is actually correct. Still waiting for my local build to finish) https://github.com/llvm/llvm-project/pull/105457 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] When sending a DAP Output Event break each message into separate lines. (PR #105456)
@@ -311,10 +309,22 @@ void DAP::SendOutput(OutputType o, const llvm::StringRef output) { category = "telemetry"; break; } - body.try_emplace("category", category); - EmplaceSafeString(body, "output", output.str()); - event.try_emplace("body", std::move(body)); - SendJSON(llvm::json::Value(std::move(event))); + + // Send each line of output as an individual event, including the newline if + // present. + ::size_t idx = 0; + do { +::size_t end = output.find('\n', idx); +if (end == llvm::StringRef::npos) + end = output.size() - 1; +llvm::json::Object event(CreateEventObject("output")); +llvm::json::Object body; +body.try_emplace("category", category); +EmplaceSafeString(body, "output", output.slice(idx, end + 1).str()); +event.try_emplace("body", std::move(body)); +SendJSON(llvm::json::Value(std::move(event))); +idx = end + 1; + } while (idx < output.size()); vogelsgesang wrote: afaict, we still send partial lines without a `\n` in the end as individual output events. Should we instead only send full lines as output events? https://github.com/llvm/llvm-project/pull/105456 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Mark hidden frames as "subtle" (PR #105457)
https://github.com/vogelsgesang edited https://github.com/llvm/llvm-project/pull/105457 ___ 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 disassembled ranges for `disassemble` request (PR #105446)
vogelsgesang wrote: @clayborg I would be interested in your guidance for this PR, given that you previously reviewed a similar change in https://reviews.llvm.org/D140358 I did use `SBFunction` / `SBSymbol` as suggested by you in [this comment](https://reviews.llvm.org/D140358#4027551). I did not know how to address the part ``` // then we need to repeat the search for the next function or symbol. // note there may be bytes between functions or symbols which we can disassemble // by calling _get_instructions_from_memory(...) but we must find the next // symbol or function boundary and get back on track ``` from your comment, though. Is there some API to find the next symbol? Or some API to get a list of symbols, sorted by their start address? I could of course use a brute-force approach, similar to ``` SBAddress addr; while (!addr.GetFunction() && !addr.GetSymbol()) addr = addr.OffsetAddress(1); ``` but that seems a bit wasteful https://github.com/llvm/llvm-project/pull/105446 ___ 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 disassembled ranges for `disassemble` request (PR #105446)
https://github.com/vogelsgesang created https://github.com/llvm/llvm-project/pull/105446 This is a first draft PR which fixes #103021 The main issue was that the `instructionOffset` was handled as a byte offset and not as an instruction offset. This commit also incorporates previous feedback from https://reviews.llvm.org/D140358: With this change, we are using symbols and DWARF debug information to find function boundaries and correctly start disassembling at this address. TODO: * Update test case * Check if we can also support disassembling across functions >From b809f570dd8055e5b899c337ec9ff5110ab94c6e Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Mon, 19 Aug 2024 15:15:22 + Subject: [PATCH] [lldb-dap] Fix disassembled ranges for `disassemble` request TODO: * Update test case * Check if we can also support disassembling across functions Incorporated feedback from https://reviews.llvm.org/D140358 --- .../test/tools/lldb-dap/dap_server.py | 4 +- .../disassemble/TestDAP_disassemble.py| 8 +++ lldb/tools/lldb-dap/lldb-dap.cpp | 68 +-- 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index a324af57b61df3..75731ebfde6723 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py @@ -674,11 +674,11 @@ def request_disconnect(self, terminateDebuggee=None): return self.send_recv(command_dict) def request_disassemble( -self, memoryReference, offset=-50, instructionCount=200, resolveSymbols=True +self, memoryReference, instructionOffset=0, instructionCount=10, resolveSymbols=True ): args_dict = { "memoryReference": memoryReference, -"offset": offset, +"instructionOffset": instructionOffset, "instructionCount": instructionCount, "resolveSymbols": resolveSymbols, } diff --git a/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py b/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py index 9e8ef5b289f2e8..ab72eb2d13d729 100644 --- a/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py +++ b/lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py @@ -29,6 +29,14 @@ def test_disassemble(self): ) self.continue_to_next_stop() +stackFrames = self.get_stackFrames( +threadId=threadId, startFrame=frameIndex, levels=1 +) +self.assertIsNotNone(stackFrames) + +# XXX finish updating test case +memoryReference = stackFrames[0]["instructionPointerReference"] + pc_assembly = self.disassemble(frameIndex=0) self.assertIn("location", pc_assembly, "Source location missing.") self.assertIn("instruction", pc_assembly, "Assembly instruction missing.") diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp index ea84f31aec3a6c..5d9d28b59ea805 100644 --- a/lldb/tools/lldb-dap/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/lldb-dap.cpp @@ -3910,8 +3910,8 @@ void request_disassemble(const llvm::json::Object &request) { return; } - addr_ptr += GetSigned(arguments, "instructionOffset", 0); - lldb::SBAddress addr(addr_ptr, g_dap.target); + addr_ptr += GetSigned(arguments, "offset", 0); + lldb::SBAddress addr = g_dap.target.ResolveLoadAddress(addr_ptr); if (!addr.IsValid()) { response["success"] = false; response["message"] = "Memory reference not found in the current binary."; @@ -3919,9 +3919,27 @@ void request_disassemble(const llvm::json::Object &request) { return; } - const auto inst_count = GetUnsigned(arguments, "instructionCount", 0); - lldb::SBInstructionList insts = - g_dap.target.ReadInstructions(addr, inst_count); + int64_t inst_offset = GetSigned(arguments, "instructionOffset", 0); + const int64_t inst_count = GetSigned(arguments, "instructionCount", 0); + if (inst_count < 0) { +response["success"] = false; +response["message"] = "Negative instruction count."; +g_dap.SendJSON(llvm::json::Value(std::move(response))); +return; + } + + lldb::SBInstructionList insts; + if (lldb::SBFunction func = addr.GetFunction()) { +// First try to identify the function boundaries through debug information +insts = func.GetInstructions(g_dap.target); + } else if (lldb::SBSymbol sym = addr.GetSymbol()) { +// Try to identify the function boundaries through the symbol table +insts = sym.GetInstructions(g_dap.target); + } else { +// We could not identify the function. Just disassemble starting from the +// provided address. +insts = g_dap.target.ReadInstructions(addr, inst_offset + inst_count); + } if (!insts.IsValid()) { response["success"] = false; @@ -3930,10
[Lldb-commits] [lldb] [lldb] Implement basic support for reverse-continue (PR #99736)
https://github.com/vogelsgesang edited https://github.com/llvm/llvm-project/pull/99736 ___ 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 dialog when executable is not found (PR #104711)
@@ -17,14 +17,46 @@ function createDefaultLLDBDapOptions(): LLDBDapOptions { const path = vscode.workspace .getConfiguration("lldb-dap", session.workspaceFolder) .get("executable-path"); - if (path) { -return new vscode.DebugAdapterExecutable(path, []); + + if (!path) { vogelsgesang wrote: even if the path is not set, we should check if the `packageJSONExecutable` actually exists By default, the `path` is not set. As such, new users would not get this error message, although those are the ones which are most likely to run into issues https://github.com/llvm/llvm-project/pull/104711 ___ 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 dialog when executable is not found (PR #104711)
@@ -17,14 +17,46 @@ function createDefaultLLDBDapOptions(): LLDBDapOptions { const path = vscode.workspace .getConfiguration("lldb-dap", session.workspaceFolder) .get("executable-path"); - if (path) { -return new vscode.DebugAdapterExecutable(path, []); + + if (!path) { +return packageJSONExecutable; } - return packageJSONExecutable; + + vscode.workspace.fs.stat(vscode.Uri.file(path)).then( +(fileStats) => { vogelsgesang wrote: in addition to checking the presence of the file on launch, we could also check for it in the `onDidChangeConfiguration` event if the `executable-path` gets changed. (100% optional; feel free to just ignore this comment 🙂) https://github.com/llvm/llvm-project/pull/104711 ___ 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 dialog when executable is not found (PR #104711)
vogelsgesang wrote: please rebase onto `main`. This unfortunately has a merge conflict with another change which I recently merged https://github.com/llvm/llvm-project/pull/104711 ___ 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 dialog when executable is not found (PR #104711)
https://github.com/vogelsgesang commented: Thanks for looking into this! The patch already looks very good! https://github.com/llvm/llvm-project/pull/104711 ___ 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 dialog when executable is not found (PR #104711)
https://github.com/vogelsgesang edited https://github.com/llvm/llvm-project/pull/104711 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Implement value locations for function pointers (PR #104589)
vogelsgesang wrote: Here the screen recording of a fully functional, non-remote session: https://github.com/user-attachments/assets/64b36078-a57b-440a-85f8-0e73f88c5a56 https://github.com/llvm/llvm-project/pull/104589 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Implement value locations for function pointers (PR #104589)
vogelsgesang wrote: In the below screen recording, you can see: * The function pointers are shown in the variables view as usual * The corresponding values are linked, as indicated by the underline when hovering the value * When Cmd+Clicking on the value, the link is followed * Currently, this still leads to an error message. Afaict, this is due to a bug in VS-Code Insiders. I suspect that it does not correctly resolve the file path provided by the debug adapter. Probably this fails because I am using a remote, SSH-based editing session here. * However, from the DAP logs (visible towards the bottom of the screen), we can see that the debug adapter returns the correct file name and also the correct line https://github.com/user-attachments/assets/6d7ff263-16e9-4194-b732-a79952ebed89 https://github.com/llvm/llvm-project/pull/104589 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Extend frame recognizers to hide frames from backtraces (PR #104523)
vogelsgesang wrote: Should hidden frames also be skipped by `StepOut`? https://github.com/llvm/llvm-project/pull/104523 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Implement value locations for function pointers (PR #104589)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/104589 >From 079def868f0216f31b78469f63034db5b350e250 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Sat, 10 Aug 2024 23:59:55 + Subject: [PATCH 1/2] [lldb-dap] Implement declaration locations This commit implements support for the "declaration location" recently added by microsoft/debug-adapter-protocol#494 to the debug adapter protocol. For the `declarationLocationReference` we need a variable ID similar to the the `variablesReference`. I decided to simply reuse the `variablesReference` here and renamed `Variables::expandable_variables` and friends accordingly. Given that almost all variables have a declaration location, we now assign those variable ids to all variables. While `declarationLocationReference` effectively supersedes `$__lldb_extensions.declaration`, I did not remove this extension, yet, since I assume that there are some closed-source extensions which rely on it. I tested this against VS-Code Insiders. However, VS-Code Insiders currently only supports `valueLoctionReference` and not `declarationLocationReference`, yet. Locally, I hence tried to publish the declaration locations as value locations. However, it seems that VS-Code still has issues with correctly resolving file paths, as reported in https://github.com/microsoft/vscode/pull/225546#issuecomment-2292428591 --- .../test/tools/lldb-dap/dap_server.py | 11 ++ .../API/tools/lldb-dap/locations/Makefile | 3 + .../lldb-dap/locations/TestDAP_locations.py | 40 + lldb/test/API/tools/lldb-dap/locations/main.c | 5 + lldb/tools/lldb-dap/DAP.cpp | 17 +- lldb/tools/lldb-dap/DAP.h | 10 +- lldb/tools/lldb-dap/JSONUtils.cpp | 125 --- lldb/tools/lldb-dap/JSONUtils.h | 31 ++-- lldb/tools/lldb-dap/lldb-dap.cpp | 146 +++--- 9 files changed, 286 insertions(+), 102 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index a324af57b61df3..9879a34ed2020c 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py @@ -1079,6 +1079,17 @@ def request_setVariable(self, containingVarRef, name, value, id=None): } return self.send_recv(command_dict) +def request_locations(self, locationReference): +args_dict = { +"locationReference": locationReference, +} +command_dict = { +"command": "locations", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + def request_testGetTargetBreakpoints(self): """A request packet used in the LLDB test suite to get all currently set breakpoint infos for all breakpoints currently set in the diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile b/lldb/test/API/tools/lldb-dap/locations/Makefile new file mode 100644 index 00..10495940055b63 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/locations/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py new file mode 100644 index 00..76d938d3908492 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py @@ -0,0 +1,40 @@ +""" +Test lldb-dap locations request +""" + + +import dap_server +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import lldbdap_testcase +import os + + +class TestDAP_locations(lldbdap_testcase.DAPTestCaseBase): +@skipIfWindows +def test_locations(self): +""" +Tests the 'locations' request. +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.c" +self.source_path = os.path.join(os.getcwd(), source) +self.set_source_breakpoints( +source, +[line_number(source, "// BREAK HERE")], +) +self.continue_to_next_stop() + +locals = {l["name"]: l for l in self.dap_server.get_local_variables()} + +# var1 has a declarationLocation but no valueLocation +self.assertIn("declarationLocationReference", locals["var1"].keys()) +self.assertNotIn("valueLocationReference", locals["var1"].keys()) +loc_var1 = self.dap_server.request_locations( +locals["var1"]["declarationLocationReference"] +) +se
[Lldb-commits] [lldb] [lldb-dap] Implement value locations for function pointers (PR #104589)
https://github.com/vogelsgesang created https://github.com/llvm/llvm-project/pull/104589 Note to reviewers: This commit builds on top of the not-yet-merged PR #102928. When reviewing, ignore the first commit, it is part of the over PR. I will rebase and turn this into a non-draft PR after #102928 landed. This commit adds `valueLocationReference` to function pointers and function references. Thereby, users can navigate directly to the pointed-to function from within the "variables" pane. In general, it would be useful to also a add similar location references also to member function pointers, `std::source_location`, `std::function`, and many more. Doing so would require extending the formatters to provide such a source code location. There were two RFCs about this a while ago: https://discourse.llvm.org/t/rfc-extending-formatters-with-a-source-code-reference/68375 https://discourse.llvm.org/t/rfc-sbvalue-metadata-provider/68377/26 However, both RFCs ended without a conclusion. As such, this commit now solve the lowest-hanging fruit, i.e. function pointers. If people find it useful, I will revive the RFC afterwards. >From 079def868f0216f31b78469f63034db5b350e250 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Sat, 10 Aug 2024 23:59:55 + Subject: [PATCH 1/2] [lldb-dap] Implement declaration locations This commit implements support for the "declaration location" recently added by microsoft/debug-adapter-protocol#494 to the debug adapter protocol. For the `declarationLocationReference` we need a variable ID similar to the the `variablesReference`. I decided to simply reuse the `variablesReference` here and renamed `Variables::expandable_variables` and friends accordingly. Given that almost all variables have a declaration location, we now assign those variable ids to all variables. While `declarationLocationReference` effectively supersedes `$__lldb_extensions.declaration`, I did not remove this extension, yet, since I assume that there are some closed-source extensions which rely on it. I tested this against VS-Code Insiders. However, VS-Code Insiders currently only supports `valueLoctionReference` and not `declarationLocationReference`, yet. Locally, I hence tried to publish the declaration locations as value locations. However, it seems that VS-Code still has issues with correctly resolving file paths, as reported in https://github.com/microsoft/vscode/pull/225546#issuecomment-2292428591 --- .../test/tools/lldb-dap/dap_server.py | 11 ++ .../API/tools/lldb-dap/locations/Makefile | 3 + .../lldb-dap/locations/TestDAP_locations.py | 40 + lldb/test/API/tools/lldb-dap/locations/main.c | 5 + lldb/tools/lldb-dap/DAP.cpp | 17 +- lldb/tools/lldb-dap/DAP.h | 10 +- lldb/tools/lldb-dap/JSONUtils.cpp | 125 --- lldb/tools/lldb-dap/JSONUtils.h | 31 ++-- lldb/tools/lldb-dap/lldb-dap.cpp | 146 +++--- 9 files changed, 286 insertions(+), 102 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/locations/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py create mode 100644 lldb/test/API/tools/lldb-dap/locations/main.c diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index a324af57b61df3..9879a34ed2020c 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py @@ -1079,6 +1079,17 @@ def request_setVariable(self, containingVarRef, name, value, id=None): } return self.send_recv(command_dict) +def request_locations(self, locationReference): +args_dict = { +"locationReference": locationReference, +} +command_dict = { +"command": "locations", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + def request_testGetTargetBreakpoints(self): """A request packet used in the LLDB test suite to get all currently set breakpoint infos for all breakpoints currently set in the diff --git a/lldb/test/API/tools/lldb-dap/locations/Makefile b/lldb/test/API/tools/lldb-dap/locations/Makefile new file mode 100644 index 00..10495940055b63 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/locations/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py new file mode 100644 index 00..76d938d3908492 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/locations/TestDAP_locations.py @@ -0,0 +1,40 @@ +""" +Test lldb-dap locations request +""" + + +import dap_server +from lldbsuite.test.decorators import * +from