[Lldb-commits] [lldb] [lldb] Tighten ABI assert in `StopInfoMachException::DeterminePtrauthFailure` (NFC) (PR #95015)
@@ -110,6 +108,9 @@ bool StopInfoMachException::DeterminePtrauthFailure(ExecutionContext _ctx) { strm.Printf("Note: Possible pointer authentication failure detected.\n"); }; + ABISP abi_sp = process.GetABI(); + assert(abi_sp && "Missing ABI info"); medismailben wrote: Sounds good, FWIW, this is happening with `crashlog` command when loading an arm64 target on an intel machine. That could explain why we're seeing this behavior. https://github.com/llvm/llvm-project/pull/95015 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Tighten ABI assert in `StopInfoMachException::DeterminePtrauthFailure` (NFC) (PR #95015)
https://github.com/jasonmolenda edited https://github.com/llvm/llvm-project/pull/95015 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][ConstString] Prevent GetString from constructing a std::string with a nullptr (PR #95175)
https://github.com/bulbazord approved this pull request. LGTM to avoid the UB, I wouldn't block this because of a complex existential question. In general though, I don't really see the point in being able to convert a `ConstString` into a `std::string`? The whole point is that it uniques the string and manages its lifetime (which is effectively until the end of LLDB). I guess if you have a function/method that takes a `std::string` argument (or a reference to one) then this is useful... But why not just change the function (if it's in our control)? https://github.com/llvm/llvm-project/pull/95175 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Tighten ABI assert in `StopInfoMachException::DeterminePtrauthFailure` (NFC) (PR #95015)
@@ -110,6 +108,9 @@ bool StopInfoMachException::DeterminePtrauthFailure(ExecutionContext _ctx) { strm.Printf("Note: Possible pointer authentication failure detected.\n"); }; + ABISP abi_sp = process.GetABI(); + assert(abi_sp && "Missing ABI info"); jasonmolenda wrote: tbh I'm not entirely sure why we're here at all for an x86_64 target? this method is only be called when the target cpu is llvm::Triple::aarch64. It fetches the value of the x16 register just before this, and returns if no such register is found I think? But yes, I would change these to not get the ABI and instead call Process::FixCodeAddress instead of getting the ABI at all, and asserting if we could not. Process::FixCodeAddress will silently return the same value if there is no ABI (and if it gets an ABI without a FixCodeAddress override method, it will also return the same value). https://github.com/llvm/llvm-project/pull/95015 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Reland "[lldb][api-test] Add API test for SBCommandInterpreter::Comm… (PR #95181)
https://github.com/chelcassanova closed https://github.com/llvm/llvm-project/pull/95181 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 3d86eeb - Reland "[lldb][api-test] Add API test for SBCommandInterpreter::Comm… (#95181)
Author: Chelsea Cassanova Date: 2024-06-11T16:41:31-07:00 New Revision: 3d86eebdf84f1c1a8ef57706c1182836176a1780 URL: https://github.com/llvm/llvm-project/commit/3d86eebdf84f1c1a8ef57706c1182836176a1780 DIFF: https://github.com/llvm/llvm-project/commit/3d86eebdf84f1c1a8ef57706c1182836176a1780.diff LOG: Reland "[lldb][api-test] Add API test for SBCommandInterpreter::Comm… (#95181) …andOverrideCallback (#94518)" This reverts commit 7cff05ada05e87408966d56b4c1675033187ff5c. The API test that was added erroneously imports a module that isn't needed and wouldn't be found which causes a test failures. This reversion removes that import. Added: lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py Modified: lldb/bindings/python/python-typemaps.swig lldb/bindings/python/python-wrapper.swig lldb/include/lldb/API/SBCommandInterpreter.h Removed: diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig index 8d4b740e5f35c..c39594c7df041 100644 --- a/lldb/bindings/python/python-typemaps.swig +++ b/lldb/bindings/python/python-typemaps.swig @@ -427,7 +427,6 @@ template <> bool SetNumberFromPyObject(double , PyObject *obj) { free($1); } - // For Log::LogOutputCallback %typemap(in) (lldb::LogOutputCallback log_callback, void *baton) { if (!($input == Py_None || @@ -476,6 +475,23 @@ template <> bool SetNumberFromPyObject(double , PyObject *obj) { $1 = $1 || PyCallable_Check(reinterpret_cast($input)); } +%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) { + if (!($input == Py_None || +PyCallable_Check(reinterpret_cast($input { +PyErr_SetString(PyExc_TypeError, "Need a callable object or None!"); +SWIG_fail; + } + + // Don't lose the callback reference. + Py_INCREF($input); + $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback; + $2 = $input; +} +%typemap(typecheck) (lldb::CommandOverrideCallback callback, void *baton) { + $1 = $input == Py_None; + $1 = $1 || PyCallable_Check(reinterpret_cast($input)); +} + %typemap(in) lldb::FileSP { PythonFile py_file(PyRefType::Borrowed, $input); if (!py_file) { diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 1370afc885d43..bd3de8ce5d46c 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -1099,6 +1099,28 @@ static void LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t } } +static bool LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void *baton, const char **argv) { + bool ret_val = false; + if (baton != Py_None) { +SWIG_PYTHON_THREAD_BEGIN_BLOCK; +// Create a PyList of items since we're going to pass it to the callback as a tuple +// of arguments. +PyObject *py_argv = PyList_New(0); +for (const char **arg = argv; arg && *arg; arg++) { + std::string arg_string = *arg; + PyObject *py_string = PyUnicode_FromStringAndSize(arg_string.c_str(), arg_string.size()); + PyList_Append(py_argv, py_string); +} + +PyObject *result = PyObject_CallObject( +reinterpret_cast(baton), PyList_AsTuple(py_argv)); +ret_val = result ? PyObject_IsTrue(result) : false; +Py_XDECREF(result); +SWIG_PYTHON_THREAD_END_BLOCK; + } + return ret_val; +} + static SBError LLDBSwigPythonCallLocateModuleCallback( void *callback_baton, const SBModuleSpec _spec_sb, SBFileSpec _file_spec_sb, SBFileSpec _file_spec_sb) { diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h b/lldb/include/lldb/API/SBCommandInterpreter.h index 639309aa32bfc..b7e39b7858616 100644 --- a/lldb/include/lldb/API/SBCommandInterpreter.h +++ b/lldb/include/lldb/API/SBCommandInterpreter.h @@ -265,11 +265,9 @@ class SBCommandInterpreter { // Catch commands before they execute by registering a callback that will get // called when the command gets executed. This allows GUI or command line // interfaces to intercept a command and stop it from happening -#ifndef SWIG bool SetCommandOverrideCallback(const char *command_name, lldb::CommandOverrideCallback callback, void *baton); -#endif /// Return true if the command interpreter is the active IO handler. /// diff --git a/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py new file mode 100644 index 0..a09c4a71c9948 --- /dev/null +++ b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py @@ -0,0 +1,30 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CommandOverrideCallback(TestBase): +def setUp(self): +
[Lldb-commits] [lldb] Reland "[lldb][api-test] Add API test for SBCommandInterpreter::Comm… (PR #95181)
https://github.com/medismailben approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/95181 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Reland "[lldb][api-test] Add API test for SBCommandInterpreter::Comm… (PR #95181)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Chelsea Cassanova (chelcassanova) Changes …andOverrideCallback (#94518)" This reverts commit 7cff05ada05e87408966d56b4c1675033187ff5c. The API test that was added erroneously imports a module that isn't needed and wouldn't be found which causes a test failures. This reversion removes that import. --- Full diff: https://github.com/llvm/llvm-project/pull/95181.diff 4 Files Affected: - (modified) lldb/bindings/python/python-typemaps.swig (+17-1) - (modified) lldb/bindings/python/python-wrapper.swig (+22) - (modified) lldb/include/lldb/API/SBCommandInterpreter.h (-2) - (added) lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py (+30) ``diff diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig index 8d4b740e5f35c..c39594c7df041 100644 --- a/lldb/bindings/python/python-typemaps.swig +++ b/lldb/bindings/python/python-typemaps.swig @@ -427,7 +427,6 @@ template <> bool SetNumberFromPyObject(double , PyObject *obj) { free($1); } - // For Log::LogOutputCallback %typemap(in) (lldb::LogOutputCallback log_callback, void *baton) { if (!($input == Py_None || @@ -476,6 +475,23 @@ template <> bool SetNumberFromPyObject(double , PyObject *obj) { $1 = $1 || PyCallable_Check(reinterpret_cast($input)); } +%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) { + if (!($input == Py_None || +PyCallable_Check(reinterpret_cast($input { +PyErr_SetString(PyExc_TypeError, "Need a callable object or None!"); +SWIG_fail; + } + + // Don't lose the callback reference. + Py_INCREF($input); + $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback; + $2 = $input; +} +%typemap(typecheck) (lldb::CommandOverrideCallback callback, void *baton) { + $1 = $input == Py_None; + $1 = $1 || PyCallable_Check(reinterpret_cast($input)); +} + %typemap(in) lldb::FileSP { PythonFile py_file(PyRefType::Borrowed, $input); if (!py_file) { diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 1370afc885d43..bd3de8ce5d46c 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -1099,6 +1099,28 @@ static void LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t } } +static bool LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void *baton, const char **argv) { + bool ret_val = false; + if (baton != Py_None) { +SWIG_PYTHON_THREAD_BEGIN_BLOCK; +// Create a PyList of items since we're going to pass it to the callback as a tuple +// of arguments. +PyObject *py_argv = PyList_New(0); +for (const char **arg = argv; arg && *arg; arg++) { + std::string arg_string = *arg; + PyObject *py_string = PyUnicode_FromStringAndSize(arg_string.c_str(), arg_string.size()); + PyList_Append(py_argv, py_string); +} + +PyObject *result = PyObject_CallObject( +reinterpret_cast(baton), PyList_AsTuple(py_argv)); +ret_val = result ? PyObject_IsTrue(result) : false; +Py_XDECREF(result); +SWIG_PYTHON_THREAD_END_BLOCK; + } + return ret_val; +} + static SBError LLDBSwigPythonCallLocateModuleCallback( void *callback_baton, const SBModuleSpec _spec_sb, SBFileSpec _file_spec_sb, SBFileSpec _file_spec_sb) { diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h b/lldb/include/lldb/API/SBCommandInterpreter.h index 639309aa32bfc..b7e39b7858616 100644 --- a/lldb/include/lldb/API/SBCommandInterpreter.h +++ b/lldb/include/lldb/API/SBCommandInterpreter.h @@ -265,11 +265,9 @@ class SBCommandInterpreter { // Catch commands before they execute by registering a callback that will get // called when the command gets executed. This allows GUI or command line // interfaces to intercept a command and stop it from happening -#ifndef SWIG bool SetCommandOverrideCallback(const char *command_name, lldb::CommandOverrideCallback callback, void *baton); -#endif /// Return true if the command interpreter is the active IO handler. /// diff --git a/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py new file mode 100644 index 0..a09c4a71c9948 --- /dev/null +++ b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py @@ -0,0 +1,30 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CommandOverrideCallback(TestBase): +def setUp(self): +TestBase.setUp(self) +self.line = line_number("main.c", "Hello world.") + +def test_command_override_callback(self): +self.build() +exe = self.getBuildArtifact("a.out") + +target = self.dbg.CreateTarget(exe)
[Lldb-commits] [lldb] Reland "[lldb][api-test] Add API test for SBCommandInterpreter::Comm… (PR #95181)
https://github.com/chelcassanova created https://github.com/llvm/llvm-project/pull/95181 …andOverrideCallback (#94518)" This reverts commit 7cff05ada05e87408966d56b4c1675033187ff5c. The API test that was added erroneously imports a module that isn't needed and wouldn't be found which causes a test failures. This reversion removes that import. >From 6cee5d2638b2b50bc8c4538014c2d3c77c98ecba Mon Sep 17 00:00:00 2001 From: Chelsea Cassanova Date: Tue, 11 Jun 2024 15:33:55 -0700 Subject: [PATCH] Reland "[lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (#94518)" This reverts commit 7cff05ada05e87408966d56b4c1675033187ff5c. The API test that was added erroneously imports a module that isn't needed and wouldn't be found which causes a test failures. This reversion removes that import. --- lldb/bindings/python/python-typemaps.swig | 18 ++- lldb/bindings/python/python-wrapper.swig | 22 ++ lldb/include/lldb/API/SBCommandInterpreter.h | 2 -- .../TestCommandOverrideCallback.py| 30 +++ 4 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig index 8d4b740e5f35c..c39594c7df041 100644 --- a/lldb/bindings/python/python-typemaps.swig +++ b/lldb/bindings/python/python-typemaps.swig @@ -427,7 +427,6 @@ template <> bool SetNumberFromPyObject(double , PyObject *obj) { free($1); } - // For Log::LogOutputCallback %typemap(in) (lldb::LogOutputCallback log_callback, void *baton) { if (!($input == Py_None || @@ -476,6 +475,23 @@ template <> bool SetNumberFromPyObject(double , PyObject *obj) { $1 = $1 || PyCallable_Check(reinterpret_cast($input)); } +%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) { + if (!($input == Py_None || +PyCallable_Check(reinterpret_cast($input { +PyErr_SetString(PyExc_TypeError, "Need a callable object or None!"); +SWIG_fail; + } + + // Don't lose the callback reference. + Py_INCREF($input); + $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback; + $2 = $input; +} +%typemap(typecheck) (lldb::CommandOverrideCallback callback, void *baton) { + $1 = $input == Py_None; + $1 = $1 || PyCallable_Check(reinterpret_cast($input)); +} + %typemap(in) lldb::FileSP { PythonFile py_file(PyRefType::Borrowed, $input); if (!py_file) { diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 1370afc885d43..bd3de8ce5d46c 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -1099,6 +1099,28 @@ static void LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t } } +static bool LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void *baton, const char **argv) { + bool ret_val = false; + if (baton != Py_None) { +SWIG_PYTHON_THREAD_BEGIN_BLOCK; +// Create a PyList of items since we're going to pass it to the callback as a tuple +// of arguments. +PyObject *py_argv = PyList_New(0); +for (const char **arg = argv; arg && *arg; arg++) { + std::string arg_string = *arg; + PyObject *py_string = PyUnicode_FromStringAndSize(arg_string.c_str(), arg_string.size()); + PyList_Append(py_argv, py_string); +} + +PyObject *result = PyObject_CallObject( +reinterpret_cast(baton), PyList_AsTuple(py_argv)); +ret_val = result ? PyObject_IsTrue(result) : false; +Py_XDECREF(result); +SWIG_PYTHON_THREAD_END_BLOCK; + } + return ret_val; +} + static SBError LLDBSwigPythonCallLocateModuleCallback( void *callback_baton, const SBModuleSpec _spec_sb, SBFileSpec _file_spec_sb, SBFileSpec _file_spec_sb) { diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h b/lldb/include/lldb/API/SBCommandInterpreter.h index 639309aa32bfc..b7e39b7858616 100644 --- a/lldb/include/lldb/API/SBCommandInterpreter.h +++ b/lldb/include/lldb/API/SBCommandInterpreter.h @@ -265,11 +265,9 @@ class SBCommandInterpreter { // Catch commands before they execute by registering a callback that will get // called when the command gets executed. This allows GUI or command line // interfaces to intercept a command and stop it from happening -#ifndef SWIG bool SetCommandOverrideCallback(const char *command_name, lldb::CommandOverrideCallback callback, void *baton); -#endif /// Return true if the command interpreter is the active IO handler. /// diff --git a/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py new file mode 100644 index 0..a09c4a71c9948 --- /dev/null +++
[Lldb-commits] [lldb] 11a4d43 - Fix flaky TestDAP_console test. (#94494)
Author: Miro Bucko Date: 2024-06-12T06:21:17+07:00 New Revision: 11a4d43f4a8ed02694de4d39b5591ff2b1c31803 URL: https://github.com/llvm/llvm-project/commit/11a4d43f4a8ed02694de4d39b5591ff2b1c31803 DIFF: https://github.com/llvm/llvm-project/commit/11a4d43f4a8ed02694de4d39b5591ff2b1c31803.diff LOG: Fix flaky TestDAP_console test. (#94494) Test Plan: llvm-lit llvm-project/lldb/test/API/tools/lldb-dap/console/TestDAP_console.py Added: Modified: lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py lldb/test/API/tools/lldb-dap/commands/TestDAP_commands.py lldb/test/API/tools/lldb-dap/console/TestDAP_console.py lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py Removed: 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 e2126d67a5fe7..a9eeec1840990 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 @@ -171,13 +171,15 @@ def get_output(self, category, timeout=0.0, clear=True): self.output_condition.release() return output -def collect_output(self, category, duration, clear=True): -end_time = time.time() + duration +def collect_output(self, category, timeout_secs, pattern, clear=True): +end_time = time.time() + timeout_secs collected_output = "" while end_time > time.time(): output = self.get_output(category, timeout=0.25, clear=clear) if output: collected_output += output +if pattern is not None and pattern in output: +break return collected_output if collected_output else None def enqueue_recv_packet(self, packet): 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 d56ea5dca14be..600dc2b5fe9bb 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 @@ -195,8 +195,10 @@ def get_stdout(self, timeout=0.0): def get_console(self, timeout=0.0): return self.dap_server.get_output("console", timeout=timeout) -def collect_console(self, duration): -return self.dap_server.collect_output("console", duration=duration) +def collect_console(self, timeout_secs, pattern=None): +return self.dap_server.collect_output( +"console", timeout_secs=timeout_secs, pattern=pattern +) def get_local_as_int(self, name, threadId=None): value = self.dap_server.get_local_variable_value(name, threadId=threadId) diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py index b3ba69749f673..1dbe00144f352 100644 --- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py +++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py @@ -200,7 +200,10 @@ def test_commands(self): # Get output from the console. This should contain both the # "exitCommands" that were run after the second breakpoint was hit # and the "terminateCommands" due to the debugging session ending -output = self.collect_console(duration=1.0) +output = self.collect_console( +timeout_secs=1.0, +pattern=terminateCommands[0], +) self.verify_commands("exitCommands", output, exitCommands) self.verify_commands("terminateCommands", output, terminateCommands) @@ -235,5 +238,8 @@ def test_terminate_commands(self): # Once it's disconnected the console should contain the # "terminateCommands" self.dap_server.request_disconnect(terminateDebuggee=True) -output = self.collect_console(duration=1.0) +output = self.collect_console( +timeout_secs=1.0, +pattern=terminateCommands[0], +) self.verify_commands("terminateCommands", output, terminateCommands) diff --git a/lldb/test/API/tools/lldb-dap/commands/TestDAP_commands.py b/lldb/test/API/tools/lldb-dap/commands/TestDAP_commands.py index 226b9385fe719..e4cf903fc0d11 100644 --- a/lldb/test/API/tools/lldb-dap/commands/TestDAP_commands.py +++ b/lldb/test/API/tools/lldb-dap/commands/TestDAP_commands.py @@ -22,7 +22,10 @@ def test_command_directive_quiet_on_success(self): stopCommands=["?" + command_quiet, command_not_quiet], exitCommands=["?" + command_quiet, command_not_quiet], ) -full_output = self.collect_console(duration=1.0) +full_output =
[Lldb-commits] [lldb] Fix flaky TestDAP_console test. (PR #94494)
https://github.com/mbucko closed https://github.com/llvm/llvm-project/pull/94494 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [WIP] [lldb][Progress] Report progress when completing types from DWARF (PR #91452)
Michael137 wrote: > This PR rate limits things. Might be worth trying this out here to see if it > helps: > > #75769 Will try this out, though I haven't found any major performance issues as a result of the progress events added here. Maybe for different workloads this could get more noticeable. Should be easy enough to adjust if it turns out this does cause problems. https://github.com/llvm/llvm-project/pull/91452 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 7cff05a - Revert "[lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (#94518)"
Author: Chelsea Cassanova Date: 2024-06-11T15:27:10-07:00 New Revision: 7cff05ada05e87408966d56b4c1675033187ff5c URL: https://github.com/llvm/llvm-project/commit/7cff05ada05e87408966d56b4c1675033187ff5c DIFF: https://github.com/llvm/llvm-project/commit/7cff05ada05e87408966d56b4c1675033187ff5c.diff LOG: Revert "[lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (#94518)" This reverts commit 6fb6eba9304b63e86ebf039edcb9a0b32e4b39e7. This test breaks due to an incorrect import in the test. Added: Modified: lldb/bindings/python/python-typemaps.swig lldb/bindings/python/python-wrapper.swig lldb/include/lldb/API/SBCommandInterpreter.h Removed: lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig index c39594c7df041..8d4b740e5f35c 100644 --- a/lldb/bindings/python/python-typemaps.swig +++ b/lldb/bindings/python/python-typemaps.swig @@ -427,6 +427,7 @@ template <> bool SetNumberFromPyObject(double , PyObject *obj) { free($1); } + // For Log::LogOutputCallback %typemap(in) (lldb::LogOutputCallback log_callback, void *baton) { if (!($input == Py_None || @@ -475,23 +476,6 @@ template <> bool SetNumberFromPyObject(double , PyObject *obj) { $1 = $1 || PyCallable_Check(reinterpret_cast($input)); } -%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) { - if (!($input == Py_None || -PyCallable_Check(reinterpret_cast($input { -PyErr_SetString(PyExc_TypeError, "Need a callable object or None!"); -SWIG_fail; - } - - // Don't lose the callback reference. - Py_INCREF($input); - $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback; - $2 = $input; -} -%typemap(typecheck) (lldb::CommandOverrideCallback callback, void *baton) { - $1 = $input == Py_None; - $1 = $1 || PyCallable_Check(reinterpret_cast($input)); -} - %typemap(in) lldb::FileSP { PythonFile py_file(PyRefType::Borrowed, $input); if (!py_file) { diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index bd3de8ce5d46c..1370afc885d43 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -1099,28 +1099,6 @@ static void LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t } } -static bool LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void *baton, const char **argv) { - bool ret_val = false; - if (baton != Py_None) { -SWIG_PYTHON_THREAD_BEGIN_BLOCK; -// Create a PyList of items since we're going to pass it to the callback as a tuple -// of arguments. -PyObject *py_argv = PyList_New(0); -for (const char **arg = argv; arg && *arg; arg++) { - std::string arg_string = *arg; - PyObject *py_string = PyUnicode_FromStringAndSize(arg_string.c_str(), arg_string.size()); - PyList_Append(py_argv, py_string); -} - -PyObject *result = PyObject_CallObject( -reinterpret_cast(baton), PyList_AsTuple(py_argv)); -ret_val = result ? PyObject_IsTrue(result) : false; -Py_XDECREF(result); -SWIG_PYTHON_THREAD_END_BLOCK; - } - return ret_val; -} - static SBError LLDBSwigPythonCallLocateModuleCallback( void *callback_baton, const SBModuleSpec _spec_sb, SBFileSpec _file_spec_sb, SBFileSpec _file_spec_sb) { diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h b/lldb/include/lldb/API/SBCommandInterpreter.h index b7e39b7858616..639309aa32bfc 100644 --- a/lldb/include/lldb/API/SBCommandInterpreter.h +++ b/lldb/include/lldb/API/SBCommandInterpreter.h @@ -265,9 +265,11 @@ class SBCommandInterpreter { // Catch commands before they execute by registering a callback that will get // called when the command gets executed. This allows GUI or command line // interfaces to intercept a command and stop it from happening +#ifndef SWIG bool SetCommandOverrideCallback(const char *command_name, lldb::CommandOverrideCallback callback, void *baton); +#endif /// Return true if the command interpreter is the active IO handler. /// diff --git a/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py deleted file mode 100644 index a593feb0012d9..0 --- a/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py +++ /dev/null @@ -1,31 +0,0 @@ -from typing_extensions import override -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil - - -class CommandOverrideCallback(TestBase): -def setUp(self): -TestBase.setUp(self) -self.line = line_number("main.c", "Hello
[Lldb-commits] [lldb] [WIP] [lldb][Progress] Report progress when completing types from DWARF (PR #91452)
@@ -1758,6 +1759,11 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext , } if (attrs.is_forward_declaration) { +Progress progress(llvm::formatv( +"Parsing forward declaration {0}: {1}", Michael137 wrote: done https://github.com/llvm/llvm-project/pull/91452 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [WIP] [lldb][Progress] Report progress when completing types from DWARF (PR #91452)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/91452 >From d9d0e0de9d57cefc8be78efa5ba9254127c68521 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 8 May 2024 10:47:54 +0100 Subject: [PATCH 1/2] [lldb][DWARFASTParserClang] Report progress when parsing types from DWARF --- .../source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp | 6 ++ 1 file changed, 6 insertions(+) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 579a538af3634..c701fa230bb79 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -23,6 +23,7 @@ #include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" #include "lldb/Core/Module.h" +#include "lldb/Core/Progress.h" #include "lldb/Core/Value.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/CompileUnit.h" @@ -1758,6 +1759,11 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext , } if (attrs.is_forward_declaration) { +Progress progress(llvm::formatv( +"Parsing forward declaration {0}: {1}", +dwarf->GetObjectFile()->GetFileSpec().GetFilename().GetString(), +attrs.name.GetString())); + // We have a forward declaration to a type and we need to try and // find a full declaration. We look in the current type index just in // case we have a forward declaration followed by an actual >From 5dc83694d3a92769a825a73f03ba85cd772b84e6 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Tue, 11 Jun 2024 23:27:40 +0100 Subject: [PATCH 2/2] fixup! rephrase progress message --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index c701fa230bb79..3255144da6d9b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1760,7 +1760,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext , if (attrs.is_forward_declaration) { Progress progress(llvm::formatv( -"Parsing forward declaration {0}: {1}", +"Parsing type in {0}: '{1}'", dwarf->GetObjectFile()->GetFileSpec().GetFilename().GetString(), attrs.name.GetString())); ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)
https://github.com/chelcassanova closed https://github.com/llvm/llvm-project/pull/94518 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 6fb6eba - [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (#94518)
Author: Chelsea Cassanova Date: 2024-06-11T15:20:35-07:00 New Revision: 6fb6eba9304b63e86ebf039edcb9a0b32e4b39e7 URL: https://github.com/llvm/llvm-project/commit/6fb6eba9304b63e86ebf039edcb9a0b32e4b39e7 DIFF: https://github.com/llvm/llvm-project/commit/6fb6eba9304b63e86ebf039edcb9a0b32e4b39e7.diff LOG: [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (#94518) `SBCommandInterpreter::CommandOverrideCallback` was not being exposed to the Python API and has no coverage in the API test suite, so this commits exposes and adds a test for it. Doing this involves also adding a typemap for the callback used for this function so that it matches the functionality of other callback functions that are exposed to Python. Added: lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py Modified: lldb/bindings/python/python-typemaps.swig lldb/bindings/python/python-wrapper.swig lldb/include/lldb/API/SBCommandInterpreter.h Removed: diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig index 8d4b740e5f35c..c39594c7df041 100644 --- a/lldb/bindings/python/python-typemaps.swig +++ b/lldb/bindings/python/python-typemaps.swig @@ -427,7 +427,6 @@ template <> bool SetNumberFromPyObject(double , PyObject *obj) { free($1); } - // For Log::LogOutputCallback %typemap(in) (lldb::LogOutputCallback log_callback, void *baton) { if (!($input == Py_None || @@ -476,6 +475,23 @@ template <> bool SetNumberFromPyObject(double , PyObject *obj) { $1 = $1 || PyCallable_Check(reinterpret_cast($input)); } +%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) { + if (!($input == Py_None || +PyCallable_Check(reinterpret_cast($input { +PyErr_SetString(PyExc_TypeError, "Need a callable object or None!"); +SWIG_fail; + } + + // Don't lose the callback reference. + Py_INCREF($input); + $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback; + $2 = $input; +} +%typemap(typecheck) (lldb::CommandOverrideCallback callback, void *baton) { + $1 = $input == Py_None; + $1 = $1 || PyCallable_Check(reinterpret_cast($input)); +} + %typemap(in) lldb::FileSP { PythonFile py_file(PyRefType::Borrowed, $input); if (!py_file) { diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 1370afc885d43..bd3de8ce5d46c 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -1099,6 +1099,28 @@ static void LLDBSwigPythonCallPythonSBDebuggerTerminateCallback(lldb::user_id_t } } +static bool LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback(void *baton, const char **argv) { + bool ret_val = false; + if (baton != Py_None) { +SWIG_PYTHON_THREAD_BEGIN_BLOCK; +// Create a PyList of items since we're going to pass it to the callback as a tuple +// of arguments. +PyObject *py_argv = PyList_New(0); +for (const char **arg = argv; arg && *arg; arg++) { + std::string arg_string = *arg; + PyObject *py_string = PyUnicode_FromStringAndSize(arg_string.c_str(), arg_string.size()); + PyList_Append(py_argv, py_string); +} + +PyObject *result = PyObject_CallObject( +reinterpret_cast(baton), PyList_AsTuple(py_argv)); +ret_val = result ? PyObject_IsTrue(result) : false; +Py_XDECREF(result); +SWIG_PYTHON_THREAD_END_BLOCK; + } + return ret_val; +} + static SBError LLDBSwigPythonCallLocateModuleCallback( void *callback_baton, const SBModuleSpec _spec_sb, SBFileSpec _file_spec_sb, SBFileSpec _file_spec_sb) { diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h b/lldb/include/lldb/API/SBCommandInterpreter.h index 639309aa32bfc..b7e39b7858616 100644 --- a/lldb/include/lldb/API/SBCommandInterpreter.h +++ b/lldb/include/lldb/API/SBCommandInterpreter.h @@ -265,11 +265,9 @@ class SBCommandInterpreter { // Catch commands before they execute by registering a callback that will get // called when the command gets executed. This allows GUI or command line // interfaces to intercept a command and stop it from happening -#ifndef SWIG bool SetCommandOverrideCallback(const char *command_name, lldb::CommandOverrideCallback callback, void *baton); -#endif /// Return true if the command interpreter is the active IO handler. /// diff --git a/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py new file mode 100644 index 0..a593feb0012d9 --- /dev/null +++ b/lldb/test/API/python_api/interpreter/TestCommandOverrideCallback.py @@ -0,0 +1,31 @@ +from typing_extensions import override +import lldb +from lldbsuite.test.decorators import *
[Lldb-commits] [lldb] [WIP] [lldb][Progress] Report progress when completing types from DWARF (PR #91452)
@@ -1758,6 +1759,11 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext , } if (attrs.is_forward_declaration) { +Progress progress(llvm::formatv( +"Parsing forward declaration {0}: {1}", adrian-prantl wrote: It should either be "Resolving forward declaration" or "Parsing type". Otherwise it sounds like we take a long time to load a forward declaration itself. https://github.com/llvm/llvm-project/pull/91452 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [WIP] [lldb][Progress] Report progress when completing types from DWARF (PR #91452)
clayborg wrote: This PR rate limits things. Might be worth trying this out here to see if it helps: https://github.com/llvm/llvm-project/pull/75769 https://github.com/llvm/llvm-project/pull/91452 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [WIP] [lldb][Progress] Report progress when completing types from DWARF (PR #91452)
Michael137 wrote: Decided to go with something much simpler. Currently just reporting progress in `ParseStructureLikeDIE`, when we search for the definition DIE. Should reduce the number of broadcasts to some extent, and once https://github.com/llvm/llvm-project/pull/92328 lands again, it would naturally move into `FindDefinitionTypeForDIE`. Also, we're no longer storing the `Progress` object for the entire lifetime of the `DWARFASTParserClang`, meaning we clear the message from the terminal by the time the expression finishes, and we are less likely to block other in-flight progress events elsewhere. https://github.com/llvm/llvm-project/pull/91452 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)
https://github.com/medismailben approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/94518 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [WIP] [lldb][Progress] Report progress when completing types from DWARF (PR #91452)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/91452 >From d9d0e0de9d57cefc8be78efa5ba9254127c68521 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 8 May 2024 10:47:54 +0100 Subject: [PATCH] [lldb][DWARFASTParserClang] Report progress when parsing types from DWARF --- .../source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp | 6 ++ 1 file changed, 6 insertions(+) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 579a538af3634..c701fa230bb79 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -23,6 +23,7 @@ #include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" #include "lldb/Core/Module.h" +#include "lldb/Core/Progress.h" #include "lldb/Core/Value.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/CompileUnit.h" @@ -1758,6 +1759,11 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext , } if (attrs.is_forward_declaration) { +Progress progress(llvm::formatv( +"Parsing forward declaration {0}: {1}", +dwarf->GetObjectFile()->GetFileSpec().GetFilename().GetString(), +attrs.name.GetString())); + // We have a forward declaration to a type and we need to try and // find a full declaration. We look in the current type index just in // case we have a forward declaration followed by an actual ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][api-test] Add API test for SBCommandInterpreter::CommandOverrideCallback (PR #94518)
https://github.com/JDevlieghere approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/94518 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][ConstString] Prevent GetString from constructing a std::string with a nullptr (PR #95175)
Michael137 wrote: @bulbazord raised a good question: do we need this API at all? >From a brief glance it looks like we're mainly using it for the `operator >std::string()` conversion operator? Apart from that, there are a couple of >other callers which probably could just use one of the C-string based APIs >instead. Technically `GetString` has the benefit of getting the string size >for the underlying `char const*` out of the string pool, instead of relying on >the `std::string` constructor calling `strlen`. But i doubt that's a big win >(if at all) https://github.com/llvm/llvm-project/pull/95175 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][ConstString] Prevent GetString from constructing a std::string with a nullptr (PR #95175)
https://github.com/JDevlieghere approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/95175 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][ConstString] Prevent GetString from constructing a std::string with a nullptr (PR #95175)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Michael Buch (Michael137) Changes This patch prevents passing a `nullptr` to the `std::string` constructor in `GetString`. This prevents UB arising from calling `GetString` on a default-constructed `ConstString`. --- Full diff: https://github.com/llvm/llvm-project/pull/95175.diff 2 Files Affected: - (modified) lldb/include/lldb/Utility/ConstString.h (+3-1) - (modified) lldb/unittests/Utility/ConstStringTest.cpp (+1) ``diff diff --git a/lldb/include/lldb/Utility/ConstString.h b/lldb/include/lldb/Utility/ConstString.h index f7f7ec7605eba..692ecb63bd763 100644 --- a/lldb/include/lldb/Utility/ConstString.h +++ b/lldb/include/lldb/Utility/ConstString.h @@ -199,7 +199,9 @@ class ConstString { } /// Get the string value as a std::string - std::string GetString() const { return std::string(m_string, GetLength()); } + std::string GetString() const { +return std::string(AsCString(""), GetLength()); + } /// Get the string value as a C string. /// diff --git a/lldb/unittests/Utility/ConstStringTest.cpp b/lldb/unittests/Utility/ConstStringTest.cpp index 716f2d8d6c804..7018248991b6e 100644 --- a/lldb/unittests/Utility/ConstStringTest.cpp +++ b/lldb/unittests/Utility/ConstStringTest.cpp @@ -88,6 +88,7 @@ TEST(ConstStringTest, NullAndEmptyStates) { EXPECT_TRUE(!null); EXPECT_TRUE(null.IsEmpty()); EXPECT_TRUE(null.IsNull()); + EXPECT_TRUE(null.GetString().empty()); } TEST(ConstStringTest, CompareConstString) { `` https://github.com/llvm/llvm-project/pull/95175 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][ConstString] Prevent GetString from constructing a std::string with a nullptr (PR #95175)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/95175 This patch prevents passing a `nullptr` to the `std::string` constructor in `GetString`. This prevents UB arising from calling `GetString` on a default-constructed `ConstString`. >From adacdee08b3d4f13be32ae3223a8272c15f7 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Tue, 11 Jun 2024 22:23:56 +0100 Subject: [PATCH] [lldb][ConstString] Prevent GetString from constructing a std::string with a nullptr This patch prevents passing a `nullptr` to the `std::string` constructor in `GetString`. This prevents UB arising from calling `GetString` on a default-constructed `ConstString`. --- lldb/include/lldb/Utility/ConstString.h| 4 +++- lldb/unittests/Utility/ConstStringTest.cpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/Utility/ConstString.h b/lldb/include/lldb/Utility/ConstString.h index f7f7ec7605eba..692ecb63bd763 100644 --- a/lldb/include/lldb/Utility/ConstString.h +++ b/lldb/include/lldb/Utility/ConstString.h @@ -199,7 +199,9 @@ class ConstString { } /// Get the string value as a std::string - std::string GetString() const { return std::string(m_string, GetLength()); } + std::string GetString() const { +return std::string(AsCString(""), GetLength()); + } /// Get the string value as a C string. /// diff --git a/lldb/unittests/Utility/ConstStringTest.cpp b/lldb/unittests/Utility/ConstStringTest.cpp index 716f2d8d6c804..7018248991b6e 100644 --- a/lldb/unittests/Utility/ConstStringTest.cpp +++ b/lldb/unittests/Utility/ConstStringTest.cpp @@ -88,6 +88,7 @@ TEST(ConstStringTest, NullAndEmptyStates) { EXPECT_TRUE(!null); EXPECT_TRUE(null.IsEmpty()); EXPECT_TRUE(null.IsNull()); + EXPECT_TRUE(null.GetString().empty()); } TEST(ConstStringTest, CompareConstString) { ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Add options to "statistics dump" to control what sections are dumped (PR #95075)
https://github.com/royitaqi edited https://github.com/llvm/llvm-project/pull/95075 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/95078 >From 75d1bc01ca42e327594cceba753bec483228efbd Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 10 Jun 2024 17:46:31 +0100 Subject: [PATCH 1/6] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine This patch moves some of the `is_cxx_method`/`objc_method` logic out of `DWARFASTParserClang::ParseSubroutine` into their own functions. Mainly the purpose of this is to (hopefully) make this function more readable by turning the deeply nested if-statements into early-returns. This will be useful in an upcoming change where we remove some of the branches of said if-statement. --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 447 +- .../SymbolFile/DWARF/DWARFASTParserClang.h| 15 + 2 files changed, 251 insertions(+), 211 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 579a538af3634..585ae4e58cc1a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -975,6 +975,226 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::HandleObjCMethod( +ObjCLanguage::MethodName const _method, DWARFDIE const , +CompilerType clang_type, ParsedDWARFTypeAttributes const , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, + false)); + + if (!complete_objc_class_type_sp) +return false; + + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + + if (!type_clang_forward_type) +return false; + + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type)) +return false; + + clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType( + type_clang_forward_type, attrs.name.GetCString(), clang_type, + attrs.is_artificial, is_variadic, attrs.is_objc_direct_call); + + if (!objc_method_decl) { +dwarf->GetObjectFile()->GetModule()->ReportError( +"[{0:x16}]: invalid Objective-C method {1:x4} ({2}), " +"please file a bug and attach the file at the start of " +"this error message", +die.GetOffset(), tag, DW_TAG_value_to_name(tag)); +return false; + } + + LinkDeclContextToDIE(objc_method_decl, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + + return true; +} + +std::pair DWARFASTParserClang::HandleCXXMethod( +DWARFDIE const , CompilerType clang_type, +ParsedDWARFTypeAttributes const , DWARFDIE const _ctx_die, +bool is_static, bool _containing_context) { + Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); + SymbolFileDWARF *dwarf = die.GetDWARF(); + // Look at the parent of this DIE and see if it is a class or + // struct and see if this is actually a C++ method + Type *class_type = dwarf->ResolveType(decl_ctx_die); + if (!class_type) +return {}; + + if (class_type->GetID() != decl_ctx_die.GetID() || + IsClangModuleFwdDecl(decl_ctx_die)) { + +// We uniqued the parent class of this function to another +// class so we now need to associate all dies under +// "decl_ctx_die" to DIEs in the DIE for "class_type"... +DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID()); + +if (class_type_die) { + std::vector failures; + + CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die, class_type, + failures); + + // FIXME do something with these failures that's + // smarter than just dropping them on the ground. + // Unfortunately classes don't like having stuff added + // to them after their definitions are complete... + + Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; + if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { +return {true, type_ptr->shared_from_this()}; + } +} + } + + if (attrs.specification.IsValid()) { +// We have a specification which we are going to base our +// function prototype off of, so we need this type to be +// completed so that the m_die_to_decl_ctx for the method in +// the specification has a valid clang decl context. +class_type->GetForwardCompilerType(); +// If we have a specification, then the function type should +// have been made with the specification and not with this +// die. +DWARFDIE spec_die = attrs.specification.Reference(); +clang::DeclContext *spec_clang_decl_ctx = +GetClangDeclContextForDIE(spec_die);
[Lldb-commits] [lldb] Fix type lookup bug where wrong decl context was being used for a DIE. (PR #94846)
https://github.com/clayborg closed https://github.com/llvm/llvm-project/pull/94846 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] a118f5f - Fix type lookup bug where wrong decl context was being used for a DIE. (#94846)
Author: Greg Clayton Date: 2024-06-11T13:58:26-07:00 New Revision: a118f5f398bf099ec76ebf889234ebbc58b28f0c URL: https://github.com/llvm/llvm-project/commit/a118f5f398bf099ec76ebf889234ebbc58b28f0c DIFF: https://github.com/llvm/llvm-project/commit/a118f5f398bf099ec76ebf889234ebbc58b28f0c.diff LOG: Fix type lookup bug where wrong decl context was being used for a DIE. (#94846) The function that calculated the declaration context for a DIE was incorrectly transparently traversing acrosss DW_TAG_subprogram dies when climbing the parent DIE chain. This meant that types defined in functions would appear to have the declaration context of anything above the function. I fixed the GetTypeLookupContextImpl(...) function in DWARFDIE.cpp to not transparently skip over functions, lexical blocks and inlined functions and compile and type units. Added a test to verify things are working. Added: lldb/test/API/functionalities/type_types/Makefile lldb/test/API/functionalities/type_types/TestFindTypes.py lldb/test/API/functionalities/type_types/main.cpp Modified: lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp Removed: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index 0ef94ed9f17c3..992d814793f9d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -477,6 +477,18 @@ static void GetTypeLookupContextImpl(DWARFDIE die, case DW_TAG_base_type: push_ctx(CompilerContextKind::Builtin, name); break; +// If any of the tags below appear in the parent chain, stop the decl +// context and return. Prior to these being in here, if a type existed in a +// namespace "a" like "a::my_struct", but we also have a function in that +// same namespace "a" which contained a type named "my_struct", both would +// return "a::my_struct" as the declaration context since the +// DW_TAG_subprogram would be skipped and its parent would be found. +case DW_TAG_compile_unit: +case DW_TAG_type_unit: +case DW_TAG_subprogram: +case DW_TAG_lexical_block: +case DW_TAG_inlined_subroutine: + return; default: break; } diff --git a/lldb/test/API/functionalities/type_types/Makefile b/lldb/test/API/functionalities/type_types/Makefile new file mode 100644 index 0..3d0b98f13f3d7 --- /dev/null +++ b/lldb/test/API/functionalities/type_types/Makefile @@ -0,0 +1,2 @@ +CXX_SOURCES := main.cpp +include Makefile.rules diff --git a/lldb/test/API/functionalities/type_types/TestFindTypes.py b/lldb/test/API/functionalities/type_types/TestFindTypes.py new file mode 100644 index 0..42b5c4cfaaf77 --- /dev/null +++ b/lldb/test/API/functionalities/type_types/TestFindTypes.py @@ -0,0 +1,66 @@ +""" +Test the SBModule and SBTarget type lookup APIs to find multiple types. +""" + +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TypeFindFirstTestCase(TestBase): +def test_find_first_type(self): +""" +Test SBTarget::FindTypes() and SBModule::FindTypes() APIs. + +We had issues where our declaration context when finding types was +incorrectly calculated where a type in a namepace, and a type in a +function that was also in the same namespace would match a lookup. For +example: + +namespace a { + struct Foo { +int foo; + }; + + unsigned foo() { +typedef unsigned Foo; +Foo foo = 12; +return foo; + } +} // namespace a + + +Previously LLDB would calculate the declaration context of "a::Foo" +correctly, but incorrectly calculate the declaration context of "Foo" +from within the foo() function as "a::Foo". Adding tests to ensure this +works correctly. +""" +self.build() +target = self.createTestTarget() +exe_module = target.GetModuleAtIndex(0) +self.assertTrue(exe_module.IsValid()) +# Test the SBTarget and SBModule APIs for FindFirstType +for api in [target, exe_module]: +# We should find the "a::Foo" but not the "Foo" type in the function +types = api.FindTypes("a::Foo") +self.assertEqual(types.GetSize(), 1) +type_str0 = str(types.GetTypeAtIndex(0)) +self.assertIn('struct Foo {', type_str0) + +# When we search by type basename, we should find any type whose +# basename matches "Foo", so "a::Foo" and the "Foo" type in the +# function. +types = api.FindTypes("Foo") +self.assertEqual(types.GetSize(), 2) +type_str0 =
[Lldb-commits] [lldb] 982b4b6 - [lldb] Fix declaration of thread argument in CommandObjectThreadStepWithTypeAndScope (#95146)
Author: Dave Lee Date: 2024-06-11T13:14:59-07:00 New Revision: 982b4b6f4d5ddf04ed5e85aea7074c9b26f29673 URL: https://github.com/llvm/llvm-project/commit/982b4b6f4d5ddf04ed5e85aea7074c9b26f29673 DIFF: https://github.com/llvm/llvm-project/commit/982b4b6f4d5ddf04ed5e85aea7074c9b26f29673.diff LOG: [lldb] Fix declaration of thread argument in CommandObjectThreadStepWithTypeAndScope (#95146) `thread step-in` (and other step commands) take a ``, not a ``. Added: Modified: lldb/source/Commands/CommandObjectThread.cpp Removed: diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index db96ee2cec383..bb2be560ebfff 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -383,7 +383,7 @@ class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed { eCommandProcessMustBePaused), m_step_type(step_type), m_step_scope(step_scope), m_class_options("scripted step") { -AddSimpleArgumentList(eArgTypeThreadID, eArgRepeatOptional); +AddSimpleArgumentList(eArgTypeThreadIndex, eArgRepeatOptional); if (step_type == eStepTypeScripted) { m_all_options.Append(_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2, ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix declaration of thread argument in CommandObjectThreadStepWithTypeAndScope (PR #95146)
https://github.com/kastiglione closed https://github.com/llvm/llvm-project/pull/95146 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix declaration of thread argument in CommandObjectThreadStepWithTypeAndScope (PR #95146)
https://github.com/jimingham approved this pull request. We clearly parse that as a Thread Index later on, so the definition here is wrong. Thread Index is also the right choice, having to type out the ID would be annoying. https://github.com/llvm/llvm-project/pull/95146 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
https://github.com/clayborg updated https://github.com/llvm/llvm-project/pull/87740 >From c364215cef4d383bf5cb51bf61d442a5bc9fbfe9 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Sat, 30 Mar 2024 10:50:34 -0700 Subject: [PATCH 1/9] Add support for using foreign type units in .debug_names. This patch adds support for the new foreign type unit support in .debug_names. Features include: - don't manually index foreign TUs if we have info for them - only use the type unit entries that match the .dwo files when we have a .dwp file - fix crashers that happen due to PeekDIEName() using wrong offsets --- .../SymbolFile/DWARF/DWARFDebugInfo.cpp | 18 .../Plugins/SymbolFile/DWARF/DWARFDebugInfo.h | 2 + .../SymbolFile/DWARF/DebugNamesDWARFIndex.cpp | 65 - .../SymbolFile/DWARF/DebugNamesDWARFIndex.h | 6 +- .../SymbolFile/DWARF/ManualDWARFIndex.cpp | 6 +- .../SymbolFile/DWARF/ManualDWARFIndex.h | 7 +- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 66 -- .../SymbolFile/DWARF/SymbolFileDWARF.h| 9 ++ .../DWARF/x86/dwp-foreign-type-units.cpp | 91 +++ .../DebugInfo/DWARF/DWARFAcceleratorTable.h | 11 +++ .../DebugInfo/DWARF/DWARFAcceleratorTable.cpp | 13 +++ 11 files changed, 257 insertions(+), 37 deletions(-) create mode 100644 lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index c37cc91e08ed1..056c6d4b0605f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -222,6 +222,20 @@ DWARFUnit *DWARFDebugInfo::GetUnitAtOffset(DIERef::Section section, return result; } +DWARFUnit *DWARFDebugInfo::GetUnit(const DIERef _ref) { + // Make sure we get the correct SymbolFileDWARF from the DIERef before + // asking for information from a debug info object. We might start with the + // DWARFDebugInfo for the main executable in a split DWARF and the DIERef + // might be pointing to a specific .dwo file or to the .dwp file. So this + // makes sure we get the right SymbolFileDWARF instance before finding the + // DWARFUnit that contains the offset. If we just use this object to do the + // search, we might be using the wrong .debug_info section from the wrong + // file with an offset meant for a different section. + SymbolFileDWARF *dwarf = m_dwarf.GetDIERefSymbolFile(die_ref); + return dwarf->DebugInfo().GetUnitContainingDIEOffset(die_ref.section(), + die_ref.die_offset()); +} + DWARFUnit * DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section section, dw_offset_t die_offset) { @@ -232,6 +246,10 @@ DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section section, return result; } +const std::shared_ptr DWARFDebugInfo::GetDwpSymbolFile() { + return m_dwarf.GetDwpSymbolFile(); +} + DWARFTypeUnit *DWARFDebugInfo::GetTypeUnitForHash(uint64_t hash) { auto pos = llvm::lower_bound(m_type_hash_to_unit_index, std::make_pair(hash, 0u), llvm::less_first()); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h index 4706b55d38ea9..4d4555a338252 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -52,6 +52,8 @@ class DWARFDebugInfo { const DWARFDebugAranges (); + const std::shared_ptr GetDwpSymbolFile(); + protected: typedef std::vector UnitColl; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index 56717bab1ecd8..a07c454ea7ee3 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -34,6 +34,18 @@ DebugNamesDWARFIndex::Create(Module , DWARFDataExtractor debug_names, module, std::move(index_up), debug_names, debug_str, dwarf)); } + +llvm::DenseSet +DebugNamesDWARFIndex::GetTypeUnitSigs(const DebugNames _names) { + llvm::DenseSet result; + for (const DebugNames::NameIndex : debug_names) { +const uint32_t num_tus = ni.getForeignTUCount(); +for (uint32_t tu = 0; tu < num_tus; ++tu) + result.insert(ni.getForeignTUSignature(tu)); + } + return result; +} + llvm::DenseSet DebugNamesDWARFIndex::GetUnits(const DebugNames _names) { llvm::DenseSet result; @@ -48,17 +60,22 @@ DebugNamesDWARFIndex::GetUnits(const DebugNames _names) { return result; } +DWARFTypeUnit * +DebugNamesDWARFIndex::GetForeignTypeUnit(const DebugNames::Entry ) const { + std::optional type_sig = entry.getForeignTUTypeSignature(); + if (type_sig) +if (auto dwp_sp = m_debug_info.GetDwpSymbolFile()) + return
[Lldb-commits] [lldb] [lldb] Tighten ABI assert in `StopInfoMachException::DeterminePtrauthFailure` (NFC) (PR #95015)
https://github.com/medismailben edited https://github.com/llvm/llvm-project/pull/95015 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Tighten ABI assert in `StopInfoMachException::DeterminePtrauthFailure` (NFC) (PR #95015)
@@ -110,6 +108,9 @@ bool StopInfoMachException::DeterminePtrauthFailure(ExecutionContext _ctx) { strm.Printf("Note: Possible pointer authentication failure detected.\n"); }; + ABISP abi_sp = process.GetABI(); + assert(abi_sp && "Missing ABI info"); medismailben wrote: @clayborg Would you be fine that ? @jasonmolenda would we still need to call `FixAnyAddress` here ? ```suggestion if(!abi_sp) { // log missing ABI info return false; } ``` https://github.com/llvm/llvm-project/pull/95015 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 56f668c - [lldb/DWARF] Remove some dead code (#95127)
Author: Pavel Labath Date: 2024-06-11T19:49:10+02:00 New Revision: 56f668c12b1a26e103aafe5ac37930b1895c938b URL: https://github.com/llvm/llvm-project/commit/56f668c12b1a26e103aafe5ac37930b1895c938b DIFF: https://github.com/llvm/llvm-project/commit/56f668c12b1a26e103aafe5ac37930b1895c938b.diff LOG: [lldb/DWARF] Remove some dead code (#95127) `GetDeclContextDIEs` and `DIEDeclContextsMatch` are unused (possibly since we added support for simplified template names, but I haven't checked). `GetDeclContextDIEs` is also very similar (but subtly different) from `GetDeclContext` and `GetTypeLookupContext`. I am keeping `GetParentDeclContextDIE` as that one still has some callers, but I want to look into the possibility of merging it with at least one of the functions mentioned above. Added: Modified: lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Removed: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index 7cf92adc6ef57..0ef94ed9f17c3 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -367,20 +367,6 @@ lldb_private::Type *DWARFDIE::ResolveTypeUID(const DWARFDIE ) const { return nullptr; } -std::vector DWARFDIE::GetDeclContextDIEs() const { - if (!IsValid()) -return {}; - - std::vector result; - DWARFDIE parent = GetParentDeclContextDIE(); - while (parent.IsValid() && parent.GetDIE() != GetDIE()) { -result.push_back(std::move(parent)); -parent = parent.GetParentDeclContextDIE(); - } - - return result; -} - static void GetDeclContextImpl(DWARFDIE die, llvm::SmallSet , std::vector ) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h index 511ca62d0197a..c74a82061fccf 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -69,9 +69,6 @@ class DWARFDIE : public DWARFBaseDIE { DWARFDIE GetParentDeclContextDIE() const; - // DeclContext related functions - std::vector GetDeclContextDIEs() const; - /// Return this DIE's decl context as it is needed to look up types /// in Clang modules. This context will include any modules or functions that /// the type is declared in so an exact module match can be efficiently made. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index a52a7d6767374..d9e81f9c105b2 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3039,95 +3039,6 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE( return type_sp; } -// This function helps to ensure that the declaration contexts match for two -// diff erent DIEs. Often times debug information will refer to a forward -// declaration of a type (the equivalent of "struct my_struct;". There will -// often be a declaration of that type elsewhere that has the full definition. -// When we go looking for the full type "my_struct", we will find one or more -// matches in the accelerator tables and we will then need to make sure the -// type was in the same declaration context as the original DIE. This function -// can efficiently compare two DIEs and will return true when the declaration -// context matches, and false when they don't. -bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE , - const DWARFDIE ) { - if (die1 == die2) -return true; - - std::vector decl_ctx_1; - std::vector decl_ctx_2; - // The declaration DIE stack is a stack of the declaration context DIEs all - // the way back to the compile unit. If a type "T" is declared inside a class - // "B", and class "B" is declared inside a class "A" and class "A" is in a - // namespace "lldb", and the namespace is in a compile unit, there will be a - // stack of DIEs: - // - // [0] DW_TAG_class_type for "B" - // [1] DW_TAG_class_type for "A" - // [2] DW_TAG_namespace for "lldb" - // [3] DW_TAG_compile_unit or DW_TAG_partial_unit for the source file. - // - // We grab both contexts and make sure that everything matches all the way - // back to the compiler unit. - - // First lets grab the decl contexts for both DIEs - decl_ctx_1 = die1.GetDeclContextDIEs(); - decl_ctx_2 = die2.GetDeclContextDIEs(); - // Make sure the context arrays have the same size, otherwise we are done - const size_t count1 = decl_ctx_1.size(); - const size_t count2 = decl_ctx_2.size(); - if (count1 != count2) -
[Lldb-commits] [lldb] [lldb/DWARF] Remove some dead code (PR #95127)
https://github.com/labath closed https://github.com/llvm/llvm-project/pull/95127 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Skip declaration DIEs in the debug_names index (PR #94744)
https://github.com/clayborg commented: LGTM. https://github.com/llvm/llvm-project/pull/94744 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb/DWARF] Remove some dead code (PR #95127)
https://github.com/clayborg approved this pull request. https://github.com/llvm/llvm-project/pull/95127 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/clayborg approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix declaration of thread argument in CommandObjectThreadStepWithTypeAndScope (PR #95146)
https://github.com/kastiglione edited https://github.com/llvm/llvm-project/pull/95146 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix declaration of thread argument in CommandObjectThreadStepWithTypeAndScope (PR #95146)
https://github.com/kastiglione edited https://github.com/llvm/llvm-project/pull/95146 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix declaration of thread argument in CommandObjectThreadStepWithTypeAndScope (PR #95146)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Dave Lee (kastiglione) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/95146.diff 1 Files Affected: - (modified) lldb/source/Commands/CommandObjectThread.cpp (+1-1) ``diff diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index db96ee2cec383..bb2be560ebfff 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -383,7 +383,7 @@ class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed { eCommandProcessMustBePaused), m_step_type(step_type), m_step_scope(step_scope), m_class_options("scripted step") { -AddSimpleArgumentList(eArgTypeThreadID, eArgRepeatOptional); +AddSimpleArgumentList(eArgTypeThreadIndex, eArgRepeatOptional); if (step_type == eStepTypeScripted) { m_all_options.Append(_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2, `` https://github.com/llvm/llvm-project/pull/95146 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix declaration of thread argument in CommandObjectThreadStepWithTypeAndScope (PR #95146)
https://github.com/kastiglione created https://github.com/llvm/llvm-project/pull/95146 None >From 1f4d61ed4e0ab42d5e5ac0937c0af0572f0f8f10 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Mon, 10 Jun 2024 10:46:08 -0700 Subject: [PATCH] [lldb] Fix declaration of thread argument in CommandObjectThreadStepWithTypeAndScope --- lldb/source/Commands/CommandObjectThread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index db96ee2cec383..bb2be560ebfff 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -383,7 +383,7 @@ class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed { eCommandProcessMustBePaused), m_step_type(step_type), m_step_scope(step_scope), m_class_options("scripted step") { -AddSimpleArgumentList(eArgTypeThreadID, eArgRepeatOptional); +AddSimpleArgumentList(eArgTypeThreadIndex, eArgRepeatOptional); if (step_type == eStepTypeScripted) { m_all_options.Append(_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2, ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
@@ -86,4 +89,22 @@ TEST_F(HostTest, GetProcessInfo) { ProcessInstanceInfo::timespec next_user_time = Info.GetUserTime(); ASSERT_TRUE(user_time.tv_sec <= next_user_time.tv_sec || user_time.tv_usec <= next_user_time.tv_usec); + + struct rlimit rlim; + EXPECT_EQ(getrlimit(RLIMIT_NICE, ), 0); + // getpriority can return -1 so we zero errno first + errno = 0; + int prio = getpriority(PRIO_PROCESS, PRIO_PROCESS); + ASSERT_TRUE((prio < 0 && errno == 0) || prio >= 0); + ASSERT_EQ(Info.GetPriorityValue(), prio); + // If we can't raise our nice level then this test can't be performed. + int max_incr = PRIO_MAX - rlim.rlim_cur; + if (max_incr < prio) { +EXPECT_EQ(setpriority(PRIO_PROCESS, PRIO_PROCESS, prio - 1), 0); +ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info)); +ASSERT_EQ(Info.GetPriorityValue().value(), prio - 1); feg208 wrote: Done. Thanks for all your effort reviewing this work https://github.com/llvm/llvm-project/pull/91544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Adds additional fields to ProcessInfo (PR #91544)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/91544 >From a162f04d6d9f6c879398e4a6883f026bbfbd1e8f Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Wed, 8 May 2024 15:36:16 -0700 Subject: [PATCH] [lldb] Adds additional fields to ProcessInfo To implement SaveCore for elf binaries we need to populate some additional fields in the prpsinfo struct. Those fields are the nice value of the process whose core is to be taken as well as a boolean flag indicating whether or not that process is a zombie. This commit adds those as well as tests to ensure that the values are consistent with expectations --- lldb/include/lldb/Utility/ProcessInfo.h | 24 ++- lldb/source/Host/linux/Host.cpp | 32 ++--- lldb/source/Utility/ProcessInfo.cpp | 7 +++--- lldb/unittests/Host/linux/HostTest.cpp | 22 + 4 files changed, 68 insertions(+), 17 deletions(-) diff --git a/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h index 54ac000dc7fc2..78ade4bbb1ee6 100644 --- a/lldb/include/lldb/Utility/ProcessInfo.h +++ b/lldb/include/lldb/Utility/ProcessInfo.h @@ -15,6 +15,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/StructuredData.h" +#include #include namespace lldb_private { @@ -147,8 +148,7 @@ class ProcessInstanceInfo : public ProcessInfo { ProcessInstanceInfo() = default; ProcessInstanceInfo(const char *name, const ArchSpec , lldb::pid_t pid) - : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), -m_parent_pid(LLDB_INVALID_PROCESS_ID) {} + : ProcessInfo(name, arch, pid) {} void Clear() { ProcessInfo::Clear(); @@ -237,6 +237,16 @@ class ProcessInstanceInfo : public ProcessInfo { m_cumulative_system_time.tv_usec > 0; } + std::optional GetPriorityValue() const { return m_priority_value; } + + void SetPriorityValue(int8_t priority_value) { +m_priority_value = priority_value; + } + + void SetIsZombie(bool is_zombie) { m_zombie = is_zombie; } + + std::optional IsZombie() const { return m_zombie; } + void Dump(Stream , UserIDResolver ) const; static void DumpTableHeader(Stream , bool show_args, bool verbose); @@ -250,10 +260,12 @@ class ProcessInstanceInfo : public ProcessInfo { lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_group_id = LLDB_INVALID_PROCESS_ID; lldb::pid_t m_process_session_id = LLDB_INVALID_PROCESS_ID; - struct timespec m_user_time {}; - struct timespec m_system_time {}; - struct timespec m_cumulative_user_time {}; - struct timespec m_cumulative_system_time {}; + struct timespec m_user_time; + struct timespec m_system_time; + struct timespec m_cumulative_user_time; + struct timespec m_cumulative_system_time; + std::optional m_priority_value = std::nullopt; + std::optional m_zombie = std::nullopt; }; typedef std::vector ProcessInstanceInfoList; diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index c6490f2fc9e2f..5545f9ef4d70e 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -37,6 +37,7 @@ using namespace lldb; using namespace lldb_private; namespace { + enum class ProcessState { Unknown, Dead, @@ -70,6 +71,12 @@ struct StatFields { long unsigned stime; long cutime; long cstime; + // In proc_pid_stat(5) this field is specified as priority + // but documented as realtime priority. To keep with the adopted + // nomenclature in ProcessInstanceInfo, we adopt the documented + // naming here. + long realtime_priority; + long priority; // other things. We don't need them below }; } @@ -91,14 +98,16 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo , if (Rest.empty()) return false; StatFields stat_fields; - if (sscanf(Rest.data(), - "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld", - _fields.pid, stat_fields.comm, _fields.state, - _fields.ppid, _fields.pgrp, _fields.session, - _fields.tty_nr, _fields.tpgid, _fields.flags, - _fields.minflt, _fields.cminflt, _fields.majflt, - _fields.cmajflt, _fields.utime, _fields.stime, - _fields.cutime, _fields.cstime) < 0) { + if (sscanf( + Rest.data(), + "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld", + _fields.pid, stat_fields.comm, _fields.state, + _fields.ppid, _fields.pgrp, _fields.session, + _fields.tty_nr, _fields.tpgid, _fields.flags, + _fields.minflt, _fields.cminflt, _fields.majflt, + _fields.cmajflt, _fields.utime, _fields.stime, + _fields.cutime, _fields.cstime, + _fields.realtime_priority, _fields.priority) < 0) { return false; } @@ -115,6 +124,11 @@ static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo , return
[Lldb-commits] [lldb] 2e007b8 - [lldb] Skip TestAttachDenied under asan
Author: Felipe de Azevedo Piovezan Date: 2024-06-11T09:28:10-07:00 New Revision: 2e007b89c65eeb33baf1b40103284d8937700cf0 URL: https://github.com/llvm/llvm-project/commit/2e007b89c65eeb33baf1b40103284d8937700cf0 DIFF: https://github.com/llvm/llvm-project/commit/2e007b89c65eeb33baf1b40103284d8937700cf0.diff LOG: [lldb] Skip TestAttachDenied under asan Like many other tests, this one times out when run under the address sanitizer. To reduce noise, this commit skips it in those builds. Added: Modified: lldb/test/API/commands/process/attach/attach_denied/TestAttachDenied.py Removed: diff --git a/lldb/test/API/commands/process/attach/attach_denied/TestAttachDenied.py b/lldb/test/API/commands/process/attach/attach_denied/TestAttachDenied.py index 22dca62045022..d72a710e8127b 100644 --- a/lldb/test/API/commands/process/attach/attach_denied/TestAttachDenied.py +++ b/lldb/test/API/commands/process/attach/attach_denied/TestAttachDenied.py @@ -18,6 +18,7 @@ class AttachDeniedTestCase(TestBase): @skipIfWindows @skipIfiOSSimulator @skipIfDarwinEmbedded # ptrace(ATTACH_REQUEST...) won't work on ios/tvos/etc +@skipIfAsan # Times out inconsistently under asan def test_attach_to_process_by_id_denied(self): """Test attach by process id denied""" self.build() ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb/DWARF] Remove some dead code (PR #95127)
https://github.com/Michael137 approved this pull request. Nice, can confirm they're unused on the apple fork too https://github.com/llvm/llvm-project/pull/95127 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/95078 >From 75d1bc01ca42e327594cceba753bec483228efbd Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 10 Jun 2024 17:46:31 +0100 Subject: [PATCH 1/6] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine This patch moves some of the `is_cxx_method`/`objc_method` logic out of `DWARFASTParserClang::ParseSubroutine` into their own functions. Mainly the purpose of this is to (hopefully) make this function more readable by turning the deeply nested if-statements into early-returns. This will be useful in an upcoming change where we remove some of the branches of said if-statement. --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 447 +- .../SymbolFile/DWARF/DWARFASTParserClang.h| 15 + 2 files changed, 251 insertions(+), 211 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 579a538af3634..585ae4e58cc1a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -975,6 +975,226 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::HandleObjCMethod( +ObjCLanguage::MethodName const _method, DWARFDIE const , +CompilerType clang_type, ParsedDWARFTypeAttributes const , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, + false)); + + if (!complete_objc_class_type_sp) +return false; + + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + + if (!type_clang_forward_type) +return false; + + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type)) +return false; + + clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType( + type_clang_forward_type, attrs.name.GetCString(), clang_type, + attrs.is_artificial, is_variadic, attrs.is_objc_direct_call); + + if (!objc_method_decl) { +dwarf->GetObjectFile()->GetModule()->ReportError( +"[{0:x16}]: invalid Objective-C method {1:x4} ({2}), " +"please file a bug and attach the file at the start of " +"this error message", +die.GetOffset(), tag, DW_TAG_value_to_name(tag)); +return false; + } + + LinkDeclContextToDIE(objc_method_decl, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + + return true; +} + +std::pair DWARFASTParserClang::HandleCXXMethod( +DWARFDIE const , CompilerType clang_type, +ParsedDWARFTypeAttributes const , DWARFDIE const _ctx_die, +bool is_static, bool _containing_context) { + Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); + SymbolFileDWARF *dwarf = die.GetDWARF(); + // Look at the parent of this DIE and see if it is a class or + // struct and see if this is actually a C++ method + Type *class_type = dwarf->ResolveType(decl_ctx_die); + if (!class_type) +return {}; + + if (class_type->GetID() != decl_ctx_die.GetID() || + IsClangModuleFwdDecl(decl_ctx_die)) { + +// We uniqued the parent class of this function to another +// class so we now need to associate all dies under +// "decl_ctx_die" to DIEs in the DIE for "class_type"... +DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID()); + +if (class_type_die) { + std::vector failures; + + CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die, class_type, + failures); + + // FIXME do something with these failures that's + // smarter than just dropping them on the ground. + // Unfortunately classes don't like having stuff added + // to them after their definitions are complete... + + Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; + if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { +return {true, type_ptr->shared_from_this()}; + } +} + } + + if (attrs.specification.IsValid()) { +// We have a specification which we are going to base our +// function prototype off of, so we need this type to be +// completed so that the m_die_to_decl_ctx for the method in +// the specification has a valid clang decl context. +class_type->GetForwardCompilerType(); +// If we have a specification, then the function type should +// have been made with the specification and not with this +// die. +DWARFDIE spec_die = attrs.specification.Reference(); +clang::DeclContext *spec_clang_decl_ctx = +GetClangDeclContextForDIE(spec_die);
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/95078 >From 75d1bc01ca42e327594cceba753bec483228efbd Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 10 Jun 2024 17:46:31 +0100 Subject: [PATCH 1/5] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine This patch moves some of the `is_cxx_method`/`objc_method` logic out of `DWARFASTParserClang::ParseSubroutine` into their own functions. Mainly the purpose of this is to (hopefully) make this function more readable by turning the deeply nested if-statements into early-returns. This will be useful in an upcoming change where we remove some of the branches of said if-statement. --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 447 +- .../SymbolFile/DWARF/DWARFASTParserClang.h| 15 + 2 files changed, 251 insertions(+), 211 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 579a538af3634..585ae4e58cc1a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -975,6 +975,226 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::HandleObjCMethod( +ObjCLanguage::MethodName const _method, DWARFDIE const , +CompilerType clang_type, ParsedDWARFTypeAttributes const , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, + false)); + + if (!complete_objc_class_type_sp) +return false; + + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + + if (!type_clang_forward_type) +return false; + + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type)) +return false; + + clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType( + type_clang_forward_type, attrs.name.GetCString(), clang_type, + attrs.is_artificial, is_variadic, attrs.is_objc_direct_call); + + if (!objc_method_decl) { +dwarf->GetObjectFile()->GetModule()->ReportError( +"[{0:x16}]: invalid Objective-C method {1:x4} ({2}), " +"please file a bug and attach the file at the start of " +"this error message", +die.GetOffset(), tag, DW_TAG_value_to_name(tag)); +return false; + } + + LinkDeclContextToDIE(objc_method_decl, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + + return true; +} + +std::pair DWARFASTParserClang::HandleCXXMethod( +DWARFDIE const , CompilerType clang_type, +ParsedDWARFTypeAttributes const , DWARFDIE const _ctx_die, +bool is_static, bool _containing_context) { + Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); + SymbolFileDWARF *dwarf = die.GetDWARF(); + // Look at the parent of this DIE and see if it is a class or + // struct and see if this is actually a C++ method + Type *class_type = dwarf->ResolveType(decl_ctx_die); + if (!class_type) +return {}; + + if (class_type->GetID() != decl_ctx_die.GetID() || + IsClangModuleFwdDecl(decl_ctx_die)) { + +// We uniqued the parent class of this function to another +// class so we now need to associate all dies under +// "decl_ctx_die" to DIEs in the DIE for "class_type"... +DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID()); + +if (class_type_die) { + std::vector failures; + + CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die, class_type, + failures); + + // FIXME do something with these failures that's + // smarter than just dropping them on the ground. + // Unfortunately classes don't like having stuff added + // to them after their definitions are complete... + + Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; + if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { +return {true, type_ptr->shared_from_this()}; + } +} + } + + if (attrs.specification.IsValid()) { +// We have a specification which we are going to base our +// function prototype off of, so we need this type to be +// completed so that the m_die_to_decl_ctx for the method in +// the specification has a valid clang decl context. +class_type->GetForwardCompilerType(); +// If we have a specification, then the function type should +// have been made with the specification and not with this +// die. +DWARFDIE spec_die = attrs.specification.Reference(); +clang::DeclContext *spec_clang_decl_ctx = +GetClangDeclContextForDIE(spec_die);
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -975,6 +975,219 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::ParseObjCMethod( +const ObjCLanguage::MethodName _method, const DWARFDIE , +CompilerType clang_type, const ParsedDWARFTypeAttributes , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); Michael137 wrote: Oh I'm surprised to find that `GetDWARF` can in fact return `nullptr`. All of the code in this file assumes that it can't, but not sure what guarantees this... https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
https://github.com/felipepiovezan edited https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
https://github.com/felipepiovezan edited https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -975,6 +975,219 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::ParseObjCMethod( +const ObjCLanguage::MethodName _method, const DWARFDIE , +CompilerType clang_type, const ParsedDWARFTypeAttributes , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, felipepiovezan wrote: should we write this as an assignment instead? It is the same thing, but at least the code is consistent with how other variables are initialized https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -975,6 +975,219 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::ParseObjCMethod( +const ObjCLanguage::MethodName _method, const DWARFDIE , +CompilerType clang_type, const ParsedDWARFTypeAttributes , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, + false)); + + if (!complete_objc_class_type_sp) +return false; + + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + + if (!type_clang_forward_type) +return false; + + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type)) +return false; + + clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType( + type_clang_forward_type, attrs.name.GetCString(), clang_type, + attrs.is_artificial, is_variadic, attrs.is_objc_direct_call); + + if (!objc_method_decl) { +dwarf->GetObjectFile()->GetModule()->ReportError( +"[{0:x16}]: invalid Objective-C method {1:x4} ({2}), " +"please file a bug and attach the file at the start of " +"this error message", +die.GetOffset(), tag, DW_TAG_value_to_name(tag)); +return false; + } + + LinkDeclContextToDIE(objc_method_decl, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + + return true; +} + +std::pair DWARFASTParserClang::ParseCXXMethod( +const DWARFDIE , CompilerType clang_type, +const ParsedDWARFTypeAttributes , const DWARFDIE _ctx_die, +bool is_static, bool _containing_context) { + Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); + SymbolFileDWARF *dwarf = die.GetDWARF(); felipepiovezan wrote: I'd also assert for this https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -975,6 +975,219 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::ParseObjCMethod( +const ObjCLanguage::MethodName _method, const DWARFDIE , +CompilerType clang_type, const ParsedDWARFTypeAttributes , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); felipepiovezan wrote: I know the previous code was not doing this, but let's take this chance to assert this is not null. https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
https://github.com/felipepiovezan approved this pull request. It's say something that, even after this refactor, the methods are still pretty big. But this is still a win https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -975,6 +975,219 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::ParseObjCMethod( +const ObjCLanguage::MethodName _method, const DWARFDIE , +CompilerType clang_type, const ParsedDWARFTypeAttributes , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, + false)); + + if (!complete_objc_class_type_sp) +return false; + + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + + if (!type_clang_forward_type) +return false; + + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type)) +return false; + + clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType( + type_clang_forward_type, attrs.name.GetCString(), clang_type, + attrs.is_artificial, is_variadic, attrs.is_objc_direct_call); + + if (!objc_method_decl) { +dwarf->GetObjectFile()->GetModule()->ReportError( +"[{0:x16}]: invalid Objective-C method {1:x4} ({2}), " +"please file a bug and attach the file at the start of " +"this error message", +die.GetOffset(), tag, DW_TAG_value_to_name(tag)); +return false; + } + + LinkDeclContextToDIE(objc_method_decl, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + + return true; +} + +std::pair DWARFASTParserClang::ParseCXXMethod( +const DWARFDIE , CompilerType clang_type, +const ParsedDWARFTypeAttributes , const DWARFDIE _ctx_die, +bool is_static, bool _containing_context) { + Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); + SymbolFileDWARF *dwarf = die.GetDWARF(); + + Type *class_type = dwarf->ResolveType(decl_ctx_die); + if (!class_type) +return {}; + + if (class_type->GetID() != decl_ctx_die.GetID() || + IsClangModuleFwdDecl(decl_ctx_die)) { + +// We uniqued the parent class of this function to another +// class so we now need to associate all dies under +// "decl_ctx_die" to DIEs in the DIE for "class_type"... +DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID()); + +if (class_type_die) { + std::vector failures; + + CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die, class_type, + failures); + + // FIXME do something with these failures that's + // smarter than just dropping them on the ground. + // Unfortunately classes don't like having stuff added + // to them after their definitions are complete... + + Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; + if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { +return {true, type_ptr->shared_from_this()}; + } felipepiovezan wrote: all the other single-statement if's here are without {} https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -975,6 +975,219 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::ParseObjCMethod( +const ObjCLanguage::MethodName _method, const DWARFDIE , +CompilerType clang_type, const ParsedDWARFTypeAttributes , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, + false)); + + if (!complete_objc_class_type_sp) +return false; + + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + + if (!type_clang_forward_type) +return false; + + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type)) +return false; + + clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType( + type_clang_forward_type, attrs.name.GetCString(), clang_type, + attrs.is_artificial, is_variadic, attrs.is_objc_direct_call); + + if (!objc_method_decl) { +dwarf->GetObjectFile()->GetModule()->ReportError( +"[{0:x16}]: invalid Objective-C method {1:x4} ({2}), " +"please file a bug and attach the file at the start of " +"this error message", +die.GetOffset(), tag, DW_TAG_value_to_name(tag)); +return false; + } + + LinkDeclContextToDIE(objc_method_decl, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + + return true; +} + +std::pair DWARFASTParserClang::ParseCXXMethod( +const DWARFDIE , CompilerType clang_type, +const ParsedDWARFTypeAttributes , const DWARFDIE _ctx_die, +bool is_static, bool _containing_context) { + Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); + SymbolFileDWARF *dwarf = die.GetDWARF(); + + Type *class_type = dwarf->ResolveType(decl_ctx_die); + if (!class_type) +return {}; + + if (class_type->GetID() != decl_ctx_die.GetID() || + IsClangModuleFwdDecl(decl_ctx_die)) { + +// We uniqued the parent class of this function to another +// class so we now need to associate all dies under +// "decl_ctx_die" to DIEs in the DIE for "class_type"... +DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID()); felipepiovezan wrote: we can reduce the scope of this variable by folding its declaration inside the if statement, it's not used outside https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [WIP][lldb] Use forward decls with redeclared definitions instead of minimal import for records (PR #95100)
Michael137 wrote: > * when you say "slower", what exactly does that mean. How much slow down are > we talking about? > * the "increased number of DWARF searches", is that due to clang asking for > definitions of types more eagerly? If yes, do you have some examples of where > are these extra definitions coming from? For example, attaching LLDB to Clang and evaluating a method on it would take ~35s instead of the baseline ~6s. One of the main contributors to this is that completing a definition for a class would try to resolve all fields *and* member functions of that class (see `DWARFASTParserClang::CompleteRecordType` where it resolves the member function DIEs). This in turn completes the parameters, etc. So we end up trying to pull in many more definitions than needed. The tricky part here is that anything that calls `getDefinition` (which we do in the `ASTImporter` for example) could trigger completion. So we can have situations where the user requests a `GetForwardCompilerType` but that ends up trying to `CompleteRedeclChain`. The current patch breaks the notion of `{Forward/Layout/Full}CompilerType`, but haven't found a good way of fixing that yet. Another source of overhead are cases where we try to find the definition DIE using a commonly used name such as `__base`, which we find many matches for in the index, but we fail to find a correct match. Such false positive lookups are quite expensive. I forget the details at the moment but IIRC this patch just makes those lookups more frequent. And the actual failure to choose the correct name for lookup is a consequence of how templates are represented in the LLDB AST. If we restrict LLDB to only complete fields (but complete methods only as needed), we get much closer to the baseline. Though "lazily" completing methods has other consequences (some features in LLDB rely on all methods being available, e.g., auto-complete, etc.). Apart from that, there still seem to be some redundant global lookups for namespaces and functions that add to the overhead. Once we get closer to the baseline performance I can provide some more accurate benchmark results. Also, happy to hear other suggestions/concerns regarding this. > * I see one test which tries to skip itself conditionally based on a setting > enabling this, but I don't see the code for the handling the setting itself. > Is the intention to add the setting, or will this be a flag day change? Good catch! I cherry-picked these commits from the `apple/llvm-project` fork where we put these changes behind a setting. But upstream I would like to avoid doing so. I'll remove the decorator from the test (we can just XPASS it) > * I'm intrigued by this line "Instead of creating partially defined records > that have fields but possibly no definition, ...". Until last week, I had > assumed that types in lldb (and clang) can exist in only one of two states > "empty/forward declared/undefined" and "fully defined". I was intrigued to > find some support for loading only fields > (`setHasLoadedFieldsFromExternalStorage`, et al.) in clang (but not in lldb, > AIUI). Does this imply that the code for loading only the fields is broken > (is the thing you're trying to remove)? Good question, I've been having trouble getting small reproducible for this. We've had numerous workarounds around the ASTImporter since the original patch was proposed that addressed these types of issues. E.g., https://reviews.llvm.org/D71378 (which isn't quite the "definition but no fields" situation, but wouldn't be surprised if historically this could've happened in some corner cases of the import mechanism). A common issue I've seen in stacktraces in the past are situtations where we started an `ASTImporter::Import`, and within that called `LoadFieldsFromExternalStorage`, which would then eventually recursively call back into `ASTImporter::Import`, messing up the various bookkeeping structures. I'll try to dig up an example of this https://github.com/llvm/llvm-project/pull/95100 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb/DWARF] Remove some dead code (PR #95127)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Pavel Labath (labath) Changes `GetDeclContextDIEs` and `DIEDeclContextsMatch` are unused (possibly since we added support for simplified template names, but I haven't checked). `GetDeclContextDIEs` is also very similar (but subtly different) from `GetDeclContext` and `GetTypeLookupContext`. I am keeping `GetParentDeclContextDIE` as that one still has some callers, but I want to look into the possibility of merging it with at least one of the functions mentioned above. --- Full diff: https://github.com/llvm/llvm-project/pull/95127.diff 4 Files Affected: - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp (-14) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h (-3) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (-89) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (-2) ``diff diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index 7cf92adc6ef57..0ef94ed9f17c3 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -367,20 +367,6 @@ lldb_private::Type *DWARFDIE::ResolveTypeUID(const DWARFDIE ) const { return nullptr; } -std::vector DWARFDIE::GetDeclContextDIEs() const { - if (!IsValid()) -return {}; - - std::vector result; - DWARFDIE parent = GetParentDeclContextDIE(); - while (parent.IsValid() && parent.GetDIE() != GetDIE()) { -result.push_back(std::move(parent)); -parent = parent.GetParentDeclContextDIE(); - } - - return result; -} - static void GetDeclContextImpl(DWARFDIE die, llvm::SmallSet , std::vector ) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h index 511ca62d0197a..c74a82061fccf 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -69,9 +69,6 @@ class DWARFDIE : public DWARFBaseDIE { DWARFDIE GetParentDeclContextDIE() const; - // DeclContext related functions - std::vector GetDeclContextDIEs() const; - /// Return this DIE's decl context as it is needed to look up types /// in Clang modules. This context will include any modules or functions that /// the type is declared in so an exact module match can be efficiently made. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index a52a7d6767374..d9e81f9c105b2 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3039,95 +3039,6 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE( return type_sp; } -// This function helps to ensure that the declaration contexts match for two -// different DIEs. Often times debug information will refer to a forward -// declaration of a type (the equivalent of "struct my_struct;". There will -// often be a declaration of that type elsewhere that has the full definition. -// When we go looking for the full type "my_struct", we will find one or more -// matches in the accelerator tables and we will then need to make sure the -// type was in the same declaration context as the original DIE. This function -// can efficiently compare two DIEs and will return true when the declaration -// context matches, and false when they don't. -bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE , - const DWARFDIE ) { - if (die1 == die2) -return true; - - std::vector decl_ctx_1; - std::vector decl_ctx_2; - // The declaration DIE stack is a stack of the declaration context DIEs all - // the way back to the compile unit. If a type "T" is declared inside a class - // "B", and class "B" is declared inside a class "A" and class "A" is in a - // namespace "lldb", and the namespace is in a compile unit, there will be a - // stack of DIEs: - // - // [0] DW_TAG_class_type for "B" - // [1] DW_TAG_class_type for "A" - // [2] DW_TAG_namespace for "lldb" - // [3] DW_TAG_compile_unit or DW_TAG_partial_unit for the source file. - // - // We grab both contexts and make sure that everything matches all the way - // back to the compiler unit. - - // First lets grab the decl contexts for both DIEs - decl_ctx_1 = die1.GetDeclContextDIEs(); - decl_ctx_2 = die2.GetDeclContextDIEs(); - // Make sure the context arrays have the same size, otherwise we are done - const size_t count1 = decl_ctx_1.size(); - const size_t count2 = decl_ctx_2.size(); - if (count1 != count2) -return false; - - // Make sure the DW_TAG values match all the way back up the compile unit. If - // they don't, then we are done. - DWARFDIE decl_ctx_die1; - DWARFDIE decl_ctx_die2; - size_t i; - for (i = 0; i <
[Lldb-commits] [lldb] [lldb/DWARF] Remove some dead code (PR #95127)
https://github.com/labath created https://github.com/llvm/llvm-project/pull/95127 `GetDeclContextDIEs` and `DIEDeclContextsMatch` are unused (possibly since we added support for simplified template names, but I haven't checked). `GetDeclContextDIEs` is also very similar (but subtly different) from `GetDeclContext` and `GetTypeLookupContext`. I am keeping `GetParentDeclContextDIE` as that one still has some callers, but I want to look into the possibility of merging it with at least one of the functions mentioned above. >From 72bee31a54df4072c5a2c4bdd83d3243bc2ac5f6 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Tue, 11 Jun 2024 16:26:24 +0200 Subject: [PATCH] [lldb/DWARF] Remove some dead code `GetDeclContextDIEs` and `DIEDeclContextsMatch` are unused (possibly since we added support for simplified template names, but I haven't checked). `GetDeclContextDIEs` is also very similar (but subtly different) from `GetDeclContext` and `GetTypeLookupContext`. I am keeping `GetParentDeclContextDIE` as that one still has some callers, but I want to look into the possibility of merging it with at least one of the functions mentioned above. --- .../Plugins/SymbolFile/DWARF/DWARFDIE.cpp | 14 --- .../Plugins/SymbolFile/DWARF/DWARFDIE.h | 3 - .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 89 --- .../SymbolFile/DWARF/SymbolFileDWARF.h| 2 - 4 files changed, 108 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index 7cf92adc6ef57..0ef94ed9f17c3 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -367,20 +367,6 @@ lldb_private::Type *DWARFDIE::ResolveTypeUID(const DWARFDIE ) const { return nullptr; } -std::vector DWARFDIE::GetDeclContextDIEs() const { - if (!IsValid()) -return {}; - - std::vector result; - DWARFDIE parent = GetParentDeclContextDIE(); - while (parent.IsValid() && parent.GetDIE() != GetDIE()) { -result.push_back(std::move(parent)); -parent = parent.GetParentDeclContextDIE(); - } - - return result; -} - static void GetDeclContextImpl(DWARFDIE die, llvm::SmallSet , std::vector ) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h index 511ca62d0197a..c74a82061fccf 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -69,9 +69,6 @@ class DWARFDIE : public DWARFBaseDIE { DWARFDIE GetParentDeclContextDIE() const; - // DeclContext related functions - std::vector GetDeclContextDIEs() const; - /// Return this DIE's decl context as it is needed to look up types /// in Clang modules. This context will include any modules or functions that /// the type is declared in so an exact module match can be efficiently made. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index a52a7d6767374..d9e81f9c105b2 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3039,95 +3039,6 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE( return type_sp; } -// This function helps to ensure that the declaration contexts match for two -// different DIEs. Often times debug information will refer to a forward -// declaration of a type (the equivalent of "struct my_struct;". There will -// often be a declaration of that type elsewhere that has the full definition. -// When we go looking for the full type "my_struct", we will find one or more -// matches in the accelerator tables and we will then need to make sure the -// type was in the same declaration context as the original DIE. This function -// can efficiently compare two DIEs and will return true when the declaration -// context matches, and false when they don't. -bool SymbolFileDWARF::DIEDeclContextsMatch(const DWARFDIE , - const DWARFDIE ) { - if (die1 == die2) -return true; - - std::vector decl_ctx_1; - std::vector decl_ctx_2; - // The declaration DIE stack is a stack of the declaration context DIEs all - // the way back to the compile unit. If a type "T" is declared inside a class - // "B", and class "B" is declared inside a class "A" and class "A" is in a - // namespace "lldb", and the namespace is in a compile unit, there will be a - // stack of DIEs: - // - // [0] DW_TAG_class_type for "B" - // [1] DW_TAG_class_type for "A" - // [2] DW_TAG_namespace for "lldb" - // [3] DW_TAG_compile_unit or DW_TAG_partial_unit for the source file. - // - // We grab both contexts and make sure that everything matches all the way - // back to the compiler unit. - - // First lets grab the decl contexts for both
[Lldb-commits] [lldb] [lldb] Do not produce field information for registers known not to exist (PR #95125)
DavidSpickett wrote: https://github.com/llvm/llvm-project/pull/85058 is the FreeBSD change, it'll get rebased onto this later. https://github.com/llvm/llvm-project/pull/95125 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Do not produce field information for registers known not to exist (PR #95125)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: David Spickett (DavidSpickett) Changes Currently the logic is generate field information for all registers in LinuxArm64RegisterFlags and then as we walk the existing register info, only those that are in that existing info will get the new fields patched in. This works fine but on a review for FreeBSD support it was pointed out that this is not obvious from the source code. So instead I've allowed the construction of empty lists of fields, and field detection methods can return an empty field list if they think that the register will never exist. Then the pre-existing code will see the empty field list, and never look for that register in the register info. I think removing the assert is ok because the GDB classes filter out empty field lists at runtime, and anyone updating the built in field information would presumably notice if none of the fields they intended to add were displayed. mte_ctrl and svcr are the only registers that need this so far. There is no extra testing here as the behaviour is the same, it doesn't add field information to regiters that don't exist. The mechanism is just clearer now. --- Full diff: https://github.com/llvm/llvm-project/pull/95125.diff 3 Files Affected: - (modified) lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp (+9-2) - (modified) lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h (+3-3) - (modified) lldb/source/Target/RegisterFlags.cpp (-4) ``diff diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp index 51553817921f3..8ed75d700f225 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp @@ -20,6 +20,7 @@ #define HWCAP2_BTI (1ULL << 17) #define HWCAP2_MTE (1ULL << 18) #define HWCAP2_AFP (1ULL << 20) +#define HWCAP2_SME (1ULL << 23) #define HWCAP2_EBF16 (1ULL << 32) using namespace lldb_private; @@ -27,7 +28,10 @@ using namespace lldb_private; LinuxArm64RegisterFlags::Fields LinuxArm64RegisterFlags::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) { (void)hwcap; - (void)hwcap2; + + if (!(hwcap2 & HWCAP2_SME)) +return {}; + // Represents the pseudo register that lldb-server builds, which itself // matches the architectural register SCVR. The fields match SVCR in the Arm // manual. @@ -40,7 +44,10 @@ LinuxArm64RegisterFlags::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) { LinuxArm64RegisterFlags::Fields LinuxArm64RegisterFlags::DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2) { (void)hwcap; - (void)hwcap2; + + if (!(hwcap2 & HWCAP2_MTE)) +return {}; + // Represents the contents of NT_ARM_TAGGED_ADDR_CTRL and the value passed // to prctl(PR_TAGGED_ADDR_CTRL...). Fields are derived from the defines // used to build the value. diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h index 660bef08700f4..49b1d90db64f6 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h @@ -38,8 +38,8 @@ class LinuxArm64RegisterFlags { /// For the registers listed in this class, detect which fields are /// present. Must be called before UpdateRegisterInfos. /// If called more than once, fields will be redetected each time from - /// scratch. If you do not have access to hwcap, just pass 0 for each one, you - /// will only get unconditional fields. + /// scratch. If the target would not have this register at all, the list of + /// fields will be left empty. void DetectFields(uint64_t hwcap, uint64_t hwcap2); /// Add the field information of any registers named in this class, @@ -63,7 +63,7 @@ class LinuxArm64RegisterFlags { struct RegisterEntry { RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector) -: m_name(name), m_flags(std::string(name) + "_flags", size, {{"", 0}}), +: m_name(name), m_flags(std::string(name) + "_flags", size, {}), m_detector(detector) {} llvm::StringRef m_name; diff --git a/lldb/source/Target/RegisterFlags.cpp b/lldb/source/Target/RegisterFlags.cpp index 5274960587bf3..de9f12649e2ec 100644 --- a/lldb/source/Target/RegisterFlags.cpp +++ b/lldb/source/Target/RegisterFlags.cpp @@ -54,10 +54,6 @@ unsigned RegisterFlags::Field::PaddingDistance(const Field ) const { } void RegisterFlags::SetFields(const std::vector ) { - // We expect that the XML processor will discard anything describing flags but - // with no fields. - assert(fields.size() && "Some fields must be provided."); - // We expect that these are unsorted but do not overlap. // They could fill the register but may have gaps. std::vector provided_fields = fields; ``
[Lldb-commits] [lldb] [lldb] Do not produce field information for registers known not to exist (PR #95125)
https://github.com/DavidSpickett ready_for_review https://github.com/llvm/llvm-project/pull/95125 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Do not produce field information for registers known not to exist (PR #95125)
https://github.com/DavidSpickett created https://github.com/llvm/llvm-project/pull/95125 Currently the logic is generate field information for all registers in LinuxArm64RegisterFlags and then as we walk the existing register info, only those that are in that existing info will get the new fields patched in. This works fine but on a review for FreeBSD support it was pointed out that this is not obvious from the source code. So instead I've allowed the construction of empty lists of fields, and field detection methods can return an empty field list if they think that the register will never exist. Then the pre-existing code will see the empty field list, and never look for that register in the register info. I think removing the assert is ok because the GDB classes filter out empty field lists at runtime, and anyone updating the built in field information would presumably notice if none of the fields they intended to add were displayed. mte_ctrl and svcr are the only registers that need this so far. There is no extra testing here as the behaviour is the same, it doesn't add field information to regiters that don't exist. The mechanism is just clearer now. >From ebfd98a3dcf80d0fd1b680407e49e95762f90741 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Tue, 11 Jun 2024 13:41:18 + Subject: [PATCH] [lldb] Do not produce field information for registers known not to exist Currently the logic is generate field information for all registers in LinuxArm64RegisterFlags and then as we walk the existing register info, only those that are in that existing info will get the new fields patched in. This works fine but on a review for FreeBSD support it was pointed out that this is not obvious from the source code. So instead I've allowed the construction of empty lists of fields, and field detection methods can return an empty field list if they think that the register will never exist. Then the pre-existing code will see the empty field list, and never look for that register in the register info. I think removing the assert is ok because the GDB classes filter out empty field lists at runtime, and anyone updating the built in field information would presumably notice if none of the fields they intended to add were displayed. mte_ctrl and svcr are the only registers that need this so far. There is no extra testing here as the behaviour is the same, it doesn't add field information to regiters that don't exist. The mechanism is just clearer now. --- .../Process/Utility/RegisterFlagsLinux_arm64.cpp | 11 +-- .../Process/Utility/RegisterFlagsLinux_arm64.h| 6 +++--- lldb/source/Target/RegisterFlags.cpp | 4 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp index 51553817921f3..8ed75d700f225 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp @@ -20,6 +20,7 @@ #define HWCAP2_BTI (1ULL << 17) #define HWCAP2_MTE (1ULL << 18) #define HWCAP2_AFP (1ULL << 20) +#define HWCAP2_SME (1ULL << 23) #define HWCAP2_EBF16 (1ULL << 32) using namespace lldb_private; @@ -27,7 +28,10 @@ using namespace lldb_private; LinuxArm64RegisterFlags::Fields LinuxArm64RegisterFlags::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) { (void)hwcap; - (void)hwcap2; + + if (!(hwcap2 & HWCAP2_SME)) +return {}; + // Represents the pseudo register that lldb-server builds, which itself // matches the architectural register SCVR. The fields match SVCR in the Arm // manual. @@ -40,7 +44,10 @@ LinuxArm64RegisterFlags::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) { LinuxArm64RegisterFlags::Fields LinuxArm64RegisterFlags::DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2) { (void)hwcap; - (void)hwcap2; + + if (!(hwcap2 & HWCAP2_MTE)) +return {}; + // Represents the contents of NT_ARM_TAGGED_ADDR_CTRL and the value passed // to prctl(PR_TAGGED_ADDR_CTRL...). Fields are derived from the defines // used to build the value. diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h index 660bef08700f4..49b1d90db64f6 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h +++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h @@ -38,8 +38,8 @@ class LinuxArm64RegisterFlags { /// For the registers listed in this class, detect which fields are /// present. Must be called before UpdateRegisterInfos. /// If called more than once, fields will be redetected each time from - /// scratch. If you do not have access to hwcap, just pass 0 for each one, you - /// will only get unconditional fields. + /// scratch. If the target would not have this register at all, the list of + ///
[Lldb-commits] [lldb] [lldb] Skip declaration DIEs in the debug_names index (PR #94744)
https://github.com/labath closed https://github.com/llvm/llvm-project/pull/94744 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] c0e1ad7 - [lldb] Skip declaration DIEs in the debug_names index (#94744)
Author: Pavel Labath Date: 2024-06-11T16:17:25+02:00 New Revision: c0e1ad779f8b7b0073b89ecdd44c3b9c4a72e494 URL: https://github.com/llvm/llvm-project/commit/c0e1ad779f8b7b0073b89ecdd44c3b9c4a72e494 DIFF: https://github.com/llvm/llvm-project/commit/c0e1ad779f8b7b0073b89ecdd44c3b9c4a72e494.diff LOG: [lldb] Skip declaration DIEs in the debug_names index (#94744) This makes sure we try to process declaration DIEs that are erroneously present in the index. Until bd5c6367bd7, clang was emitting index entries for declaration DIEs with DW_AT_signature attributes. This makes sure to avoid returning those DIEs as the definitions of a type, but also makes sure to pass through DIEs referring to static constexpr member variables, which is a (probably nonconforming) extension used by dsymutil. It adds test cases for both of the scenarios. It is essentially a recommit of #91808. Added: lldb/test/Shell/SymbolFile/DWARF/x86/debug-names-signature.s lldb/test/Shell/SymbolFile/DWARF/x86/debug-names-static-constexpr-member.s Modified: lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp Removed: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index 90e42be7202d8..1d17f20670eed 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -85,6 +85,11 @@ bool DebugNamesDWARFIndex::ProcessEntry( DWARFDIE die = GetDIE(entry); if (!die) return true; + // Clang used to erroneously emit index entries for declaration DIEs in case + // when the definition is in a type unit (llvm.org/pr77696). + if (die.IsStructUnionOrClass() && + die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0)) +return true; return callback(die); } diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug-names-signature.s b/lldb/test/Shell/SymbolFile/DWARF/x86/debug-names-signature.s new file mode 100644 index 0..7b845a72bbed4 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug-names-signature.s @@ -0,0 +1,265 @@ +## Test that we can correctly complete types even if the debug_names index +## contains entries referring to declaration dies (clang emitted entries like +## that until bd5c6367bd7). +## +## This test consists of two compile units and one type unit. CU1 has the +## definition of a variable, but only a forward-declaration of its type. When +## attempting to find a definition, the debug_names lookup will return the DIE +## in CU0, which is also a forward-declaration (with a reference to a type +## unit). LLDB needs to find the definition of the type within the type unit. + +# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s > %t +# RUN: %lldb %t -o "target variable s" -o exit | FileCheck %s + +# CHECK: (lldb) target variable s +# CHECK-NEXT: (Struct) s = (member = 47) + +.data +.p2align2, 0x0 +.long 0 +s: +.long 47 # 0x2f + +.section.debug_abbrev,"",@progbits +.byte 1 # Abbreviation Code +.byte 65 # DW_TAG_type_unit +.byte 1 # DW_CHILDREN_yes +.byte 19 # DW_AT_language +.byte 5 # DW_FORM_data2 +.byte 0 # EOM(1) +.byte 0 # EOM(2) +.byte 2 # Abbreviation Code +.byte 19 # DW_TAG_structure_type +.byte 1 # DW_CHILDREN_yes +.byte 54 # DW_AT_calling_convention +.byte 11 # DW_FORM_data1 +.byte 3 # DW_AT_name +.byte 14 # DW_FORM_strp +.byte 11 # DW_AT_byte_size +.byte 11 # DW_FORM_data1 +.byte 0 # EOM(1) +.byte 0 # EOM(2) +.byte 3 # Abbreviation Code +.byte 13 # DW_TAG_member +.byte 0 # DW_CHILDREN_no +.byte 3 # DW_AT_name +.byte 14 # DW_FORM_strp +.byte 73 # DW_AT_type +.byte 19 # DW_FORM_ref4 +.byte 56 # DW_AT_data_member_location +.byte 11 # DW_FORM_data1 +.byte
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
@@ -657,6 +657,42 @@ std::optional DWARFDebugNames::Entry::getLocalTUOffset() const { return NameIdx->getLocalTUOffset(*Index); } +std::optional +DWARFDebugNames::Entry::getForeignTUTypeSignature() const { + std::optional Index = getLocalTUIndex(); + const uint32_t NumLocalTUs = NameIdx->getLocalTUCount(); + if (!Index || *Index < NumLocalTUs) +return std::nullopt; // Invalid TU index or TU index is for a local TU + // The foreign TU index is the TU index minus the number of local TUs. + const uint64_t ForeignTUIndex = *Index - NumLocalTUs; + if (ForeignTUIndex >= NameIdx->getForeignTUCount()) +return std::nullopt; // Invalid foreign TU index. + return NameIdx->getForeignTUSignature(ForeignTUIndex); +} + +std::optional +DWARFDebugNames::Entry::getForeignTUSkeletonCUOffset() const { + // Must have a DW_IDX_type_unit and it must be a foreign type unit. + if (!getForeignTUTypeSignature()) ayermolo wrote: I guess I miss understood "Must have a DW_IDX_type_unit". I thought you meant that an entry for foreign type unit must have DW_IDX_type_unit attribute. https://github.com/llvm/llvm-project/pull/87740 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [WIP][lldb] Use forward decls with redeclared definitions instead of minimal import for records (PR #95100)
labath wrote: Thank you for working on this. I'm very interested in the results of this effort, as it appears I may end up dabbling into these parts of lldb in the near future. For now just a couple of quick questions (with hopefully not too long answers). - when you say "slower", what exactly does that mean. How much slow down are we talking about? - the "increased number of DWARF searches", is that due to clang asking for definitions of types more eagerly? If yes, do you have some examples of where are these extra definitions coming from? - I see one test which tries to skip itself conditionally based on a setting enabling this, but I don't see the code for the handling the setting itself. Is the intention to add the setting, or will this be a flag day change? - I'm intrigued by this line "Instead of creating partially defined records that have fields but possibly no definition, ...". Until last week, I had assumed that types in lldb (and clang) can exist in only one of two states "empty/forward declared/undefined" and "fully defined". I was intrigued to find some support for loading only fields (`setHasLoadedFieldsFromExternalStorage`, et al.) in clang (but not in lldb, AIUI). Does this imply that the code for loading only the fields is broken (is the thing you're trying to remove)? https://github.com/llvm/llvm-project/pull/95100 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Added "port" property to vscode "attach" command. (PR #91570)
walter-erquinigo wrote: I'll review this today or tomorrow. Thanks for all the activity! https://github.com/llvm/llvm-project/pull/91570 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [WIP][lldb] Use forward decls with redeclared definitions instead of minimal import for records (PR #95100)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 97cfe549c9a9ec3880c984bd4d2ddbbd92dcb9a0 2d90c9f4bf29f7de7db3df115d505db4b674649c -- lldb/source/Plugins/TypeSystem/Clang/ImporterBackedASTSource.cpp lldb/source/Plugins/TypeSystem/Clang/ImporterBackedASTSource.h lldb/unittests/TypeSystem/Clang/TestClangRedeclarations.cpp lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.h lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h `` View the diff from clang-format here. ``diff diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h index bc950cc7a0..98d2ff66b7 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h @@ -9,8 +9,8 @@ #ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_ASTUTILS_H -#include "clang/Basic/ASTSourceDescriptor.h" #include "Plugins/TypeSystem/Clang/ImporterBackedASTSource.h" +#include "clang/Basic/ASTSourceDescriptor.h" #include "clang/Basic/Module.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/MultiplexExternalSemaSource.h" diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp index 913fd50d4c..722df69615 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp @@ -836,10 +836,9 @@ bool ClangASTImporter::CompleteObjCInterfaceDecl( if (result) return true; - llvm::handleAllErrors(result.takeError(), -[](const clang::ASTImportError ) { - llvm::errs() << "ERR: " << e.toString() << "\n"; -}); + llvm::handleAllErrors(result.takeError(), [](const clang::ASTImportError ) { +llvm::errs() << "ERR: " << e.toString() << "\n"; + }); return false; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 08e0ec6ffc..f7179b14c1 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -277,7 +277,8 @@ static void PrepareContextToReceiveMembers(TypeSystemClang , // We have already completed the type, or we have found its definition and are // ready to complete it later (cf. ParseStructureLikeDIE). - if (tag_decl_ctx->getDefinition() != nullptr || tag_decl_ctx->isBeingDefined()) + if (tag_decl_ctx->getDefinition() != nullptr || + tag_decl_ctx->isBeingDefined()) return; // We reach this point of the tag was present in the debug info as a @@ -491,7 +492,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext , if (type_ptr) return type_ptr->shared_from_this(); // Set a bit that lets us know that we are currently parsing this -//dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; + // dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; ParsedDWARFTypeAttributes attrs(die); @@ -1228,8 +1229,8 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE , llvm::PrettyStackTraceFormat stack_trace( "SymbolFileDWARF::ParseType() is adding a method " "%s to class %s in DIE 0x%8.8" PRIx64 " from %s", -attrs.name.GetCString(), -class_type->GetName().GetCString(), die.GetID(), +attrs.name.GetCString(), class_type->GetName().GetCString(), +die.GetID(), dwarf->GetObjectFile()->GetFileSpec().GetPath().c_str()); const bool is_attr_used = false; @@ -1243,10 +1244,10 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE , clang::CXXMethodDecl
[Lldb-commits] [lldb] [WIP][lldb] Use forward decls with redeclared definitions instead of minimal import for records (PR #95100)
github-actions[bot] wrote: :warning: Python code formatter, darker found issues in your code. :warning: You can test this locally with the following command: ``bash darker --check --diff -r 97cfe549c9a9ec3880c984bd4d2ddbbd92dcb9a0...2d90c9f4bf29f7de7db3df115d505db4b674649c lldb/test/API/lang/cpp/reference-to-outer-type/TestCppReferenceToOuterClass.py `` View the diff from darker here. ``diff --- TestCppReferenceToOuterClass.py 2024-06-11 10:58:48.00 + +++ TestCppReferenceToOuterClass.py 2024-06-11 12:03:33.657545 + @@ -4,11 +4,13 @@ from lldbsuite.test.lldbtest import * from lldbsuite.test import lldbutil class TestCase(TestBase): - @expectedFailureAll(setting=('plugin.typesystem.clang.experimental-redecl-completion', 'false')) +@expectedFailureAll( +setting=("plugin.typesystem.clang.experimental-redecl-completion", "false") +) def test(self): self.build() self.dbg.CreateTarget(self.getBuildArtifact("a.out")) test_var = self.expect_expr("test_var", result_type="In") nested_member = test_var.GetChildMemberWithName("NestedClassMember") `` https://github.com/llvm/llvm-project/pull/95100 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/95078 >From 75d1bc01ca42e327594cceba753bec483228efbd Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 10 Jun 2024 17:46:31 +0100 Subject: [PATCH 1/4] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine This patch moves some of the `is_cxx_method`/`objc_method` logic out of `DWARFASTParserClang::ParseSubroutine` into their own functions. Mainly the purpose of this is to (hopefully) make this function more readable by turning the deeply nested if-statements into early-returns. This will be useful in an upcoming change where we remove some of the branches of said if-statement. --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 447 +- .../SymbolFile/DWARF/DWARFASTParserClang.h| 15 + 2 files changed, 251 insertions(+), 211 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 579a538af3634..585ae4e58cc1a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -975,6 +975,226 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::HandleObjCMethod( +ObjCLanguage::MethodName const _method, DWARFDIE const , +CompilerType clang_type, ParsedDWARFTypeAttributes const , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, + false)); + + if (!complete_objc_class_type_sp) +return false; + + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + + if (!type_clang_forward_type) +return false; + + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type)) +return false; + + clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType( + type_clang_forward_type, attrs.name.GetCString(), clang_type, + attrs.is_artificial, is_variadic, attrs.is_objc_direct_call); + + if (!objc_method_decl) { +dwarf->GetObjectFile()->GetModule()->ReportError( +"[{0:x16}]: invalid Objective-C method {1:x4} ({2}), " +"please file a bug and attach the file at the start of " +"this error message", +die.GetOffset(), tag, DW_TAG_value_to_name(tag)); +return false; + } + + LinkDeclContextToDIE(objc_method_decl, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + + return true; +} + +std::pair DWARFASTParserClang::HandleCXXMethod( +DWARFDIE const , CompilerType clang_type, +ParsedDWARFTypeAttributes const , DWARFDIE const _ctx_die, +bool is_static, bool _containing_context) { + Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); + SymbolFileDWARF *dwarf = die.GetDWARF(); + // Look at the parent of this DIE and see if it is a class or + // struct and see if this is actually a C++ method + Type *class_type = dwarf->ResolveType(decl_ctx_die); + if (!class_type) +return {}; + + if (class_type->GetID() != decl_ctx_die.GetID() || + IsClangModuleFwdDecl(decl_ctx_die)) { + +// We uniqued the parent class of this function to another +// class so we now need to associate all dies under +// "decl_ctx_die" to DIEs in the DIE for "class_type"... +DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID()); + +if (class_type_die) { + std::vector failures; + + CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die, class_type, + failures); + + // FIXME do something with these failures that's + // smarter than just dropping them on the ground. + // Unfortunately classes don't like having stuff added + // to them after their definitions are complete... + + Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; + if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { +return {true, type_ptr->shared_from_this()}; + } +} + } + + if (attrs.specification.IsValid()) { +// We have a specification which we are going to base our +// function prototype off of, so we need this type to be +// completed so that the m_die_to_decl_ctx for the method in +// the specification has a valid clang decl context. +class_type->GetForwardCompilerType(); +// If we have a specification, then the function type should +// have been made with the specification and not with this +// die. +DWARFDIE spec_die = attrs.specification.Reference(); +clang::DeclContext *spec_clang_decl_ctx = +GetClangDeclContextForDIE(spec_die);
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/95078 >From 75d1bc01ca42e327594cceba753bec483228efbd Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Mon, 10 Jun 2024 17:46:31 +0100 Subject: [PATCH 1/3] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine This patch moves some of the `is_cxx_method`/`objc_method` logic out of `DWARFASTParserClang::ParseSubroutine` into their own functions. Mainly the purpose of this is to (hopefully) make this function more readable by turning the deeply nested if-statements into early-returns. This will be useful in an upcoming change where we remove some of the branches of said if-statement. --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 447 +- .../SymbolFile/DWARF/DWARFASTParserClang.h| 15 + 2 files changed, 251 insertions(+), 211 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 579a538af3634..585ae4e58cc1a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -975,6 +975,226 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::HandleObjCMethod( +ObjCLanguage::MethodName const _method, DWARFDIE const , +CompilerType clang_type, ParsedDWARFTypeAttributes const , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, + false)); + + if (!complete_objc_class_type_sp) +return false; + + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + + if (!type_clang_forward_type) +return false; + + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type)) +return false; + + clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType( + type_clang_forward_type, attrs.name.GetCString(), clang_type, + attrs.is_artificial, is_variadic, attrs.is_objc_direct_call); + + if (!objc_method_decl) { +dwarf->GetObjectFile()->GetModule()->ReportError( +"[{0:x16}]: invalid Objective-C method {1:x4} ({2}), " +"please file a bug and attach the file at the start of " +"this error message", +die.GetOffset(), tag, DW_TAG_value_to_name(tag)); +return false; + } + + LinkDeclContextToDIE(objc_method_decl, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + + return true; +} + +std::pair DWARFASTParserClang::HandleCXXMethod( +DWARFDIE const , CompilerType clang_type, +ParsedDWARFTypeAttributes const , DWARFDIE const _ctx_die, +bool is_static, bool _containing_context) { + Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); + SymbolFileDWARF *dwarf = die.GetDWARF(); + // Look at the parent of this DIE and see if it is a class or + // struct and see if this is actually a C++ method + Type *class_type = dwarf->ResolveType(decl_ctx_die); + if (!class_type) +return {}; + + if (class_type->GetID() != decl_ctx_die.GetID() || + IsClangModuleFwdDecl(decl_ctx_die)) { + +// We uniqued the parent class of this function to another +// class so we now need to associate all dies under +// "decl_ctx_die" to DIEs in the DIE for "class_type"... +DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID()); + +if (class_type_die) { + std::vector failures; + + CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die, class_type, + failures); + + // FIXME do something with these failures that's + // smarter than just dropping them on the ground. + // Unfortunately classes don't like having stuff added + // to them after their definitions are complete... + + Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; + if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { +return {true, type_ptr->shared_from_this()}; + } +} + } + + if (attrs.specification.IsValid()) { +// We have a specification which we are going to base our +// function prototype off of, so we need this type to be +// completed so that the m_die_to_decl_ctx for the method in +// the specification has a valid clang decl context. +class_type->GetForwardCompilerType(); +// If we have a specification, then the function type should +// have been made with the specification and not with this +// die. +DWARFDIE spec_die = attrs.specification.Reference(); +clang::DeclContext *spec_clang_decl_ctx = +GetClangDeclContextForDIE(spec_die);
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -975,6 +975,226 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::HandleObjCMethod( +ObjCLanguage::MethodName const _method, DWARFDIE const , +CompilerType clang_type, ParsedDWARFTypeAttributes const , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, + false)); + + if (!complete_objc_class_type_sp) +return false; + + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + + if (!type_clang_forward_type) +return false; + + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type)) +return false; + + clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType( + type_clang_forward_type, attrs.name.GetCString(), clang_type, + attrs.is_artificial, is_variadic, attrs.is_objc_direct_call); + + if (!objc_method_decl) { +dwarf->GetObjectFile()->GetModule()->ReportError( +"[{0:x16}]: invalid Objective-C method {1:x4} ({2}), " +"please file a bug and attach the file at the start of " +"this error message", +die.GetOffset(), tag, DW_TAG_value_to_name(tag)); +return false; + } + + LinkDeclContextToDIE(objc_method_decl, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + + return true; +} + +std::pair DWARFASTParserClang::HandleCXXMethod( +DWARFDIE const , CompilerType clang_type, +ParsedDWARFTypeAttributes const , DWARFDIE const _ctx_die, +bool is_static, bool _containing_context) { + Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); + SymbolFileDWARF *dwarf = die.GetDWARF(); + // Look at the parent of this DIE and see if it is a class or + // struct and see if this is actually a C++ method + Type *class_type = dwarf->ResolveType(decl_ctx_die); + if (!class_type) +return {}; labath wrote: The difference I guess is that that check just looks at whether we're syntactically within a DW_TAG_class_type, whereas this checks whether we were able to resolve that TAG into an actual type. I don't know of a specific reason why that could fail, however. So yeah, maybe just remove the comment. https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -975,6 +975,226 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::HandleObjCMethod( +ObjCLanguage::MethodName const _method, DWARFDIE const , +CompilerType clang_type, ParsedDWARFTypeAttributes const , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, + false)); + + if (!complete_objc_class_type_sp) +return false; + + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + + if (!type_clang_forward_type) +return false; + + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type)) +return false; + + clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType( + type_clang_forward_type, attrs.name.GetCString(), clang_type, + attrs.is_artificial, is_variadic, attrs.is_objc_direct_call); + + if (!objc_method_decl) { +dwarf->GetObjectFile()->GetModule()->ReportError( +"[{0:x16}]: invalid Objective-C method {1:x4} ({2}), " +"please file a bug and attach the file at the start of " +"this error message", +die.GetOffset(), tag, DW_TAG_value_to_name(tag)); +return false; + } + + LinkDeclContextToDIE(objc_method_decl, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + + return true; +} + +std::pair DWARFASTParserClang::HandleCXXMethod( +DWARFDIE const , CompilerType clang_type, +ParsedDWARFTypeAttributes const , DWARFDIE const _ctx_die, +bool is_static, bool _containing_context) { + Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); + SymbolFileDWARF *dwarf = die.GetDWARF(); + // Look at the parent of this DIE and see if it is a class or + // struct and see if this is actually a C++ method + Type *class_type = dwarf->ResolveType(decl_ctx_die); + if (!class_type) +return {}; + + if (class_type->GetID() != decl_ctx_die.GetID() || + IsClangModuleFwdDecl(decl_ctx_die)) { + +// We uniqued the parent class of this function to another +// class so we now need to associate all dies under +// "decl_ctx_die" to DIEs in the DIE for "class_type"... +DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID()); + +if (class_type_die) { + std::vector failures; + + CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die, class_type, + failures); + + // FIXME do something with these failures that's + // smarter than just dropping them on the ground. + // Unfortunately classes don't like having stuff added + // to them after their definitions are complete... + + Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; + if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { +return {true, type_ptr->shared_from_this()}; + } +} + } + + if (attrs.specification.IsValid()) { +// We have a specification which we are going to base our +// function prototype off of, so we need this type to be +// completed so that the m_die_to_decl_ctx for the method in +// the specification has a valid clang decl context. +class_type->GetForwardCompilerType(); +// If we have a specification, then the function type should +// have been made with the specification and not with this +// die. +DWARFDIE spec_die = attrs.specification.Reference(); +clang::DeclContext *spec_clang_decl_ctx = +GetClangDeclContextForDIE(spec_die); +if (spec_clang_decl_ctx) { + LinkDeclContextToDIE(spec_clang_decl_ctx, die); +} else { + dwarf->GetObjectFile()->GetModule()->ReportWarning( + "{0:x8}: DW_AT_specification({1:x16}" + ") has no decl\n", + die.GetID(), spec_die.GetOffset()); +} +return {true, nullptr}; + } + + if (attrs.abstract_origin.IsValid()) { +// We have a specification which we are going to base our +// function prototype off of, so we need this type to be +// completed so that the m_die_to_decl_ctx for the method in +// the abstract origin has a valid clang decl context. +class_type->GetForwardCompilerType(); + +DWARFDIE abs_die = attrs.abstract_origin.Reference(); +clang::DeclContext *abs_clang_decl_ctx = GetClangDeclContextForDIE(abs_die); +if (abs_clang_decl_ctx) { + LinkDeclContextToDIE(abs_clang_decl_ctx, die); +} else { + dwarf->GetObjectFile()->GetModule()->ReportWarning( + "{0:x8}: DW_AT_abstract_origin({1:x16}" + ") has no decl\n", + die.GetID(), abs_die.GetOffset()); +} + +return {true, nullptr}; + } + + CompilerType class_opaque_type =
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -975,6 +975,226 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::HandleObjCMethod( +ObjCLanguage::MethodName const _method, DWARFDIE const , +CompilerType clang_type, ParsedDWARFTypeAttributes const , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, + false)); + + if (!complete_objc_class_type_sp) +return false; + + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + + if (!type_clang_forward_type) +return false; + + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type)) +return false; + + clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType( + type_clang_forward_type, attrs.name.GetCString(), clang_type, + attrs.is_artificial, is_variadic, attrs.is_objc_direct_call); + + if (!objc_method_decl) { +dwarf->GetObjectFile()->GetModule()->ReportError( +"[{0:x16}]: invalid Objective-C method {1:x4} ({2}), " +"please file a bug and attach the file at the start of " +"this error message", +die.GetOffset(), tag, DW_TAG_value_to_name(tag)); +return false; + } + + LinkDeclContextToDIE(objc_method_decl, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + + return true; +} + +std::pair DWARFASTParserClang::HandleCXXMethod( +DWARFDIE const , CompilerType clang_type, +ParsedDWARFTypeAttributes const , DWARFDIE const _ctx_die, +bool is_static, bool _containing_context) { + Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); + SymbolFileDWARF *dwarf = die.GetDWARF(); + // Look at the parent of this DIE and see if it is a class or + // struct and see if this is actually a C++ method + Type *class_type = dwarf->ResolveType(decl_ctx_die); + if (!class_type) +return {}; Michael137 wrote: The comment on line 1029 is a bit misleading if my read of this is correct. I'm not sure how failing to call `ResolveType(decl_ctx_die)` would imply that we're not dealing with a C++ method. We already determined this on line 1237 AFAICT. Should we just remove this comment? https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -370,6 +371,20 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser { ParsedDWARFTypeAttributes ); lldb::TypeSP ParseSubroutine(const lldb_private::plugin::dwarf::DWARFDIE , const ParsedDWARFTypeAttributes ); + + bool + HandleObjCMethod(lldb_private::ObjCLanguage::MethodName const _method, + lldb_private::plugin::dwarf::DWARFDIE const , + lldb_private::CompilerType clang_type, + ParsedDWARFTypeAttributes const , bool is_variadic); + + std::pair + HandleCXXMethod(lldb_private::plugin::dwarf::DWARFDIE const , Michael137 wrote: > Is that all the function does? It seems to be doing a bit more, so maybe > something with the word Parse in it might be better. True, could go for `ParseCXXMethod` I suppose > I can't really say anything confidently, since I don't really understand this > code, even though I've spend a lot of time staring at it last week. Sadly having the same experience https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -975,6 +975,226 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::HandleObjCMethod( +ObjCLanguage::MethodName const _method, DWARFDIE const , +CompilerType clang_type, ParsedDWARFTypeAttributes const , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, + false)); + + if (!complete_objc_class_type_sp) +return false; + + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + + if (!type_clang_forward_type) +return false; + + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type)) +return false; + + clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType( + type_clang_forward_type, attrs.name.GetCString(), clang_type, + attrs.is_artificial, is_variadic, attrs.is_objc_direct_call); + + if (!objc_method_decl) { +dwarf->GetObjectFile()->GetModule()->ReportError( +"[{0:x16}]: invalid Objective-C method {1:x4} ({2}), " +"please file a bug and attach the file at the start of " +"this error message", +die.GetOffset(), tag, DW_TAG_value_to_name(tag)); +return false; + } + + LinkDeclContextToDIE(objc_method_decl, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + + return true; +} + +std::pair DWARFASTParserClang::HandleCXXMethod( +DWARFDIE const , CompilerType clang_type, +ParsedDWARFTypeAttributes const , DWARFDIE const _ctx_die, +bool is_static, bool _containing_context) { + Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); + SymbolFileDWARF *dwarf = die.GetDWARF(); + // Look at the parent of this DIE and see if it is a class or + // struct and see if this is actually a C++ method + Type *class_type = dwarf->ResolveType(decl_ctx_die); + if (!class_type) +return {}; + + if (class_type->GetID() != decl_ctx_die.GetID() || + IsClangModuleFwdDecl(decl_ctx_die)) { + +// We uniqued the parent class of this function to another +// class so we now need to associate all dies under +// "decl_ctx_die" to DIEs in the DIE for "class_type"... +DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID()); + +if (class_type_die) { + std::vector failures; + + CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die, class_type, + failures); + + // FIXME do something with these failures that's + // smarter than just dropping them on the ground. + // Unfortunately classes don't like having stuff added + // to them after their definitions are complete... + + Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; + if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { +return {true, type_ptr->shared_from_this()}; + } +} + } + + if (attrs.specification.IsValid()) { +// We have a specification which we are going to base our +// function prototype off of, so we need this type to be +// completed so that the m_die_to_decl_ctx for the method in +// the specification has a valid clang decl context. +class_type->GetForwardCompilerType(); +// If we have a specification, then the function type should +// have been made with the specification and not with this +// die. +DWARFDIE spec_die = attrs.specification.Reference(); +clang::DeclContext *spec_clang_decl_ctx = +GetClangDeclContextForDIE(spec_die); +if (spec_clang_decl_ctx) { + LinkDeclContextToDIE(spec_clang_decl_ctx, die); +} else { + dwarf->GetObjectFile()->GetModule()->ReportWarning( + "{0:x8}: DW_AT_specification({1:x16}" + ") has no decl\n", + die.GetID(), spec_die.GetOffset()); +} +return {true, nullptr}; + } + + if (attrs.abstract_origin.IsValid()) { +// We have a specification which we are going to base our +// function prototype off of, so we need this type to be +// completed so that the m_die_to_decl_ctx for the method in +// the abstract origin has a valid clang decl context. +class_type->GetForwardCompilerType(); + +DWARFDIE abs_die = attrs.abstract_origin.Reference(); +clang::DeclContext *abs_clang_decl_ctx = GetClangDeclContextForDIE(abs_die); +if (abs_clang_decl_ctx) { + LinkDeclContextToDIE(abs_clang_decl_ctx, die); +} else { + dwarf->GetObjectFile()->GetModule()->ReportWarning( + "{0:x8}: DW_AT_abstract_origin({1:x16}" + ") has no decl\n", + die.GetID(), abs_die.GetOffset()); +} + +return {true, nullptr}; + } + + CompilerType class_opaque_type =
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -975,6 +975,226 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::HandleObjCMethod( +ObjCLanguage::MethodName const _method, DWARFDIE const , labath wrote: I believe we normally put `const` before the type name. https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -370,6 +371,20 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser { ParsedDWARFTypeAttributes ); lldb::TypeSP ParseSubroutine(const lldb_private::plugin::dwarf::DWARFDIE , const ParsedDWARFTypeAttributes ); + + bool + HandleObjCMethod(lldb_private::ObjCLanguage::MethodName const _method, + lldb_private::plugin::dwarf::DWARFDIE const , + lldb_private::CompilerType clang_type, + ParsedDWARFTypeAttributes const , bool is_variadic); + + std::pair + HandleCXXMethod(lldb_private::plugin::dwarf::DWARFDIE const , labath wrote: > LinkCXXMethodDeclContextToDIE Is that all the function does? It seems to be doing a bit more, so maybe something with the word `Parse` in it might be better. I can't really say anything confidently, since I don't really understand this code, even though I've spend a lot of time staring at it last week. https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
https://github.com/labath commented: I can't say if this is the right split, but I think we should try something, as this function is long overdue for an overhaul. https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -975,6 +975,226 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::HandleObjCMethod( +ObjCLanguage::MethodName const _method, DWARFDIE const , +CompilerType clang_type, ParsedDWARFTypeAttributes const , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, + false)); + + if (!complete_objc_class_type_sp) +return false; + + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + + if (!type_clang_forward_type) +return false; + + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type)) +return false; + + clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType( + type_clang_forward_type, attrs.name.GetCString(), clang_type, + attrs.is_artificial, is_variadic, attrs.is_objc_direct_call); + + if (!objc_method_decl) { +dwarf->GetObjectFile()->GetModule()->ReportError( +"[{0:x16}]: invalid Objective-C method {1:x4} ({2}), " +"please file a bug and attach the file at the start of " +"this error message", +die.GetOffset(), tag, DW_TAG_value_to_name(tag)); +return false; + } + + LinkDeclContextToDIE(objc_method_decl, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + + return true; +} + +std::pair DWARFASTParserClang::HandleCXXMethod( +DWARFDIE const , CompilerType clang_type, +ParsedDWARFTypeAttributes const , DWARFDIE const _ctx_die, +bool is_static, bool _containing_context) { + Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); + SymbolFileDWARF *dwarf = die.GetDWARF(); + // Look at the parent of this DIE and see if it is a class or + // struct and see if this is actually a C++ method + Type *class_type = dwarf->ResolveType(decl_ctx_die); + if (!class_type) +return {}; labath wrote: Maybe this should be outside of the function, since going through the branch means we're not actually processing a method. https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
https://github.com/labath edited https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix type lookup bug where wrong decl context was being used for a DIE. (PR #94846)
https://github.com/labath approved this pull request. Thanks. https://github.com/llvm/llvm-project/pull/94846 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix type lookup bug where wrong decl context was being used for a DIE. (PR #94846)
@@ -0,0 +1,69 @@ +""" +Test the SBModule and SBTarget type lookup APIs to find multiple types. +""" + +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TypeFindFirstTestCase(TestBase): +def test_find_first_type(self): +""" +Test SBTarget::FindTypes() and SBModule::FindTypes() APIs. + +We had issues where our declaration context when finding types was +incorrectly calculated where a type in a namepace, and a type in a +function that was also in the same namespace would match a lookup. For +example: + +namespace a { + struct Foo { +int foo; + }; + + unsigned foo() { +typedef unsigned Foo; +Foo foo = 12; +return foo; + } +} // namespace a + + +Previously LLDB would calculate the declaration context of "a::Foo" +correctly, but incorrectly calculate the declaration context of "Foo" +from within the foo() function as "a::Foo". Adding tests to ensure this +works correctly. +""" +self.build() +target = self.createTestTarget() +exe_module = target.GetModuleAtIndex(0) +self.assertTrue(exe_module.IsValid()) +# Test the SBTarget and SBModule APIs for FindFirstType +for api in [target, exe_module]: +# We should find the "a::Foo" but not the "Foo" type in the function +types = api.FindTypes("a::Foo") +self.assertEqual(types.GetSize(), 1) +type_str0 = str(types.GetTypeAtIndex(0)) +self.assertIn('struct Foo', type_str0) + +# When we search by type basename, we should find any type whose +# basename matches "Foo", so "a::Foo" and the "Foo" type in the +# function. +types = api.FindTypes("Foo") +self.assertEqual(types.GetSize(), 2) +type_str0 = str(types.GetTypeAtIndex(0)) +type_str1 = str(types.GetTypeAtIndex(1)) +# We don't know which order the types will come back as, so +if 'struct Foo' in type_str0: +self.assertIn('typedef Foo', type_str1) +else: +self.assertIn('struct Foo', type_str1) + +# When we search by type basename with "::" prepended, we should +# only types in the root namespace which means only "Foo" type in labath wrote: > So I don't know of anyone that would use the function name when asking for a > type, even if that type was defined in a function. It's certainly not valid C++, if that's what you mean (c++ just doesn't give you the option of referring to a local type from outside of the function), but I don't think this kind of qualification is a revolutionary concept. For example if the aforementioned local struct had a constructor, it's mangled name would be `_ZZN1a3fooEvEN3FooC1Ev `, that is `a::foo()::Foo::Foo()`. Gdb (AFAICT) does not support these kinds of lookups, but it also does not return the type for query like `::Foo`. (instead gdb supports searching for a type in a specific block/function, which is kind of similar to this) > To make the expression parser work, we should be able to find all of the > types using a context like just "Foo", where we would find both `::Foo` and > the `Foo` from `a::foo()`, but sort the results based on the > CompilerDeclContext of each type that was returned. If we are evaluating an > expression in `a::foo()`, the `Foo` type from that function could tell us the > CompilerDeclContext it was defined in and we would find the closest match to > where the expression is being run. This approach has the problem that a type (or really, anything) defined with the same name at a class level would take precedence over a local declaration. For example with code like: ``` struct Foo { int one; } class Class { struct Foo { int two; } void Method() { struct Foo { int three; } } }; ``` if we were stopped in `Class::Method`, then the name `Foo` should refer to the third definition with that name, but I believe this will end up using the second one because clang will see the class-level declaration first and will not bother asking for other possible definitions. I think we used to use the same approach for local variables, but then we changed the implementation because of the same shadowing problem. https://github.com/llvm/llvm-project/pull/94846 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Added "port" property to vscode "attach" command. (PR #91570)
https://github.com/labath approved this pull request. My concerns have been addressed (*), so I'm removing my request for changes. It looks like the only way to do that is to Approve the PR, but I'd suggest getting another approval from a lldb-dap owner as well. (*) There is still the question of the single "url" setting (to rule them all), but I don't consider myself an authority there. https://github.com/llvm/llvm-project/pull/91570 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Added "port" property to vscode "attach" command. (PR #91570)
@@ -672,9 +672,14 @@ void request_attach(const llvm::json::Object ) { lldb::SBError error; FillResponse(request, response); lldb::SBAttachInfo attach_info; + const int invalid_port = 0; auto arguments = request.getObject("arguments"); const lldb::pid_t pid = GetUnsigned(arguments, "pid", LLDB_INVALID_PROCESS_ID); + const auto gdb_remote_port = + GetUnsigned(arguments, "gdb-remote-port", invalid_port); + llvm::StringRef gdb_remote_hostname = + GetString(arguments, "gdb-remote-hostname", "localhost"); labath wrote: There are environments (Google's (default) test environment is like that) that don't have an IPv4 stack configured (just v6), so `localhost` would be an advantage there. That said, this definitely wouldn't be the first instance of `127.0.0.1 in lldb. FWIW, I'm of the opinion that anyone who configures `localhost` to point to something other than their local host deserves whatever is coming their way, https://github.com/llvm/llvm-project/pull/91570 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Added "port" property to vscode "attach" command. (PR #91570)
https://github.com/labath edited https://github.com/llvm/llvm-project/pull/91570 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Added "port" property to vscode "attach" command. (PR #91570)
@@ -0,0 +1,202 @@ +""" +Test lldb-dap "port" configuration to "attach" request +""" + + +import dap_server +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +from lldbsuite.test import lldbplatformutil +import lldbdap_testcase +import os +import shutil +import subprocess +import tempfile +import threading +import sys +import socket +import select + + +# A class representing a pipe for communicating with debug server. +# This class includes menthods to open the pipe and read the port number from it. +class Pipe(object): +def __init__(self, prefix): +self.name = os.path.join(prefix, "stub_port_number") +os.mkfifo(self.name) +self._fd = os.open(self.name, os.O_RDONLY | os.O_NONBLOCK) + +def finish_connection(self, timeout): +pass + +def read(self, size, timeout): +(readers, _, _) = select.select([self._fd], [], [], timeout) +if self._fd not in readers: +raise TimeoutError +return os.read(self._fd, size) + +def close(self): +os.close(self._fd) labath wrote: Thanks. Glad we got that resolved. https://github.com/llvm/llvm-project/pull/91570 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -370,6 +371,20 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser { ParsedDWARFTypeAttributes ); lldb::TypeSP ParseSubroutine(const lldb_private::plugin::dwarf::DWARFDIE , const ParsedDWARFTypeAttributes ); + + bool + HandleObjCMethod(lldb_private::ObjCLanguage::MethodName const _method, + lldb_private::plugin::dwarf::DWARFDIE const , + lldb_private::CompilerType clang_type, + ParsedDWARFTypeAttributes const , bool is_variadic); + + std::pair + HandleCXXMethod(lldb_private::plugin::dwarf::DWARFDIE const , Michael137 wrote: The names `HandleCXXMethod` and `HandleObjCMethod` feel a bit generic. Possibly something like `LinkCXXMethodDeclContextToDIE` would be better? https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] baad1b8 - [lldb] Add a test for lea_rsp_pattern_p to x86 unwinder (NFC) (#94852)
Author: Shivam Gupta Date: 2024-06-11T12:52:32+05:30 New Revision: baad1b85b93c0b5ce0341668259ae21911bed8b1 URL: https://github.com/llvm/llvm-project/commit/baad1b85b93c0b5ce0341668259ae21911bed8b1 DIFF: https://github.com/llvm/llvm-project/commit/baad1b85b93c0b5ce0341668259ae21911bed8b1.diff LOG: [lldb] Add a test for lea_rsp_pattern_p to x86 unwinder (NFC) (#94852) This commit adds a test for lea_rsp_pattern_p which was previously due as FIXME. Added: Modified: lldb/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp Removed: diff --git a/lldb/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp b/lldb/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp index 277cc14ce50c9..597e5b2e40d5e 100644 --- a/lldb/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp +++ b/lldb/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp @@ -1731,7 +1731,29 @@ TEST_F(Testx86AssemblyInspectionEngine, TestAddESP) { EXPECT_EQ(4 - 16, row_sp->GetCFAValue().GetOffset()); } -// FIXME add test for lea_rsp_pattern_p +TEST_F(Testx86AssemblyInspectionEngine, TestLEA_RSP_Pattern) { + UnwindPlan::Row::RegisterLocation regloc; + UnwindPlan::RowSP row_sp; + AddressRange sample_range; + UnwindPlan unwind_plan(eRegisterKindLLDB); + std::unique_ptr engine = Getx86_64Inspector(); + + uint8_t data[] = { + 0x8d, 0x64, 0x24, 0x10, // lea rsp, [rsp + 0x10] + 0x90// nop + }; + + sample_range = AddressRange(0x1000, sizeof(data)); + + EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly( + data, sizeof(data), sample_range, unwind_plan)); + + row_sp = unwind_plan.GetRowForFunctionOffset(0); + EXPECT_EQ(0ull, row_sp->GetOffset()); + EXPECT_TRUE(row_sp->GetCFAValue().GetRegisterNumber() == k_rsp); + EXPECT_TRUE(row_sp->GetCFAValue().IsRegisterPlusOffset() == true); + EXPECT_EQ(8, row_sp->GetCFAValue().GetOffset()); +} TEST_F(Testx86AssemblyInspectionEngine, TestPopRBX) { UnwindPlan::Row::RegisterLocation regloc; ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a test for lea_rsp_pattern_p to x86 unwinder (NFC) (PR #94852)
https://github.com/xgupta closed https://github.com/llvm/llvm-project/pull/94852 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a test for lea_rsp_pattern_p to x86 unwinder (NFC) (PR #94852)
xgupta wrote: Thanks @jasonmolenda for the review. I do have commit access to merge it. https://github.com/llvm/llvm-project/pull/94852 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
@@ -370,6 +371,20 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser { ParsedDWARFTypeAttributes ); lldb::TypeSP ParseSubroutine(const lldb_private::plugin::dwarf::DWARFDIE , const ParsedDWARFTypeAttributes ); + + bool + HandleObjCMethod(lldb_private::ObjCLanguage::MethodName const _method, + lldb_private::plugin::dwarf::DWARFDIE const , + lldb_private::CompilerType clang_type, + ParsedDWARFTypeAttributes const , bool is_variadic); Michael137 wrote: Will add docs once we settle on signatures, etc. https://github.com/llvm/llvm-project/pull/95078 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParser][NFC] Factor out CXX/ObjC method specifics out of ParseSubroutine (PR #95078)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Michael Buch (Michael137) Changes This patch moves some of the `is_cxx_method`/`objc_method` logic out of `DWARFASTParserClang::ParseSubroutine` into their own functions. Mainly the purpose of this is to (hopefully) make this function more readable by turning the deeply nested if-statements into early-returns. This will be useful in an upcoming change where we remove some of the branches of said if-statement. Considerations: * Would be nice to make them into static helpers in `DWARFASTParserClang.cpp`. That would require them take few more arguments which seemed to get unwieldy. * `HandleCXXMethod` can return three states: (1) found a `TypeSP` we previously parsed (2) successfully set a link between the DIE and DeclContext (3) failure. One could express this with `std::optionalTypeSP`, but then returning `std::nullopt` vs `nullptr` becomes hard to reason about. So I opted to return `std::pairbool, TypeSP`, where the `bool` indicates success and the `TypeSP` the cached type. * `HandleCXXMethod` and `HandleObjCMethod` are feel too generic. Possibly something like `LinkCXXMethodDeclContextToDIE` or something. * `HandleCXXMethod` takes `ignore_containing_context` as an output parameter. Haven't found a great way to do this differently --- Patch is 22.72 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/95078.diff 2 Files Affected: - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (+236-211) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h (+15) ``diff diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 579a538af3634..585ae4e58cc1a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -975,6 +975,226 @@ ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes ) { return clang::CC_C; } +bool DWARFASTParserClang::HandleObjCMethod( +ObjCLanguage::MethodName const _method, DWARFDIE const , +CompilerType clang_type, ParsedDWARFTypeAttributes const , +bool is_variadic) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + const auto tag = die.Tag(); + ConstString class_name(objc_method.GetClassName()); + if (!class_name) +return false; + + TypeSP complete_objc_class_type_sp( + dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), class_name, + false)); + + if (!complete_objc_class_type_sp) +return false; + + CompilerType type_clang_forward_type = + complete_objc_class_type_sp->GetForwardCompilerType(); + + if (!type_clang_forward_type) +return false; + + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(type_clang_forward_type)) +return false; + + clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType( + type_clang_forward_type, attrs.name.GetCString(), clang_type, + attrs.is_artificial, is_variadic, attrs.is_objc_direct_call); + + if (!objc_method_decl) { +dwarf->GetObjectFile()->GetModule()->ReportError( +"[{0:x16}]: invalid Objective-C method {1:x4} ({2}), " +"please file a bug and attach the file at the start of " +"this error message", +die.GetOffset(), tag, DW_TAG_value_to_name(tag)); +return false; + } + + LinkDeclContextToDIE(objc_method_decl, die); + m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); + + return true; +} + +std::pair DWARFASTParserClang::HandleCXXMethod( +DWARFDIE const , CompilerType clang_type, +ParsedDWARFTypeAttributes const , DWARFDIE const _ctx_die, +bool is_static, bool _containing_context) { + Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); + SymbolFileDWARF *dwarf = die.GetDWARF(); + // Look at the parent of this DIE and see if it is a class or + // struct and see if this is actually a C++ method + Type *class_type = dwarf->ResolveType(decl_ctx_die); + if (!class_type) +return {}; + + if (class_type->GetID() != decl_ctx_die.GetID() || + IsClangModuleFwdDecl(decl_ctx_die)) { + +// We uniqued the parent class of this function to another +// class so we now need to associate all dies under +// "decl_ctx_die" to DIEs in the DIE for "class_type"... +DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID()); + +if (class_type_die) { + std::vector failures; + + CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die, class_type, + failures); + + // FIXME do something with these failures that's + // smarter than just dropping them on the ground. + // Unfortunately classes don't like having stuff added + // to them after their definitions are complete... + + Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; +