[Lldb-commits] [lldb] 3d06de5 - [lldb] Remove Phabricator usernames from Code Owners file (#102590)
Author: David Spickett Date: 2024-08-15T09:07:02+01:00 New Revision: 3d06de544b8397a6b93a4fdb52650579237b77fa URL: https://github.com/llvm/llvm-project/commit/3d06de544b8397a6b93a4fdb52650579237b77fa DIFF: https://github.com/llvm/llvm-project/commit/3d06de544b8397a6b93a4fdb52650579237b77fa.diff LOG: [lldb] Remove Phabricator usernames from Code Owners file (#102590) Removing them simplifies the content and means we don't confuse anyone who joined after the Phabricator shutdown. You could use them for review archaeology but this is only a subset of the names you'd encounter there anyway. So I don't think this is a good reason to keep them here. With a couple of exceptions the Phabricator/GitHub names are the same and/or related to their full name anyway. Added: Modified: lldb/CodeOwners.rst Removed: diff --git a/lldb/CodeOwners.rst b/lldb/CodeOwners.rst index 52e3e550523e5..3c10c2a28da9e 100644 --- a/lldb/CodeOwners.rst +++ b/lldb/CodeOwners.rst @@ -17,7 +17,7 @@ assistance. All parts of LLDB not covered by someone else -- | Jonas Devlieghere -| jonas\@devlieghere.com (email), jdevlieghere (Phabricator), jdevlieghere (GitHub), jdevlieghere (Discourse), jdevlieghere (Discord) +| jonas\@devlieghere.com (email), jdevlieghere (GitHub), jdevlieghere (Discourse), jdevlieghere (Discord) Components -- @@ -27,100 +27,100 @@ LLDB. ABI ~~~ | Jason Molenda -| jmolenda\@apple.com (email), jasonmolenda (Phabricator), jasonmolenda (GitHub), jasonmolenda (Discourse), jasonmolenda (Discord) +| jmolenda\@apple.com (email), jasonmolenda (GitHub), jasonmolenda (Discourse), jasonmolenda (Discord) | David Spickett -| david.spickett\@linaro.org (email), DavidSpickett (Phabricator), DavidSpickett (GitHub), DavidSpickett (Discourse), davidspickett (Discord) +| david.spickett\@linaro.org (email), DavidSpickett (GitHub), DavidSpickett (Discourse), davidspickett (Discord) Breakpoint ~~ | Jim Ingham -| jingham\@apple.com (email), jingham (Phabricator), jimingham (GitHub), jingham (Discourse) +| jingham\@apple.com (email), jimingham (GitHub), jingham (Discourse) CMake & Build System | Jonas Devlieghere -| jonas\@devlieghere.com (email), jdevlieghere (Phabricator), jdevlieghere (GitHub), jdevlieghere (Discourse), jdevlieghere (Discord) +| jonas\@devlieghere.com (email), jdevlieghere (GitHub), jdevlieghere (Discourse), jdevlieghere (Discord) | Alex Langford -| alangford\@apple.com (email), bulbazord (Phabricator), bulbazord (GitHub), bulbazord (Discourse), bulba_zord (Discord) +| alangford\@apple.com (email), bulbazord (GitHub), bulbazord (Discourse), bulba_zord (Discord) Commands | Jim Ingham -| jingham\@apple.com (email), jingham (Phabricator), jimingham (GitHub), jingham (Discourse) +| jingham\@apple.com (email), jimingham (GitHub), jingham (Discourse) Expression Parser ~ | Michael Buch -| michaelbuch12\@gmail.com (email), Michael137 (Phabricator), Michael137 (GitHub), Michael137 (Discourse) +| michaelbuch12\@gmail.com (email), Michael137 (GitHub), Michael137 (Discourse) | Jim Ingham -| jingham\@apple.com (email), jingham (Phabricator), jimingham (GitHub), jingham (Discourse) +| jingham\@apple.com (email), jimingham (GitHub), jingham (Discourse) Interpreter ~~~ | Jim Ingham -| jingham\@apple.com (email), jingham (Phabricator), jimingham (GitHub), jingham (Discourse) +| jingham\@apple.com (email), jimingham (GitHub), jingham (Discourse) | Greg Clayton -| gclayton\@fb.com (email), clayborg (Phabricator), clayborg (GitHub), clayborg (Discourse) +| gclayton\@fb.com (email), clayborg (GitHub), clayborg (Discourse) Lua ~~~ | Jonas Delvieghere -| jonas\@devlieghere.com (email), jdevlieghere (Phabricator), jdevlieghere (GitHub), jdevlieghere (Discourse), jdevlieghere (Discord) +| jonas\@devlieghere.com (email), jdevlieghere (GitHub), jdevlieghere (Discourse), jdevlieghere (Discord) Python ~~ | Med Ismail Bennani -| ismail\@bennani.ma (email), mib (Phabricator), medismailben (GitHub), mib (Discourse), mib#8727 (Discord) +| ismail\@bennani.ma (email), medismailben (GitHub), mib (Discourse), mib#8727 (Discord) Target/Process Control ~~ | Med Ismail Bennani -| ismail\@bennani.ma (email), mib (Phabricator), medismailben (GitHub), mib (Discourse), mib#8727 (Discord) +| ismail\@bennani.ma (email), medismailben (GitHub), mib (Discourse), mib#8727 (Discord) | Jim Ingham -| jingham\@apple.com (email), jingham (Phabricator), jimingham (GitHub), jingham (Discourse) +| jingham\@apple.com (email), jimingham (GitHub), jingham (Discourse) Test Suite ~~ | Jonas Devlieghere -| jonas\@devlieghere.com (email), jdevlieghere (Phabricator), jdevlieghere (GitHub), jdevlieghere (Discourse), jdevlieghere (Discord) +| jon
[Lldb-commits] [lldb] [lldb] Remove Phabricator usernames from Code Owners file (PR #102590)
https://github.com/DavidSpickett closed https://github.com/llvm/llvm-project/pull/102590 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
DavidSpickett wrote: Thanks for putting so much work into this. I will test this out with my VM setup. > Parameters --min-gdbserver-port and --max-gdbserver-port are deprecated now. Are they just consumed but the port number is not used because it can use the first port for everything? (I do see the logic of leaving the options in at first, so we can tell whether any problems are from the changes in this PR or purely from removing the options) https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Reland "[lldb] Reland 2402b3213c2f with `/H` to debug the windows build issue (PR #101672)
DavidSpickett wrote: @medismailben how might we reduce the path length? Maybe `/interfaces/` content could be moved into the parent folder, or `Python` dropped from some of the cpp file names (as they're in a python subfolder anyway)? Headers are better left verbose so we can see what they are from the include site. Or Python -> Py, but that's a lot more file names to change. https://github.com/llvm/llvm-project/pull/101672 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/104317 >From a5b4f6e7e105d36b82f9de588d2705ad3d622953 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Wed, 14 Aug 2024 11:52:40 + Subject: [PATCH 1/2] [lldb-dap] Support inspecting memory Adds support for the `readMemory` request which allows VS-Code to inspect memory. Also, add `memoryReference` to variablesa and `evaluate` responses, such that the binary view can be opened from the variables view and from the "watch" pane. --- .../test/tools/lldb-dap/dap_server.py | 13 ++ lldb/test/API/tools/lldb-dap/memory/Makefile | 3 + .../tools/lldb-dap/memory/TestDAP_memory.py | 135 ++ lldb/test/API/tools/lldb-dap/memory/main.cpp | 10 + lldb/tools/lldb-dap/JSONUtils.cpp | 29 ++- lldb/tools/lldb-dap/JSONUtils.h | 6 + lldb/tools/lldb-dap/lldb-dap.cpp | 172 +- 7 files changed, 365 insertions(+), 3 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/memory/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py create mode 100644 lldb/test/API/tools/lldb-dap/memory/main.cpp diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index a324af57b61df3..da10e8ab5c57c2 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 @@ -691,6 +691,19 @@ def request_disassemble( for inst in instructions: self.disassembled_instructions[inst["address"]] = inst +def request_read_memory(self, memoryReference, offset, count): +args_dict = { +"memoryReference": memoryReference, +"offset": offset, +"count": count, +} +command_dict = { +"command": "readMemory", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + def request_evaluate(self, expression, frameIndex=0, threadId=None, context=None): stackFrame = self.get_stackFrame(frameIndex=frameIndex, threadId=threadId) if stackFrame is None: diff --git a/lldb/test/API/tools/lldb-dap/memory/Makefile b/lldb/test/API/tools/lldb-dap/memory/Makefile new file mode 100644 index 00..8b20bcb050 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/memory/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py new file mode 100644 index 00..f950d5eecda671 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py @@ -0,0 +1,135 @@ +""" +Test lldb-dap memory support +""" + +from base64 import b64decode +import dap_server +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import lldbdap_testcase +import os + + +class TestDAP_memory(lldbdap_testcase.DAPTestCaseBase): +def test_read_memory(self): +""" +Tests the 'read_memory' request +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.cpp" +self.source_path = os.path.join(os.getcwd(), source) +self.set_source_breakpoints( +source, +[line_number(source, "// Breakpoint")], +) +self.continue_to_next_stop() + +locals = {l["name"]: l for l in self.dap_server.get_local_variables()} +rawptr_ref = locals["rawptr"]["memoryReference"] + +# We can read the complete string +mem = self.dap_server.request_read_memory(rawptr_ref, 0, 5)["body"] +self.assertEqual(mem["unreadableBytes"], 0) +self.assertEqual(b64decode(mem["data"]), b"dead\0") + +# Use an offset +mem = self.dap_server.request_read_memory(rawptr_ref, 2, 3)["body"] +self.assertEqual(b64decode(mem["data"]), b"ad\0") + +# Use a negative offset +mem = self.dap_server.request_read_memory(rawptr_ref, -1, 6)["body"] +self.assertEqual(b64decode(mem["data"])[1:], b"dead\0") + +# Reads of size 0 are successful +# VS-Code sends those in order to check if a `memoryReference` can actually be dereferenced. +mem = self.dap_server.request_read_memory(rawptr_ref, 0, 0) +self.assertEqual(mem["success"], True) +self.assertEqual(mem["body"]["data"], "") + +# Reads at offset 0x0 fail +mem = self.dap_server.request_read_memory("0x0", 0, 6) +self.assertEqual(mem["success"], False) +self.assertTrue(mem["message"].startswith("Unable to read memory: ")) + +def test_memory_refs_variables(self): +""" +Tests memory references for evaluate +""" +
[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)
@@ -4028,6 +4049,154 @@ void request_disassemble(const llvm::json::Object &request) { response.try_emplace("body", std::move(body)); g_dap.SendJSON(llvm::json::Value(std::move(response))); } + +// "ReadMemoryRequest": { +// "allOf": [ { "$ref": "#/definitions/Request" }, { +// "type": "object", +// "description": "Reads bytes from memory at the provided location. Clients +// should only call this request if the corresponding +// capability `supportsReadMemoryRequest` is true.", +// "properties": { +// "command": { +// "type": "string", +// "enum": [ "readMemory" ] +// }, +// "arguments": { +// "$ref": "#/definitions/ReadMemoryArguments" +// } +// }, +// "required": [ "command", "arguments" ] +// }] +// }, +// "ReadMemoryArguments": { +// "type": "object", +// "description": "Arguments for `readMemory` request.", +// "properties": { +// "memoryReference": { +// "type": "string", +// "description": "Memory reference to the base location from which data +// should be read." +// }, +// "offset": { +// "type": "integer", +// "description": "Offset (in bytes) to be applied to the reference +// location before reading data. Can be negative." +// }, +// "count": { +// "type": "integer", +// "description": "Number of bytes to read at the specified location and +// offset." +// } +// }, +// "required": [ "memoryReference", "count" ] +// }, +// "ReadMemoryResponse": { +// "allOf": [ { "$ref": "#/definitions/Response" }, { +// "type": "object", +// "description": "Response to `readMemory` request.", +// "properties": { +// "body": { +// "type": "object", +// "properties": { +// "address": { +// "type": "string", +// "description": "The address of the first byte of data returned. +// Treated as a hex value if prefixed with `0x`, or +// as a decimal value otherwise." +// }, +// "unreadableBytes": { +// "type": "integer", +// "description": "The number of unreadable bytes encountered after +// the last successfully read byte.\nThis can be +// used to determine the number of bytes that should +// be skipped before a subsequent +// `readMemory` request succeeds." +// }, +// "data": { +// "type": "string", +// "description": "The bytes read from memory, encoded using base64. +// If the decoded length of `data` is less than the +// requested `count` in the original `readMemory` +// request, and `unreadableBytes` is zero or +// omitted, then the client should assume it's +// reached the end of readable memory." +// } +// }, +// "required": [ "address" ] +// } +// } +// }] +// }, +void request_readMemory(const llvm::json::Object &request) { + llvm::json::Object response; + FillResponse(request, response); + auto arguments = request.getObject("arguments"); + + lldb::SBProcess process = g_dap.target.GetProcess(); + if (!process.IsValid()) { +response["success"] = false; +response["message"] = "No process running"; +g_dap.SendJSON(llvm::json::Value(std::move(response))); +return; + } + + auto memoryReference = GetString(arguments, "memoryReference"); + lldb::addr_t addr; + if (memoryReference.consumeInteger(0, addr)) { vogelsgesang wrote: To my understanding, `GetUnsigned` works for JSON request similar to `{"memoryReference": 1234 }`. However, memory references are string-typed and not integer-typed. The request we are receiving has the form `{"memoryReference": "0x1234"}` https://github.com/llvm/llvm-project/pull/104317 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)
https://github.com/vogelsgesang edited https://github.com/llvm/llvm-project/pull/104317 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)
@@ -4028,6 +4049,154 @@ void request_disassemble(const llvm::json::Object &request) { response.try_emplace("body", std::move(body)); g_dap.SendJSON(llvm::json::Value(std::move(response))); } + +// "ReadMemoryRequest": { +// "allOf": [ { "$ref": "#/definitions/Request" }, { +// "type": "object", +// "description": "Reads bytes from memory at the provided location. Clients +// should only call this request if the corresponding +// capability `supportsReadMemoryRequest` is true.", +// "properties": { +// "command": { +// "type": "string", +// "enum": [ "readMemory" ] +// }, +// "arguments": { +// "$ref": "#/definitions/ReadMemoryArguments" +// } +// }, +// "required": [ "command", "arguments" ] +// }] +// }, +// "ReadMemoryArguments": { +// "type": "object", +// "description": "Arguments for `readMemory` request.", +// "properties": { +// "memoryReference": { +// "type": "string", +// "description": "Memory reference to the base location from which data +// should be read." +// }, +// "offset": { +// "type": "integer", +// "description": "Offset (in bytes) to be applied to the reference +// location before reading data. Can be negative." +// }, +// "count": { +// "type": "integer", +// "description": "Number of bytes to read at the specified location and +// offset." +// } +// }, +// "required": [ "memoryReference", "count" ] +// }, +// "ReadMemoryResponse": { +// "allOf": [ { "$ref": "#/definitions/Response" }, { +// "type": "object", +// "description": "Response to `readMemory` request.", +// "properties": { +// "body": { +// "type": "object", +// "properties": { +// "address": { +// "type": "string", +// "description": "The address of the first byte of data returned. +// Treated as a hex value if prefixed with `0x`, or +// as a decimal value otherwise." +// }, +// "unreadableBytes": { +// "type": "integer", +// "description": "The number of unreadable bytes encountered after +// the last successfully read byte.\nThis can be +// used to determine the number of bytes that should +// be skipped before a subsequent +// `readMemory` request succeeds." +// }, +// "data": { +// "type": "string", +// "description": "The bytes read from memory, encoded using base64. +// If the decoded length of `data` is less than the +// requested `count` in the original `readMemory` +// request, and `unreadableBytes` is zero or +// omitted, then the client should assume it's +// reached the end of readable memory." +// } +// }, +// "required": [ "address" ] +// } +// } +// }] +// }, +void request_readMemory(const llvm::json::Object &request) { + llvm::json::Object response; + FillResponse(request, response); + auto arguments = request.getObject("arguments"); + + lldb::SBProcess process = g_dap.target.GetProcess(); + if (!process.IsValid()) { +response["success"] = false; +response["message"] = "No process running"; +g_dap.SendJSON(llvm::json::Value(std::move(response))); +return; + } + + auto memoryReference = GetString(arguments, "memoryReference"); + lldb::addr_t addr; + if (memoryReference.consumeInteger(0, addr)) { vogelsgesang wrote: FWIW, I copied used `request_disassemble` as inspiration here https://github.com/llvm/llvm-project/pull/104317 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/104317 >From a5b4f6e7e105d36b82f9de588d2705ad3d622953 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Wed, 14 Aug 2024 11:52:40 + Subject: [PATCH 1/4] [lldb-dap] Support inspecting memory Adds support for the `readMemory` request which allows VS-Code to inspect memory. Also, add `memoryReference` to variablesa and `evaluate` responses, such that the binary view can be opened from the variables view and from the "watch" pane. --- .../test/tools/lldb-dap/dap_server.py | 13 ++ lldb/test/API/tools/lldb-dap/memory/Makefile | 3 + .../tools/lldb-dap/memory/TestDAP_memory.py | 135 ++ lldb/test/API/tools/lldb-dap/memory/main.cpp | 10 + lldb/tools/lldb-dap/JSONUtils.cpp | 29 ++- lldb/tools/lldb-dap/JSONUtils.h | 6 + lldb/tools/lldb-dap/lldb-dap.cpp | 172 +- 7 files changed, 365 insertions(+), 3 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/memory/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py create mode 100644 lldb/test/API/tools/lldb-dap/memory/main.cpp diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index a324af57b61df3..da10e8ab5c57c2 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 @@ -691,6 +691,19 @@ def request_disassemble( for inst in instructions: self.disassembled_instructions[inst["address"]] = inst +def request_read_memory(self, memoryReference, offset, count): +args_dict = { +"memoryReference": memoryReference, +"offset": offset, +"count": count, +} +command_dict = { +"command": "readMemory", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + def request_evaluate(self, expression, frameIndex=0, threadId=None, context=None): stackFrame = self.get_stackFrame(frameIndex=frameIndex, threadId=threadId) if stackFrame is None: diff --git a/lldb/test/API/tools/lldb-dap/memory/Makefile b/lldb/test/API/tools/lldb-dap/memory/Makefile new file mode 100644 index 00..8b20bcb050 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/memory/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py new file mode 100644 index 00..f950d5eecda671 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py @@ -0,0 +1,135 @@ +""" +Test lldb-dap memory support +""" + +from base64 import b64decode +import dap_server +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import lldbdap_testcase +import os + + +class TestDAP_memory(lldbdap_testcase.DAPTestCaseBase): +def test_read_memory(self): +""" +Tests the 'read_memory' request +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.cpp" +self.source_path = os.path.join(os.getcwd(), source) +self.set_source_breakpoints( +source, +[line_number(source, "// Breakpoint")], +) +self.continue_to_next_stop() + +locals = {l["name"]: l for l in self.dap_server.get_local_variables()} +rawptr_ref = locals["rawptr"]["memoryReference"] + +# We can read the complete string +mem = self.dap_server.request_read_memory(rawptr_ref, 0, 5)["body"] +self.assertEqual(mem["unreadableBytes"], 0) +self.assertEqual(b64decode(mem["data"]), b"dead\0") + +# Use an offset +mem = self.dap_server.request_read_memory(rawptr_ref, 2, 3)["body"] +self.assertEqual(b64decode(mem["data"]), b"ad\0") + +# Use a negative offset +mem = self.dap_server.request_read_memory(rawptr_ref, -1, 6)["body"] +self.assertEqual(b64decode(mem["data"])[1:], b"dead\0") + +# Reads of size 0 are successful +# VS-Code sends those in order to check if a `memoryReference` can actually be dereferenced. +mem = self.dap_server.request_read_memory(rawptr_ref, 0, 0) +self.assertEqual(mem["success"], True) +self.assertEqual(mem["body"]["data"], "") + +# Reads at offset 0x0 fail +mem = self.dap_server.request_read_memory("0x0", 0, 6) +self.assertEqual(mem["success"], False) +self.assertTrue(mem["message"].startswith("Unable to read memory: ")) + +def test_memory_refs_variables(self): +""" +Tests memory references for evaluate +""" +
[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)
@@ -4028,6 +4049,154 @@ void request_disassemble(const llvm::json::Object &request) { response.try_emplace("body", std::move(body)); g_dap.SendJSON(llvm::json::Value(std::move(response))); } + +// "ReadMemoryRequest": { +// "allOf": [ { "$ref": "#/definitions/Request" }, { +// "type": "object", +// "description": "Reads bytes from memory at the provided location. Clients +// should only call this request if the corresponding +// capability `supportsReadMemoryRequest` is true.", +// "properties": { +// "command": { +// "type": "string", +// "enum": [ "readMemory" ] +// }, +// "arguments": { +// "$ref": "#/definitions/ReadMemoryArguments" +// } +// }, +// "required": [ "command", "arguments" ] +// }] +// }, +// "ReadMemoryArguments": { +// "type": "object", +// "description": "Arguments for `readMemory` request.", +// "properties": { +// "memoryReference": { +// "type": "string", +// "description": "Memory reference to the base location from which data +// should be read." +// }, +// "offset": { +// "type": "integer", +// "description": "Offset (in bytes) to be applied to the reference +// location before reading data. Can be negative." +// }, +// "count": { +// "type": "integer", +// "description": "Number of bytes to read at the specified location and +// offset." +// } +// }, +// "required": [ "memoryReference", "count" ] +// }, +// "ReadMemoryResponse": { +// "allOf": [ { "$ref": "#/definitions/Response" }, { +// "type": "object", +// "description": "Response to `readMemory` request.", +// "properties": { +// "body": { +// "type": "object", +// "properties": { +// "address": { +// "type": "string", +// "description": "The address of the first byte of data returned. +// Treated as a hex value if prefixed with `0x`, or +// as a decimal value otherwise." +// }, +// "unreadableBytes": { +// "type": "integer", +// "description": "The number of unreadable bytes encountered after +// the last successfully read byte.\nThis can be +// used to determine the number of bytes that should +// be skipped before a subsequent +// `readMemory` request succeeds." +// }, +// "data": { +// "type": "string", +// "description": "The bytes read from memory, encoded using base64. +// If the decoded length of `data` is less than the +// requested `count` in the original `readMemory` +// request, and `unreadableBytes` is zero or +// omitted, then the client should assume it's +// reached the end of readable memory." +// } +// }, +// "required": [ "address" ] +// } +// } +// }] +// }, +void request_readMemory(const llvm::json::Object &request) { + llvm::json::Object response; + FillResponse(request, response); + auto arguments = request.getObject("arguments"); + + lldb::SBProcess process = g_dap.target.GetProcess(); + if (!process.IsValid()) { +response["success"] = false; +response["message"] = "No process running"; +g_dap.SendJSON(llvm::json::Value(std::move(response))); +return; + } + + auto memoryReference = GetString(arguments, "memoryReference"); + lldb::addr_t addr; + if (memoryReference.consumeInteger(0, addr)) { +response["success"] = false; +response["message"] = +"Malformed memory reference: " + memoryReference.str(); +g_dap.SendJSON(llvm::json::Value(std::move(response))); +return; + } + + addr += GetSigned(arguments, "offset", 0); + const auto requested_count = GetUnsigned(arguments, "count", 0); + lldb::SBMemoryRegionInfo region_info; + lldb::SBError memRegError = process.GetMemoryRegionInfo(addr, region_info); + if (memRegError.Fail()) { +response["success"] = false; +EmplaceSafeString(response, "message", + "Unable to find memory region: " + + std::string(memRegError.GetCString())); +g_dap.SendJSON(llvm::json::Value(std::move(response))); +return; + } + const auto available_count = + std::min(requested_count, region_info.GetRegionEnd() - addr); + const auto unavailable_count = requested_count - available_count; + + std::vector buf; + buf.resize(available_count); + if (available_count > 0) { +lldb::SBError memReadError; +auto bytes_read = +process.ReadMemory(addr, buf.data(), available_count, memReadError); +if (memReadEr
[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/104317 >From a5b4f6e7e105d36b82f9de588d2705ad3d622953 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Wed, 14 Aug 2024 11:52:40 + Subject: [PATCH 1/5] [lldb-dap] Support inspecting memory Adds support for the `readMemory` request which allows VS-Code to inspect memory. Also, add `memoryReference` to variablesa and `evaluate` responses, such that the binary view can be opened from the variables view and from the "watch" pane. --- .../test/tools/lldb-dap/dap_server.py | 13 ++ lldb/test/API/tools/lldb-dap/memory/Makefile | 3 + .../tools/lldb-dap/memory/TestDAP_memory.py | 135 ++ lldb/test/API/tools/lldb-dap/memory/main.cpp | 10 + lldb/tools/lldb-dap/JSONUtils.cpp | 29 ++- lldb/tools/lldb-dap/JSONUtils.h | 6 + lldb/tools/lldb-dap/lldb-dap.cpp | 172 +- 7 files changed, 365 insertions(+), 3 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/memory/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py create mode 100644 lldb/test/API/tools/lldb-dap/memory/main.cpp diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index a324af57b61df3..da10e8ab5c57c2 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 @@ -691,6 +691,19 @@ def request_disassemble( for inst in instructions: self.disassembled_instructions[inst["address"]] = inst +def request_read_memory(self, memoryReference, offset, count): +args_dict = { +"memoryReference": memoryReference, +"offset": offset, +"count": count, +} +command_dict = { +"command": "readMemory", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + def request_evaluate(self, expression, frameIndex=0, threadId=None, context=None): stackFrame = self.get_stackFrame(frameIndex=frameIndex, threadId=threadId) if stackFrame is None: diff --git a/lldb/test/API/tools/lldb-dap/memory/Makefile b/lldb/test/API/tools/lldb-dap/memory/Makefile new file mode 100644 index 00..8b20bcb050 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/memory/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py new file mode 100644 index 00..f950d5eecda671 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py @@ -0,0 +1,135 @@ +""" +Test lldb-dap memory support +""" + +from base64 import b64decode +import dap_server +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import lldbdap_testcase +import os + + +class TestDAP_memory(lldbdap_testcase.DAPTestCaseBase): +def test_read_memory(self): +""" +Tests the 'read_memory' request +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.cpp" +self.source_path = os.path.join(os.getcwd(), source) +self.set_source_breakpoints( +source, +[line_number(source, "// Breakpoint")], +) +self.continue_to_next_stop() + +locals = {l["name"]: l for l in self.dap_server.get_local_variables()} +rawptr_ref = locals["rawptr"]["memoryReference"] + +# We can read the complete string +mem = self.dap_server.request_read_memory(rawptr_ref, 0, 5)["body"] +self.assertEqual(mem["unreadableBytes"], 0) +self.assertEqual(b64decode(mem["data"]), b"dead\0") + +# Use an offset +mem = self.dap_server.request_read_memory(rawptr_ref, 2, 3)["body"] +self.assertEqual(b64decode(mem["data"]), b"ad\0") + +# Use a negative offset +mem = self.dap_server.request_read_memory(rawptr_ref, -1, 6)["body"] +self.assertEqual(b64decode(mem["data"])[1:], b"dead\0") + +# Reads of size 0 are successful +# VS-Code sends those in order to check if a `memoryReference` can actually be dereferenced. +mem = self.dap_server.request_read_memory(rawptr_ref, 0, 0) +self.assertEqual(mem["success"], True) +self.assertEqual(mem["body"]["data"], "") + +# Reads at offset 0x0 fail +mem = self.dap_server.request_read_memory("0x0", 0, 6) +self.assertEqual(mem["success"], False) +self.assertTrue(mem["message"].startswith("Unable to read memory: ")) + +def test_memory_refs_variables(self): +""" +Tests memory references for evaluate +""" +
[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/104317 >From a5b4f6e7e105d36b82f9de588d2705ad3d622953 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Wed, 14 Aug 2024 11:52:40 + Subject: [PATCH 1/5] [lldb-dap] Support inspecting memory Adds support for the `readMemory` request which allows VS-Code to inspect memory. Also, add `memoryReference` to variablesa and `evaluate` responses, such that the binary view can be opened from the variables view and from the "watch" pane. --- .../test/tools/lldb-dap/dap_server.py | 13 ++ lldb/test/API/tools/lldb-dap/memory/Makefile | 3 + .../tools/lldb-dap/memory/TestDAP_memory.py | 135 ++ lldb/test/API/tools/lldb-dap/memory/main.cpp | 10 + lldb/tools/lldb-dap/JSONUtils.cpp | 29 ++- lldb/tools/lldb-dap/JSONUtils.h | 6 + lldb/tools/lldb-dap/lldb-dap.cpp | 172 +- 7 files changed, 365 insertions(+), 3 deletions(-) create mode 100644 lldb/test/API/tools/lldb-dap/memory/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py create mode 100644 lldb/test/API/tools/lldb-dap/memory/main.cpp diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index a324af57b61df3..da10e8ab5c57c2 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 @@ -691,6 +691,19 @@ def request_disassemble( for inst in instructions: self.disassembled_instructions[inst["address"]] = inst +def request_read_memory(self, memoryReference, offset, count): +args_dict = { +"memoryReference": memoryReference, +"offset": offset, +"count": count, +} +command_dict = { +"command": "readMemory", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + def request_evaluate(self, expression, frameIndex=0, threadId=None, context=None): stackFrame = self.get_stackFrame(frameIndex=frameIndex, threadId=threadId) if stackFrame is None: diff --git a/lldb/test/API/tools/lldb-dap/memory/Makefile b/lldb/test/API/tools/lldb-dap/memory/Makefile new file mode 100644 index 00..8b20bcb050 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/memory/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py new file mode 100644 index 00..f950d5eecda671 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py @@ -0,0 +1,135 @@ +""" +Test lldb-dap memory support +""" + +from base64 import b64decode +import dap_server +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import lldbdap_testcase +import os + + +class TestDAP_memory(lldbdap_testcase.DAPTestCaseBase): +def test_read_memory(self): +""" +Tests the 'read_memory' request +""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.cpp" +self.source_path = os.path.join(os.getcwd(), source) +self.set_source_breakpoints( +source, +[line_number(source, "// Breakpoint")], +) +self.continue_to_next_stop() + +locals = {l["name"]: l for l in self.dap_server.get_local_variables()} +rawptr_ref = locals["rawptr"]["memoryReference"] + +# We can read the complete string +mem = self.dap_server.request_read_memory(rawptr_ref, 0, 5)["body"] +self.assertEqual(mem["unreadableBytes"], 0) +self.assertEqual(b64decode(mem["data"]), b"dead\0") + +# Use an offset +mem = self.dap_server.request_read_memory(rawptr_ref, 2, 3)["body"] +self.assertEqual(b64decode(mem["data"]), b"ad\0") + +# Use a negative offset +mem = self.dap_server.request_read_memory(rawptr_ref, -1, 6)["body"] +self.assertEqual(b64decode(mem["data"])[1:], b"dead\0") + +# Reads of size 0 are successful +# VS-Code sends those in order to check if a `memoryReference` can actually be dereferenced. +mem = self.dap_server.request_read_memory(rawptr_ref, 0, 0) +self.assertEqual(mem["success"], True) +self.assertEqual(mem["body"]["data"], "") + +# Reads at offset 0x0 fail +mem = self.dap_server.request_read_memory("0x0", 0, 6) +self.assertEqual(mem["success"], False) +self.assertTrue(mem["message"].startswith("Unable to read memory: ")) + +def test_memory_refs_variables(self): +""" +Tests memory references for evaluate +""" +
[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)
@@ -1085,6 +1085,19 @@ std::string VariableDescription::GetResult(llvm::StringRef context) { return description.trim().str(); } +lldb::addr_t GetMemoryReference(lldb::SBValue v) { + if (!v.GetType().IsPointerType() && !v.GetType().IsArrayType()) { +return LLDB_INVALID_ADDRESS; + } + + lldb::SBValue deref = v.Dereference(); + if (!deref.IsValid()) { +return LLDB_INVALID_ADDRESS; + } + + return deref.GetLoadAddress(); vogelsgesang wrote: I addressed the stylistic parts of this comment (`std::optional`, don't check if `Derefence()` succeeded, ...). I am not 100% sure regarding the proposed semantic changes, though, in particular about ``` if (v_type.IsPointerType() || v_type.IsReferenceType()) v = v.Dereference(); ``` This change would lead to a test case failure in the newly added memory tests. The `int not_a_ptr` would now have a memory reference associated. To my understanding of the intended debugging semantics of the DAP, it should not have an associated memory reference, though, since it is not a pointer or pointer-like type https://github.com/llvm/llvm-project/pull/104317 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)
vogelsgesang wrote: Thanks for the super-fast review, @clayborg! I addressed all the straightforward issues and replied to the non-straightforward ones https://github.com/llvm/llvm-project/pull/104317 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Support inspecting memory (PR #104317)
https://github.com/vogelsgesang edited https://github.com/llvm/llvm-project/pull/104317 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 7898866 - [lldb-dap] Expose log path in extension settings (#103482)
Author: Adrian Vogelsgesang Date: 2024-08-15T13:19:32+02:00 New Revision: 7898866065f6c9b72b5fa3e45e565baf8a5e7609 URL: https://github.com/llvm/llvm-project/commit/7898866065f6c9b72b5fa3e45e565baf8a5e7609 DIFF: https://github.com/llvm/llvm-project/commit/7898866065f6c9b72b5fa3e45e565baf8a5e7609.diff LOG: [lldb-dap] Expose log path in extension settings (#103482) lldb-dap already supports a log file which can be enabled by setting the `LLDBDAP_LOG` environment variable. With this commit, the log location can be set directly through the VS-Code extension settings. Also, this commit bumps the version number, such that the new VS Code extension gets published to the Marketplace. Added: Modified: lldb/tools/lldb-dap/package-lock.json lldb/tools/lldb-dap/package.json lldb/tools/lldb-dap/src-ts/extension.ts Removed: diff --git a/lldb/tools/lldb-dap/package-lock.json b/lldb/tools/lldb-dap/package-lock.json index 8c70cc2d30e144..96570e42dbfdc4 100644 --- a/lldb/tools/lldb-dap/package-lock.json +++ b/lldb/tools/lldb-dap/package-lock.json @@ -1,12 +1,12 @@ { "name": "lldb-dap", - "version": "0.2.0", + "version": "0.2.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "lldb-dap", - "version": "0.2.0", + "version": "0.2.4", "license": "Apache 2.0 License with LLVM exceptions", "devDependencies": { "@types/node": "^18.11.18", diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json index 97e4efe7bac19d..4f4261d1718c01 100644 --- a/lldb/tools/lldb-dap/package.json +++ b/lldb/tools/lldb-dap/package.json @@ -1,7 +1,7 @@ { "name": "lldb-dap", "displayName": "LLDB DAP", - "version": "0.2.3", + "version": "0.2.4", "publisher": "llvm-vs-code-extensions", "homepage": "https://lldb.llvm.org";, "description": "LLDB debugging from VSCode", @@ -73,6 +73,11 @@ "scope": "resource", "type": "string", "description": "The path to the lldb-dap binary." +}, +"lldb-dap.log-path": { + "scope": "resource", + "type": "string", + "description": "The log path for lldb-dap (if any)" } } }, diff --git a/lldb/tools/lldb-dap/src-ts/extension.ts b/lldb/tools/lldb-dap/src-ts/extension.ts index 791175f7b46224..7df09f7a29dad7 100644 --- a/lldb/tools/lldb-dap/src-ts/extension.ts +++ b/lldb/tools/lldb-dap/src-ts/extension.ts @@ -14,13 +14,29 @@ function createDefaultLLDBDapOptions(): LLDBDapOptions { session: vscode.DebugSession, packageJSONExecutable: vscode.DebugAdapterExecutable | undefined, ): Promise { - const path = vscode.workspace -.getConfiguration("lldb-dap", session.workspaceFolder) -.get("executable-path"); + const config = vscode.workspace +.getConfiguration("lldb-dap", session.workspaceFolder); + const path = config.get("executable-path"); + const log_path = config.get("log-path"); + + let env : { [key: string]: string } = {}; + if (log_path) { +env["LLDBDAP_LOG"] = log_path; + } + if (path) { -return new vscode.DebugAdapterExecutable(path, []); +return new vscode.DebugAdapterExecutable(path, [], {env}); + } else if (packageJSONExecutable) { +return new vscode.DebugAdapterExecutable(packageJSONExecutable.command, packageJSONExecutable.args, { + ...packageJSONExecutable.options, + env: { +...packageJSONExecutable.options?.env, +...env + } +}); + } else { +return undefined; } - return packageJSONExecutable; }, }; } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Expose log path in extension settings (PR #103482)
https://github.com/vogelsgesang closed https://github.com/llvm/llvm-project/pull/103482 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix single thread stepping timeout race condition (PR #104195)
https://github.com/labath approved this pull request. This indeed fixes the race condition. I can confirm that the test no longer hangs after with this patch. I'm glad we were able to figure this out. *However*, this doesn't appear to be the only problem here. With the hang out of the way, I can now see another failure mode, which appears with a lower (say ~0.1%) frequency. Judging by the [logs](https://paste.debian.net/hidden/30235a5c/), the problem is triggered when the interrupt packet (^C) arrives too soon -- before the inferior has had a chance to execute anything. I haven't looked at the code, but my guess would be that the step-over thread plan erroneously decides that it's done (because it's back at the function it wanted to be in, but it does not realize that's because the PC hasn't been moved). If you want to reproduce this yourself, I've found that inserting a 10ms sleep [here](https://github.com/llvm/llvm-project/blob/7898866065f6c9b72b5fa3e45e565baf8a5e7609/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp#L1005) makes the failure reproduce in about 50% of cases (as it increases the likelyhood that the interrupt will arrive "too soon" -- you could probably achieve the same thing by decreasing the single thread timeout) https://github.com/llvm/llvm-project/pull/104195 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Reapply "[lldb] Tolerate multiple compile units with the same DWO ID (#100577)" (PR #104041)
https://github.com/labath closed https://github.com/llvm/llvm-project/pull/104041 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 57a19ac - Reapply "[lldb] Tolerate multiple compile units with the same DWO ID (#100577)" (#104041)
Author: Pavel Labath Date: 2024-08-15T13:34:03+02:00 New Revision: 57a19ac3365f1dc255e6f24fcb7afcde2ccef8f9 URL: https://github.com/llvm/llvm-project/commit/57a19ac3365f1dc255e6f24fcb7afcde2ccef8f9 DIFF: https://github.com/llvm/llvm-project/commit/57a19ac3365f1dc255e6f24fcb7afcde2ccef8f9.diff LOG: Reapply "[lldb] Tolerate multiple compile units with the same DWO ID (#100577)" (#104041) The only change vs. the first version of the patch is that I've made DWARFUnit linking thread-safe/unit. This was necessary because, during the indexing step, two skeleton units could attempt to associate themselves with the split unit. The original commit message was: I ran into this when LTO completely emptied two compile units, so they ended up with the same hash (see #100375). Although, ideally, the compiler would try to ensure we don't end up with a hash collision even in this case, guaranteeing their absence is practically impossible. This patch ensures this situation does not bring down lldb. Added: lldb/test/Shell/SymbolFile/DWARF/x86/dwp-hash-collision.s Modified: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h Removed: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 66a762bf9b6854..81f937762e35a6 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -97,12 +97,14 @@ void DWARFUnit::ExtractUnitDIEIfNeeded() { *m_dwo_id, m_first_die.GetOffset())); return; // Can't fetch the compile unit from the dwo file. } - // If the skeleton compile unit gets its unit DIE parsed first, then this - // will fill in the DWO file's back pointer to this skeleton compile unit. - // If the DWO files get parsed on their own first the skeleton back link - // can be done manually in DWARFUnit::GetSkeletonCompileUnit() which will - // do a reverse lookup and cache the result. - dwo_cu->SetSkeletonUnit(this); + + // Link the DWO unit to this object, if it hasn't been linked already (this + // can happen when we have an index, and the DWO unit is parsed first). + if (!dwo_cu->LinkToSkeletonUnit(*this)) { +SetDwoError(Status::createWithFormat( +"multiple compile units with Dwo ID {0:x16}", *m_dwo_id)); +return; + } DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly(); if (!dwo_cu_die.IsValid()) { @@ -708,23 +710,28 @@ uint8_t DWARFUnit::GetAddressByteSize(const DWARFUnit *cu) { uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; } DWARFCompileUnit *DWARFUnit::GetSkeletonUnit() { - if (m_skeleton_unit == nullptr && IsDWOUnit()) { + if (m_skeleton_unit.load() == nullptr && IsDWOUnit()) { SymbolFileDWARFDwo *dwo = llvm::dyn_cast_or_null(&GetSymbolFileDWARF()); // Do a reverse lookup if the skeleton compile unit wasn't set. -if (dwo) - m_skeleton_unit = dwo->GetBaseSymbolFile().GetSkeletonUnit(this); +DWARFUnit *candidate_skeleton_unit = +dwo ? dwo->GetBaseSymbolFile().GetSkeletonUnit(this) : nullptr; +if (candidate_skeleton_unit) + (void)LinkToSkeletonUnit(*candidate_skeleton_unit); +// Linking may fail due to a race, so be sure to return the actual value. } - return llvm::dyn_cast_or_null(m_skeleton_unit); + return llvm::dyn_cast_or_null(m_skeleton_unit.load()); } -void DWARFUnit::SetSkeletonUnit(DWARFUnit *skeleton_unit) { - // If someone is re-setting the skeleton compile unit backlink, make sure - // it is setting it to a valid value when it wasn't valid, or if the - // value in m_skeleton_unit was valid, it should be the same value. - assert(skeleton_unit); - assert(m_skeleton_unit == nullptr || m_skeleton_unit == skeleton_unit); - m_skeleton_unit = skeleton_unit; +bool DWARFUnit::LinkToSkeletonUnit(DWARFUnit &skeleton_unit) { + DWARFUnit *expected_unit = nullptr; + if (m_skeleton_unit.compare_exchange_strong(expected_unit, &skeleton_unit)) +return true; + if (expected_unit == &skeleton_unit) { +// Exchange failed because it already contained the right value. +return true; + } + return false; // Already linked to a diff erent unit. } bool DWARFUnit::Supports_DW_AT_APPLE_objc_complete_type() { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 85c37971ced8e0..148932d67b908c 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -170,7 +170,7 @@ class DWARFUnit : public UserID { /// both cases correctly and avoids crashes. DWARFCompileUnit *GetSkeletonUnit(); - void SetSkeletonUnit(DWARFUnit *skeleton_unit); + bool LinkToSkeletonUnit(DWARFUnit &skeleton_unit); bool Supports_DW_AT_APPLE_objc_complete_type(); @@ -308,7 +308,7 @@ class DWARFUn
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
https://github.com/labath edited https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
https://github.com/labath commented: The termination part definitely needs to be done differently, but overall, I think this is a pretty good start. (PSA: I will be OOO all of next week.) https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
@@ -20,6 +20,10 @@ #include #include +#ifdef SendMessage +#undef SendMessage +#endif + labath wrote: I guess that means we're including a windows header somewhere. Any chance to avoid that? Llvm is pretty strict about that. Lldb is not, though I think it's a good practice. https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
@@ -40,83 +40,20 @@ #include "lldb/Utility/StringExtractorGDBRemote.h" +#include "../tools/lldb-server/Acceptor.h" labath wrote: We will need to move this someplace else (probably `Host`) https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
@@ -601,15 +570,24 @@ int main_platform(int argc, char *argv[]) { // If not running as a server, this process will not accept // connections while a connection is active. acceptor_up.reset(); - - // When not running in server mode, use all available ports - platform.SetPortMap(std::move(gdbserver_portmap)); } platform.SetConnection(std::unique_ptr(conn)); client_handle(platform, inferior_arguments); } while (g_server); + // FIXME: Make TCPSocket::CloseListenSockets() public and implement + // Acceptor::Close(). + /* + if (acceptor_gdb && gdb_thread.IsJoinable()) { +g_listen_gdb = false; +static_cast(acceptor_gdb->m_listener_socket_up.get()) +->CloseListenSockets(); +lldb::thread_result_t result; +gdb_thread.Join(&result); + } + */ + labath wrote: This won't work. This is exactly the pattern from that kernel bug we were arguing over. It's just not possible to safely close an fd while another thread may be operating on it. You need to use an out-of-band mechanism (e.g. a pipe) to notify the thread that it's time to terminate. However, since that will involve some form of multiplexing (e.g. `select(2)`). I would strongly prefer to just multiplex over the two sockets we are accepting. We should be able to use the `MainLoop` class for that -- just register the two sockets with the class, and let it call the right callback when needed. Basically, the code should look similar to [this](https://github.com/llvm/llvm-project/blob/f71b63865140cf3c286baf3a77ba3e467f929504/lldb/source/Host/common/TCPSocket.cpp#L267), except that it will be listening to two unrelated sockets. https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
@@ -666,7 +756,23 @@ ConnectionStatus ConnectionFileDescriptor::ConnectFD(llvm::StringRef s, socket_id_callback_type socket_id_callback, Status *error_ptr) { -#if LLDB_ENABLE_POSIX +#ifdef _WIN32 + int64_t fd = -1; + if (!s.getAsInteger(0, fd)) { +// Assume we own fd. +std::unique_ptr tcp_socket = +std::make_unique((NativeSocket)fd, true, false); +m_io_sp = std::move(tcp_socket); +m_uri = s.str(); +return eConnectionStatusSuccess; + } labath wrote: I don't exactly have an alternative in mind yet, but I'm not sure this is a good idea. File descriptors are a thing on windows as well (though, IIUC, they're more of like an in-process thing rather than a kernel entity), and we do have code which treats them as such, so I think it could be confusing that this functions considers an "fd" to be a socket handle. https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
@@ -879,20 +879,12 @@ lldb::thread_result_t GDBRemoteCommunication::ListenThread() { return {}; } -Status GDBRemoteCommunication::StartDebugserverProcess( -const char *url, Platform *platform, ProcessLaunchInfo &launch_info, -uint16_t *port, const Args *inferior_args, int pass_comm_fd) { +bool GDBRemoteCommunication::GetDebugserverPath( +Platform *platform, FileSpec &debugserver_file_spec) { labath wrote: ```suggestion FileSpec GDBRemoteCommunication::GetDebugserverPath( Platform *platform) { ``` just return an invalid FileSpec for error. https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
@@ -47,111 +48,10 @@ using namespace llvm; // option descriptors for getopt_long_only() -#ifdef _WIN32 -typedef pipe_t shared_fd_t; -const shared_fd_t kInvalidSharedFD = LLDB_INVALID_PIPE; -#else -typedef NativeSocket shared_fd_t; -const shared_fd_t kInvalidSharedFD = Socket::kInvalidSocketValue; -#endif - -class SharedSocket { -public: - SharedSocket(Connection *conn, Status &error) { -m_fd = kInvalidSharedFD; - -const Socket *socket = -static_cast(conn->GetReadObject().get()); -if (socket == nullptr) { - error = Status("invalid conn socket"); - return; -} - -#ifdef _WIN32 -m_socket = socket->GetNativeSocket(); - -// Create a pipe to transfer WSAPROTOCOL_INFO to the child process. -error = m_socket_pipe.CreateNew(true); -if (error.Fail()) - return; - -m_fd = m_socket_pipe.GetReadPipe(); -#else -m_fd = socket->GetNativeSocket(); -error = Status(); -#endif - } - - shared_fd_t GetSendableFD() { return m_fd; } - - Status CompleteSending(lldb::pid_t child_pid) { -#ifdef _WIN32 -// Transfer WSAPROTOCOL_INFO to the child process. -m_socket_pipe.CloseReadFileDescriptor(); - -WSAPROTOCOL_INFO protocol_info; -if (::WSADuplicateSocket(m_socket, child_pid, &protocol_info) == -SOCKET_ERROR) { - int last_error = ::WSAGetLastError(); - return Status("WSADuplicateSocket() failed, error: %d", last_error); -} - -size_t num_bytes; -Status error = -m_socket_pipe.WriteWithTimeout(&protocol_info, sizeof(protocol_info), - std::chrono::seconds(10), num_bytes); -if (error.Fail()) - return error; -if (num_bytes != sizeof(protocol_info)) - return Status("WriteWithTimeout(WSAPROTOCOL_INFO) failed: %d bytes", -num_bytes); -#endif -return Status(); - } - - static Status GetNativeSocket(shared_fd_t fd, NativeSocket &socket) { -#ifdef _WIN32 -socket = Socket::kInvalidSocketValue; -// Read WSAPROTOCOL_INFO from the parent process and create NativeSocket. -WSAPROTOCOL_INFO protocol_info; -{ - Pipe socket_pipe(fd, LLDB_INVALID_PIPE); - size_t num_bytes; - Status error = - socket_pipe.ReadWithTimeout(&protocol_info, sizeof(protocol_info), - std::chrono::seconds(10), num_bytes); - if (error.Fail()) -return error; - if (num_bytes != sizeof(protocol_info)) { -return Status( -"socket_pipe.ReadWithTimeout(WSAPROTOCOL_INFO) failed: % d bytes", -num_bytes); - } -} -socket = ::WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, &protocol_info, 0, 0); -if (socket == INVALID_SOCKET) { - return Status("WSASocket(FROM_PROTOCOL_INFO) failed: error %d", -::WSAGetLastError()); -} -return Status(); -#else -socket = fd; -return Status(); -#endif - } - -private: -#ifdef _WIN32 - Pipe m_socket_pipe; - NativeSocket m_socket; -#endif - shared_fd_t m_fd; -}; - static int g_debug = 0; static int g_verbose = 0; static int g_server = 0; +static volatile bool g_listen_gdb = true; labath wrote: volatile? really? https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
https://github.com/labath edited https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Reland "[lldb] Reland 2402b3213c2f with `/H` to debug the windows build issue (PR #101672)
labath wrote: `lldbPluginScriptInterpreterPythonScriptedThreadPlanPythonInterface` quite a mouthful for just a single cpp file. Maybe all of the interfaces could be a part of a single library? That would end up with something like: ``` D:\build-lldb\tools\lldb\source\Plugins\ScriptInterpreter\Python\Interfaces\CMakeFiles\lldbPluginScriptInterpreterPythonInterfaces.dir\lldbPluginScriptInterpreterPythonInterfaces.pdb ``` .. which is 80 chars shorter? https://github.com/llvm/llvm-project/pull/101672 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Realpath symlinks for breakpoints (PR #102223)
https://github.com/labath commented: The deps seem fine. I like the approach you've chosen. I'll leave the rest to other reviewers. https://github.com/llvm/llvm-project/pull/102223 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
@@ -879,20 +879,12 @@ lldb::thread_result_t GDBRemoteCommunication::ListenThread() { return {}; } -Status GDBRemoteCommunication::StartDebugserverProcess( -const char *url, Platform *platform, ProcessLaunchInfo &launch_info, -uint16_t *port, const Args *inferior_args, int pass_comm_fd) { +bool GDBRemoteCommunication::GetDebugserverPath( +Platform *platform, FileSpec &debugserver_file_spec) { slydiman wrote: I tried to minimize changes here. `bool debugserver_exists` already was here. GetDebugserverPath() is used in GDBRemoteCommunicationServerPlatform.cpp for checking debugserver w/o launching. Invalid FileSpec is not convenient for this purpose. https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
@@ -40,83 +40,20 @@ #include "lldb/Utility/StringExtractorGDBRemote.h" +#include "../tools/lldb-server/Acceptor.h" slydiman wrote: SocketProtocol is defined in lldb/include/lldb/Host/Socket.h I will move FindSchemeByProtocol(const Socket::SocketProtocol protocol) to Socket.* https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
@@ -47,111 +48,10 @@ using namespace llvm; // option descriptors for getopt_long_only() -#ifdef _WIN32 -typedef pipe_t shared_fd_t; -const shared_fd_t kInvalidSharedFD = LLDB_INVALID_PIPE; -#else -typedef NativeSocket shared_fd_t; -const shared_fd_t kInvalidSharedFD = Socket::kInvalidSocketValue; -#endif - -class SharedSocket { -public: - SharedSocket(Connection *conn, Status &error) { -m_fd = kInvalidSharedFD; - -const Socket *socket = -static_cast(conn->GetReadObject().get()); -if (socket == nullptr) { - error = Status("invalid conn socket"); - return; -} - -#ifdef _WIN32 -m_socket = socket->GetNativeSocket(); - -// Create a pipe to transfer WSAPROTOCOL_INFO to the child process. -error = m_socket_pipe.CreateNew(true); -if (error.Fail()) - return; - -m_fd = m_socket_pipe.GetReadPipe(); -#else -m_fd = socket->GetNativeSocket(); -error = Status(); -#endif - } - - shared_fd_t GetSendableFD() { return m_fd; } - - Status CompleteSending(lldb::pid_t child_pid) { -#ifdef _WIN32 -// Transfer WSAPROTOCOL_INFO to the child process. -m_socket_pipe.CloseReadFileDescriptor(); - -WSAPROTOCOL_INFO protocol_info; -if (::WSADuplicateSocket(m_socket, child_pid, &protocol_info) == -SOCKET_ERROR) { - int last_error = ::WSAGetLastError(); - return Status("WSADuplicateSocket() failed, error: %d", last_error); -} - -size_t num_bytes; -Status error = -m_socket_pipe.WriteWithTimeout(&protocol_info, sizeof(protocol_info), - std::chrono::seconds(10), num_bytes); -if (error.Fail()) - return error; -if (num_bytes != sizeof(protocol_info)) - return Status("WriteWithTimeout(WSAPROTOCOL_INFO) failed: %d bytes", -num_bytes); -#endif -return Status(); - } - - static Status GetNativeSocket(shared_fd_t fd, NativeSocket &socket) { -#ifdef _WIN32 -socket = Socket::kInvalidSocketValue; -// Read WSAPROTOCOL_INFO from the parent process and create NativeSocket. -WSAPROTOCOL_INFO protocol_info; -{ - Pipe socket_pipe(fd, LLDB_INVALID_PIPE); - size_t num_bytes; - Status error = - socket_pipe.ReadWithTimeout(&protocol_info, sizeof(protocol_info), - std::chrono::seconds(10), num_bytes); - if (error.Fail()) -return error; - if (num_bytes != sizeof(protocol_info)) { -return Status( -"socket_pipe.ReadWithTimeout(WSAPROTOCOL_INFO) failed: % d bytes", -num_bytes); - } -} -socket = ::WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, &protocol_info, 0, 0); -if (socket == INVALID_SOCKET) { - return Status("WSASocket(FROM_PROTOCOL_INFO) failed: error %d", -::WSAGetLastError()); -} -return Status(); -#else -socket = fd; -return Status(); -#endif - } - -private: -#ifdef _WIN32 - Pipe m_socket_pipe; - NativeSocket m_socket; -#endif - shared_fd_t m_fd; -}; - static int g_debug = 0; static int g_verbose = 0; static int g_server = 0; +static volatile bool g_listen_gdb = true; slydiman wrote: I expected to use this for break the gdb port listener thread. But currently there is no public API to close listen socket. See FIXME at the end of lldb-platform.cpp. I think we can just exit the app safely without graceful terminating this thread. https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
@@ -601,15 +570,24 @@ int main_platform(int argc, char *argv[]) { // If not running as a server, this process will not accept // connections while a connection is active. acceptor_up.reset(); - - // When not running in server mode, use all available ports - platform.SetPortMap(std::move(gdbserver_portmap)); } platform.SetConnection(std::unique_ptr(conn)); client_handle(platform, inferior_arguments); } while (g_server); + // FIXME: Make TCPSocket::CloseListenSockets() public and implement + // Acceptor::Close(). + /* + if (acceptor_gdb && gdb_thread.IsJoinable()) { +g_listen_gdb = false; +static_cast(acceptor_gdb->m_listener_socket_up.get()) +->CloseListenSockets(); +lldb::thread_result_t result; +gdb_thread.Join(&result); + } + */ + slydiman wrote: Oh, Linux... Such pattern works just fine on Windows. I saw MainLoop. But I think it is much safer just exit the app. Terminating the main thread is enough. I will remove this comment in the code and the g_listen_gdb flag. https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add 'FindInMemory()' overload for PostMortemProcess. (PR #102536)
labath wrote: Thanks for chiming in Jason. I'm glad this is getting attention, as I think that our memory reading APIs are in need of an overhaul -- and it gives me a chance to share my idea. ;) I don't think that we need to change all of the APIs to return their memory. Sometimes reading the memory into a caller-provided buffer makes perfect sense. What I would like to do is to regularize all the APIs, and avoid the need to implement the logic of e.g. "reading a c string twice". The approach I'd like is to define a `MemoryReader` interface, which would contain all of the ways one may want to read a memory (as a string, integer, etc..). It would also contain a default implementation of the APIs so that an implementation would only need to implement one or two methods and have everything fall out naturally. Then, anything that wants to support that interface, can just inherit from it and implement the required method. If something wants to provide two different methods for reading the memory (I believe Process supports cached and uncached reads), it can just do two implementations, and provide them via different accessors (e.g. `process->CachedMemory()->ReadInt(addr)` and process->DirectMemory()->ReadInt(addr)`). Another nice part about this is that if we have some code, which only needs to read memory, then it can take a MemoryReader reference (instead of Process or whatever), and then it can be unit tested by just passing it a mock memory reader. https://github.com/llvm/llvm-project/pull/102536 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
@@ -20,6 +20,10 @@ #include #include +#ifdef SendMessage +#undef SendMessage +#endif + slydiman wrote: Note TestClient.cpp and LLGSTest.cpp already contain this code. Windows headers are necessary for socket definitions. It is impossible to separate them. This fix is necessary because the order of headers has been changed. Note we can remove the same code in TestClient.cpp and LLGSTest.cpp. I just minimized changes. Should I remove it from TestClient.cpp and LLGSTest.cpp? https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
@@ -666,7 +756,23 @@ ConnectionStatus ConnectionFileDescriptor::ConnectFD(llvm::StringRef s, socket_id_callback_type socket_id_callback, Status *error_ptr) { -#if LLDB_ENABLE_POSIX +#ifdef _WIN32 + int64_t fd = -1; + if (!s.getAsInteger(0, fd)) { +// Assume we own fd. +std::unique_ptr tcp_socket = +std::make_unique((NativeSocket)fd, true, false); +m_io_sp = std::move(tcp_socket); +m_uri = s.str(); +return eConnectionStatusSuccess; + } slydiman wrote: Right, file descriptors on Windows are in-process CRT specific things. But we already have this API. I don't see any point in complicating things here. https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
slydiman wrote: > Are they just consumed but the port number is not used because it can use the > first port for everything? > > (I do see the logic of leaving the options in at first, so we can tell > whether any problems are from the changes in this PR or purely from removing > the options) We need only 1 port defined by `--gdbserver-port`. I kept `--min-gdbserver-port` and `--max-gdbserver-port` for backward compatibility. ``` lldb-server p --server --listen *:1234 --gdbserver-port 1235 --min-gdbserver-port 1236 --max-gdbserver-port 1237 ``` 1235 is used for gdb ``` lldb-server p --server --listen *:1234 --min-gdbserver-port 1236 --max-gdbserver-port 1237 ``` 1236 is used for gdb ``` lldb-server p --server --listen *:1234 --max-gdbserver-port 1237 --min-gdbserver-port 1236 ``` 1237 is used for gdb https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [WIP] memory find speedup+bugfix (PR #104193)
https://github.com/labath updated https://github.com/llvm/llvm-project/pull/104193 >From a537a48c444e9dec3a85241d9726d6f3187a43cf Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Wed, 14 Aug 2024 19:58:27 +0200 Subject: [PATCH] [WIP] memory find speedup+bugfix --- lldb/source/Target/Process.cpp| 58 ++--- .../memory/find/TestMemoryFind.py | 10 +++ .../API/functionalities/memory/find/main.cpp | 82 +-- 3 files changed, 108 insertions(+), 42 deletions(-) diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index e3c4f2ee398cc4..4e3d7651a066ec 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -114,33 +114,6 @@ class ProcessOptionValueProperties } }; -class ProcessMemoryIterator { -public: - ProcessMemoryIterator(Process &process, lldb::addr_t base) - : m_process(process), m_base_addr(base) {} - - bool IsValid() { return m_is_valid; } - - uint8_t operator[](lldb::addr_t offset) { -if (!IsValid()) - return 0; - -uint8_t retval = 0; -Status error; -if (0 == m_process.ReadMemory(m_base_addr + offset, &retval, 1, error)) { - m_is_valid = false; - return 0; -} - -return retval; - } - -private: - Process &m_process; - const lldb::addr_t m_base_addr; - bool m_is_valid = true; -}; - static constexpr OptionEnumValueElement g_follow_fork_mode_values[] = { { eFollowParent, @@ -3368,20 +3341,37 @@ lldb::addr_t Process::FindInMemory(lldb::addr_t low, lldb::addr_t high, return LLDB_INVALID_ADDRESS; std::vector bad_char_heuristic(256, size); - ProcessMemoryIterator iterator(*this, low); - for (size_t idx = 0; idx < size - 1; idx++) { decltype(bad_char_heuristic)::size_type bcu_idx = buf[idx]; bad_char_heuristic[bcu_idx] = size - idx - 1; } - for (size_t s = 0; s <= (region_size - size);) { + + llvm::SmallVector mem; + addr_t mem_pos = low; + const size_t read_size = std::max(size, 0x1); + + for (addr_t s = low; s <= (high - size);) { +if (s + size >= mem.size() + mem_pos) { + mem.resize_for_overwrite(read_size); + Status error; + mem.resize( + ReadMemory(s, mem.data(), std::min(mem.size(), high - s), error)); + mem_pos = s; + if (error.Fail()) { +MemoryRegionInfo info; +error = GetMemoryRegionInfo(s, info); +if (error.Fail()) + return LLDB_INVALID_ADDRESS; +s = info.GetRange().GetRangeEnd(); +continue; + } +} int64_t j = size - 1; -while (j >= 0 && buf[j] == iterator[s + j]) +while (j >= 0 && buf[j] == mem[s + j - mem_pos]) j--; if (j < 0) - return low + s; -else - s += bad_char_heuristic[iterator[s + size - 1]]; + return s; +s += bad_char_heuristic[mem[s + size - 1 - mem_pos]]; } return LLDB_INVALID_ADDRESS; diff --git a/lldb/test/API/functionalities/memory/find/TestMemoryFind.py b/lldb/test/API/functionalities/memory/find/TestMemoryFind.py index 09611cc808777d..a606899498b722 100644 --- a/lldb/test/API/functionalities/memory/find/TestMemoryFind.py +++ b/lldb/test/API/functionalities/memory/find/TestMemoryFind.py @@ -79,3 +79,13 @@ def test_memory_find(self): 'memory find -s "nothere" `stringdata` `stringdata+10`', substrs=["data not found within the range."], ) + +pagesize = self.frame().FindVariable("pagesize").GetValueAsUnsigned() +mem_with_holes = self.frame().FindVariable("mem_with_holes").GetValueAsUnsigned() +matches_var = self.frame().FindVariable("matches") +self.assertEqual(matches_var.GetNumChildren(), 4) +matches = [f'data found at location: {matches_var.GetChildAtIndex(i).GetValueAsUnsigned():#x}' for i in range(4)] +self.expect( +'memory find -c 5 -s "needle" `mem_with_holes` `mem_with_holes+5*pagesize`', +substrs=matches + ["no more matches within the range"], +) diff --git a/lldb/test/API/functionalities/memory/find/main.cpp b/lldb/test/API/functionalities/memory/find/main.cpp index e3dcfc762ee0f9..e5525e3ca1f73f 100644 --- a/lldb/test/API/functionalities/memory/find/main.cpp +++ b/lldb/test/API/functionalities/memory/find/main.cpp @@ -1,9 +1,75 @@ -#include -#include - -int main (int argc, char const *argv[]) -{ -const char* stringdata = "hello world; I like to write text in const char pointers"; -uint8_t bytedata[] = {0xAA,0xBB,0xCC,0xDD,0xEE,0xFF,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99}; -return 0; // break here +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include "Windows.h" + +int getpagesize() { + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + return system_info.dwPageSize; +} + +void *allocate_memory_with_holes() { + int pagesize = getpagesize(); + void *mem = VirtualAlloc(nullptr, 5 * pagesize, MEM_RESERVE, PAGE_NOACCESS); + if (!mem) { +
[Lldb-commits] [lldb] [WIP] memory find speedup+bugfix (PR #104193)
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 20b2c9f10fe09f2c5cbd3da7f0af8df24f62e899...a537a48c444e9dec3a85241d9726d6f3187a43cf lldb/test/API/functionalities/memory/find/TestMemoryFind.py `` View the diff from darker here. ``diff --- TestMemoryFind.py 2024-08-15 14:00:02.00 + +++ TestMemoryFind.py 2024-08-15 14:03:36.803186 + @@ -79,13 +79,18 @@ 'memory find -s "nothere" `stringdata` `stringdata+10`', substrs=["data not found within the range."], ) pagesize = self.frame().FindVariable("pagesize").GetValueAsUnsigned() -mem_with_holes = self.frame().FindVariable("mem_with_holes").GetValueAsUnsigned() +mem_with_holes = ( +self.frame().FindVariable("mem_with_holes").GetValueAsUnsigned() +) matches_var = self.frame().FindVariable("matches") self.assertEqual(matches_var.GetNumChildren(), 4) -matches = [f'data found at location: {matches_var.GetChildAtIndex(i).GetValueAsUnsigned():#x}' for i in range(4)] +matches = [ +f"data found at location: {matches_var.GetChildAtIndex(i).GetValueAsUnsigned():#x}" +for i in range(4) +] self.expect( 'memory find -c 5 -s "needle" `mem_with_holes` `mem_with_holes+5*pagesize`', substrs=matches + ["no more matches within the range"], ) `` https://github.com/llvm/llvm-project/pull/104193 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][NFC] Moved FindSchemeByProtocol() from Acceptor to Socket (PR #104439)
https://github.com/slydiman created https://github.com/llvm/llvm-project/pull/104439 This is the prerequisite for #104238. >From e4dce57456f354c30e8a9f896354aeb12075d58b Mon Sep 17 00:00:00 2001 From: Dmitry Vasilyev Date: Thu, 15 Aug 2024 17:59:55 +0400 Subject: [PATCH] [lldb][NFC] Moved FindSchemeByProtocol() from Acceptor to Socket This is the prerequisite for #104238. --- lldb/include/lldb/Host/Socket.h | 4 +++ lldb/source/Host/common/Socket.cpp | 32 +++ lldb/tools/lldb-server/Acceptor.cpp | 39 +++-- 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/lldb/include/lldb/Host/Socket.h b/lldb/include/lldb/Host/Socket.h index 4dad88e78faa11..573c881f727d8f 100644 --- a/lldb/include/lldb/Host/Socket.h +++ b/lldb/include/lldb/Host/Socket.h @@ -60,6 +60,10 @@ class Socket : public IOObject { ~Socket() override; + static const char *FindSchemeByProtocol(const SocketProtocol protocol); + static bool FindProtocolByScheme(const char *scheme, + SocketProtocol &protocol); + static llvm::Error Initialize(); static void Terminate(); diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp index f9911cf136cbd0..7364a12280cfdd 100644 --- a/lldb/source/Host/common/Socket.cpp +++ b/lldb/source/Host/common/Socket.cpp @@ -70,6 +70,38 @@ static bool IsInterrupted() { #endif } +struct SocketScheme { + const char *m_scheme; + const Socket::SocketProtocol m_protocol; +}; + +static SocketScheme socket_schemes[] = { +{"tcp", Socket::ProtocolTcp}, +{"udp", Socket::ProtocolUdp}, +{"unix", Socket::ProtocolUnixDomain}, +{"unix-abstract", Socket::ProtocolUnixAbstract}, +}; + +const char * +Socket::FindSchemeByProtocol(const Socket::SocketProtocol protocol) { + for (auto s : socket_schemes) { +if (s.m_protocol == protocol) + return s.m_scheme; + } + return nullptr; +} + +bool Socket::FindProtocolByScheme(const char *scheme, + Socket::SocketProtocol &protocol) { + for (auto s : socket_schemes) { +if (!strcmp(s.m_scheme, scheme)) { + protocol = s.m_protocol; + return true; +} + } + return false; +} + Socket::Socket(SocketProtocol protocol, bool should_close, bool child_processes_inherit) : IOObject(eFDTypeSocket), m_protocol(protocol), diff --git a/lldb/tools/lldb-server/Acceptor.cpp b/lldb/tools/lldb-server/Acceptor.cpp index 2037f1e0f62b9a..cf9a55c6c07da5 100644 --- a/lldb/tools/lldb-server/Acceptor.cpp +++ b/lldb/tools/lldb-server/Acceptor.cpp @@ -22,40 +22,6 @@ using namespace lldb_private; using namespace lldb_private::lldb_server; using namespace llvm; -namespace { - -struct SocketScheme { - const char *m_scheme; - const Socket::SocketProtocol m_protocol; -}; - -SocketScheme socket_schemes[] = { -{"tcp", Socket::ProtocolTcp}, -{"udp", Socket::ProtocolUdp}, -{"unix", Socket::ProtocolUnixDomain}, -{"unix-abstract", Socket::ProtocolUnixAbstract}, -}; - -bool FindProtocolByScheme(const char *scheme, - Socket::SocketProtocol &protocol) { - for (auto s : socket_schemes) { -if (!strcmp(s.m_scheme, scheme)) { - protocol = s.m_protocol; - return true; -} - } - return false; -} - -const char *FindSchemeByProtocol(const Socket::SocketProtocol protocol) { - for (auto s : socket_schemes) { -if (s.m_protocol == protocol) - return s.m_scheme; - } - return nullptr; -} -} - Status Acceptor::Listen(int backlog) { return m_listener_socket_up->Listen(StringRef(m_name), backlog); } @@ -74,7 +40,7 @@ Socket::SocketProtocol Acceptor::GetSocketProtocol() const { } const char *Acceptor::GetSocketScheme() const { - return FindSchemeByProtocol(GetSocketProtocol()); + return Socket::FindSchemeByProtocol(GetSocketProtocol()); } std::string Acceptor::GetLocalSocketId() const { return m_local_socket_id(); } @@ -87,7 +53,8 @@ std::unique_ptr Acceptor::Create(StringRef name, Socket::SocketProtocol socket_protocol = Socket::ProtocolUnixDomain; // Try to match socket name as URL - e.g., tcp://localhost: if (std::optional res = URI::Parse(name)) { -if (!FindProtocolByScheme(res->scheme.str().c_str(), socket_protocol)) +if (!Socket::FindProtocolByScheme(res->scheme.str().c_str(), + socket_protocol)) error.SetErrorStringWithFormat("Unknown protocol scheme \"%s\"", res->scheme.str().c_str()); else ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][NFC] Moved FindSchemeByProtocol() from Acceptor to Socket (PR #104439)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Dmitry Vasilyev (slydiman) Changes This is the prerequisite for #104238. --- Full diff: https://github.com/llvm/llvm-project/pull/104439.diff 3 Files Affected: - (modified) lldb/include/lldb/Host/Socket.h (+4) - (modified) lldb/source/Host/common/Socket.cpp (+32) - (modified) lldb/tools/lldb-server/Acceptor.cpp (+3-36) ``diff diff --git a/lldb/include/lldb/Host/Socket.h b/lldb/include/lldb/Host/Socket.h index 4dad88e78faa11..573c881f727d8f 100644 --- a/lldb/include/lldb/Host/Socket.h +++ b/lldb/include/lldb/Host/Socket.h @@ -60,6 +60,10 @@ class Socket : public IOObject { ~Socket() override; + static const char *FindSchemeByProtocol(const SocketProtocol protocol); + static bool FindProtocolByScheme(const char *scheme, + SocketProtocol &protocol); + static llvm::Error Initialize(); static void Terminate(); diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp index f9911cf136cbd0..7364a12280cfdd 100644 --- a/lldb/source/Host/common/Socket.cpp +++ b/lldb/source/Host/common/Socket.cpp @@ -70,6 +70,38 @@ static bool IsInterrupted() { #endif } +struct SocketScheme { + const char *m_scheme; + const Socket::SocketProtocol m_protocol; +}; + +static SocketScheme socket_schemes[] = { +{"tcp", Socket::ProtocolTcp}, +{"udp", Socket::ProtocolUdp}, +{"unix", Socket::ProtocolUnixDomain}, +{"unix-abstract", Socket::ProtocolUnixAbstract}, +}; + +const char * +Socket::FindSchemeByProtocol(const Socket::SocketProtocol protocol) { + for (auto s : socket_schemes) { +if (s.m_protocol == protocol) + return s.m_scheme; + } + return nullptr; +} + +bool Socket::FindProtocolByScheme(const char *scheme, + Socket::SocketProtocol &protocol) { + for (auto s : socket_schemes) { +if (!strcmp(s.m_scheme, scheme)) { + protocol = s.m_protocol; + return true; +} + } + return false; +} + Socket::Socket(SocketProtocol protocol, bool should_close, bool child_processes_inherit) : IOObject(eFDTypeSocket), m_protocol(protocol), diff --git a/lldb/tools/lldb-server/Acceptor.cpp b/lldb/tools/lldb-server/Acceptor.cpp index 2037f1e0f62b9a..cf9a55c6c07da5 100644 --- a/lldb/tools/lldb-server/Acceptor.cpp +++ b/lldb/tools/lldb-server/Acceptor.cpp @@ -22,40 +22,6 @@ using namespace lldb_private; using namespace lldb_private::lldb_server; using namespace llvm; -namespace { - -struct SocketScheme { - const char *m_scheme; - const Socket::SocketProtocol m_protocol; -}; - -SocketScheme socket_schemes[] = { -{"tcp", Socket::ProtocolTcp}, -{"udp", Socket::ProtocolUdp}, -{"unix", Socket::ProtocolUnixDomain}, -{"unix-abstract", Socket::ProtocolUnixAbstract}, -}; - -bool FindProtocolByScheme(const char *scheme, - Socket::SocketProtocol &protocol) { - for (auto s : socket_schemes) { -if (!strcmp(s.m_scheme, scheme)) { - protocol = s.m_protocol; - return true; -} - } - return false; -} - -const char *FindSchemeByProtocol(const Socket::SocketProtocol protocol) { - for (auto s : socket_schemes) { -if (s.m_protocol == protocol) - return s.m_scheme; - } - return nullptr; -} -} - Status Acceptor::Listen(int backlog) { return m_listener_socket_up->Listen(StringRef(m_name), backlog); } @@ -74,7 +40,7 @@ Socket::SocketProtocol Acceptor::GetSocketProtocol() const { } const char *Acceptor::GetSocketScheme() const { - return FindSchemeByProtocol(GetSocketProtocol()); + return Socket::FindSchemeByProtocol(GetSocketProtocol()); } std::string Acceptor::GetLocalSocketId() const { return m_local_socket_id(); } @@ -87,7 +53,8 @@ std::unique_ptr Acceptor::Create(StringRef name, Socket::SocketProtocol socket_protocol = Socket::ProtocolUnixDomain; // Try to match socket name as URL - e.g., tcp://localhost: if (std::optional res = URI::Parse(name)) { -if (!FindProtocolByScheme(res->scheme.str().c_str(), socket_protocol)) +if (!Socket::FindProtocolByScheme(res->scheme.str().c_str(), + socket_protocol)) error.SetErrorStringWithFormat("Unknown protocol scheme \"%s\"", res->scheme.str().c_str()); else `` https://github.com/llvm/llvm-project/pull/104439 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
https://github.com/slydiman edited https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][WIP] memory find speedup+bugfix (PR #104193)
https://github.com/nikic edited https://github.com/llvm/llvm-project/pull/104193 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][NFC] Moved FindSchemeByProtocol() from Acceptor to Socket (PR #104439)
DavidSpickett wrote: So to test https://github.com/llvm/llvm-project/pull/104238 I should apply this first, or is it included in that? https://github.com/llvm/llvm-project/pull/104439 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][NFC] Moved FindSchemeByProtocol() from Acceptor to Socket (PR #104439)
slydiman wrote: > So to test #104238 I should apply this first, or is it included in that? Don't include that. I will rebase #104238 after merging this patch. https://github.com/llvm/llvm-project/pull/104439 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
https://github.com/slydiman edited https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
https://github.com/slydiman edited https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
@@ -20,6 +20,10 @@ #include #include +#ifdef SendMessage +#undef SendMessage +#endif + slydiman wrote: I will retest it after #104439. Probably we won't need it. https://github.com/llvm/llvm-project/pull/104238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix single thread stepping timeout race condition (PR #104195)
Endilll wrote: FYI there was a Linux pre-commit CI build recently that timed out on `functionalities/single-thread-step/TestSingleThreadStepTimeout.py`: https://buildkite.com/llvm-project/github-pull-requests/builds/91810 Relevant part of the log: https://gist.github.com/Endilll/a15335f75f2aa4b211c0b2181b25ff8f https://github.com/llvm/llvm-project/pull/104195 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Removed gdbserver ports map from lldb-server (PR #104238)
https://github.com/slydiman updated https://github.com/llvm/llvm-project/pull/104238 >From 5732bda3558a0d55f2f7b9d1a3722d11458a2360 Mon Sep 17 00:00:00 2001 From: Dmitry Vasilyev Date: Wed, 14 Aug 2024 22:36:52 +0400 Subject: [PATCH 1/2] [lldb] Removed gdbserver ports map from lldb-server Listen to gdbserver-port, accept the connection and run `lldb-server gdbserver --fd` on all platforms. Added acceptor_gdb and gdb_thread to lldb-platform.cpp SharedSocket has been moved to ConnectionFileDescriptorPosix. Parameters --min-gdbserver-port and --max-gdbserver-port are deprecated now. This is the part 2 of #101283. Fixes #97537, fixes #101475. --- lldb/docs/man/lldb-server.rst | 11 +- lldb/docs/resources/qemu-testing.rst | 19 +- .../posix/ConnectionFileDescriptorPosix.h | 26 ++ .../posix/ConnectionFileDescriptorPosix.cpp | 110 +- .../gdb-remote/GDBRemoteCommunication.cpp | 41 ++- .../gdb-remote/GDBRemoteCommunication.h | 8 +- .../GDBRemoteCommunicationServerPlatform.cpp | 290 ++-- .../GDBRemoteCommunicationServerPlatform.h| 83 + .../Process/gdb-remote/ProcessGDBRemote.cpp | 2 +- .../Shell/lldb-server/TestGdbserverPort.test | 4 - lldb/tools/lldb-server/Acceptor.cpp | 6 +- lldb/tools/lldb-server/Acceptor.h | 3 + lldb/tools/lldb-server/lldb-gdbserver.cpp | 23 +- lldb/tools/lldb-server/lldb-platform.cpp | 326 -- .../Process/gdb-remote/CMakeLists.txt | 1 - .../Process/gdb-remote/PortMapTest.cpp| 115 -- .../tools/lldb-server/tests/TestClient.h | 4 + 17 files changed, 461 insertions(+), 611 deletions(-) delete mode 100644 lldb/test/Shell/lldb-server/TestGdbserverPort.test delete mode 100644 lldb/unittests/Process/gdb-remote/PortMapTest.cpp diff --git a/lldb/docs/man/lldb-server.rst b/lldb/docs/man/lldb-server.rst index a67c00b305f6d2..31f5360df5e23e 100644 --- a/lldb/docs/man/lldb-server.rst +++ b/lldb/docs/man/lldb-server.rst @@ -147,15 +147,8 @@ GDB-SERVER CONNECTIONS .. option:: --gdbserver-port - Define a port to be used for gdb-server connections. Can be specified multiple - times to allow multiple ports. Has no effect if --min-gdbserver-port - and --max-gdbserver-port are specified. - -.. option:: --min-gdbserver-port -.. option:: --max-gdbserver-port - - Specify the range of ports that can be used for gdb-server connections. Both - options need to be specified simultaneously. Overrides --gdbserver-port. + Define a port to be used for gdb-server connections. This port is used for + multiple connections. .. option:: --port-offset diff --git a/lldb/docs/resources/qemu-testing.rst b/lldb/docs/resources/qemu-testing.rst index 51a30b11717a87..e102f84a1d31f4 100644 --- a/lldb/docs/resources/qemu-testing.rst +++ b/lldb/docs/resources/qemu-testing.rst @@ -149,7 +149,6 @@ to the host (refer to QEMU's manuals for the specific options). * At least one to connect to the intial ``lldb-server``. * One more if you want to use ``lldb-server`` in ``platform mode``, and have it start a ``gdbserver`` instance for you. -* A bunch more if you want to run tests against the ``lldb-server`` platform. If you are doing either of the latter 2 you should also restrict what ports ``lldb-server tries`` to use, otherwise it will randomly pick one that is almost @@ -157,22 +156,14 @@ certainly not forwarded. An example of this is shown below. :: - $ lldb-server plaform --server --listen 0.0.0.0:54321 \ ---min-gdbserver-port 49140 --max-gdbserver-port 49150 + $ lldb-server plaform --server --listen 0.0.0.0:54321 --gdbserver-port 49140 The result of this is that: * ``lldb-server`` platform mode listens externally on port ``54321``. -* When it is asked to start a new gdbserver mode instance, it will use a port - in the range ``49140`` to ``49150``. +* When it is asked to start a new gdbserver mode instance, it will use the port + ``49140``. -Your VM configuration should have ports ``54321``, and ``49140`` to ``49150`` -forwarded for this to work. - -.. note:: - These options are used to create a "port map" within ``lldb-server``. - Unfortunately this map is not cleaned up on Windows on connection close, - and across a few uses you may run out of valid ports. To work around this, - restart the platform every so often, especially after running a set of tests. - This is tracked here: https://github.com/llvm/llvm-project/issues/90923 +Your VM configuration should have ports ``54321`` and ``49140`` forwarded for +this to work. diff --git a/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h b/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h index 35773d5907e913..08f486b92e0f07 100644 --- a/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h +++ b/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h @@ -26,6 +26,32 @@ class Status; class Socket; class SocketAddress; +#
[Lldb-commits] [lldb] [lldb] Realpath symlinks for breakpoints (PR #102223)
https://github.com/clayborg approved this pull request. https://github.com/llvm/llvm-project/pull/102223 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix single thread stepping timeout race condition (PR #104195)
jeffreytan81 wrote: @labath, thanks. I am able to reproduce the failure after adding the sleep and running tests in a loop for 4 iterations. I will take a look after landing this race condition fix. https://github.com/llvm/llvm-project/pull/104195 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 54154f9 - Fix single thread stepping timeout race condition (#104195)
Author: jeffreytan81 Date: 2024-08-15T09:57:01-07:00 New Revision: 54154f9f06e08b7ab3c7294352601ca4c6e5e160 URL: https://github.com/llvm/llvm-project/commit/54154f9f06e08b7ab3c7294352601ca4c6e5e160 DIFF: https://github.com/llvm/llvm-project/commit/54154f9f06e08b7ab3c7294352601ca4c6e5e160.diff LOG: Fix single thread stepping timeout race condition (#104195) This PR fixes a potential race condition in https://github.com/llvm/llvm-project/pull/90930. This race can happen because the original code set `m_info->m_isAlive = true` **after** the timer thread is created. So if there is a context switch happens and timer thread checks `m_info->m_isAlive` before main thread got a chance to run `m_info->m_isAlive = true`, the timer thread may treat `ThreadPlanSingleThreadTimeout` as not alive and simply exit resulting in async interrupt never being sent to resume all threads (deadlock). The PR fixes the race by initializing all states **before** worker timer thread creates. Co-authored-by: jeffreytan81 Added: Modified: lldb/source/Target/ThreadPlanSingleThreadTimeout.cpp Removed: diff --git a/lldb/source/Target/ThreadPlanSingleThreadTimeout.cpp b/lldb/source/Target/ThreadPlanSingleThreadTimeout.cpp index 0a939d55f4ce49..806ba95c508b7c 100644 --- a/lldb/source/Target/ThreadPlanSingleThreadTimeout.cpp +++ b/lldb/source/Target/ThreadPlanSingleThreadTimeout.cpp @@ -29,10 +29,10 @@ ThreadPlanSingleThreadTimeout::ThreadPlanSingleThreadTimeout( : ThreadPlan(ThreadPlan::eKindSingleThreadTimeout, "Single thread timeout", thread, eVoteNo, eVoteNoOpinion), m_info(info), m_state(State::WaitTimeout) { - // TODO: reuse m_timer_thread without recreation. - m_timer_thread = std::thread(TimeoutThreadFunc, this); m_info->m_isAlive = true; m_state = m_info->m_last_state; + // TODO: reuse m_timer_thread without recreation. + m_timer_thread = std::thread(TimeoutThreadFunc, this); } ThreadPlanSingleThreadTimeout::~ThreadPlanSingleThreadTimeout() { ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix single thread stepping timeout race condition (PR #104195)
https://github.com/jeffreytan81 closed https://github.com/llvm/llvm-project/pull/104195 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/104109 >From 8f2f84294ea3875c88ce36a4980fd3a3afce01de Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 18 Jun 2024 10:38:09 -0700 Subject: [PATCH 1/3] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus To create elf core files there are multiple notes in the core file that contain these structs as the note. These populate methods take a Process and produce fully specified structures that can be used to fill these note sections. The pr also adds tests to ensure these structs are correctly populated. --- .../Process/elf-core/ThreadElfCore.cpp| 134 +++ .../Plugins/Process/elf-core/ThreadElfCore.h | 7 + lldb/unittests/Process/CMakeLists.txt | 1 + .../unittests/Process/elf-core/CMakeLists.txt | 15 ++ .../Process/elf-core/ThreadElfCoreTest.cpp| 162 ++ 5 files changed, 319 insertions(+) create mode 100644 lldb/unittests/Process/elf-core/CMakeLists.txt create mode 100644 lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 2a83163884e168..fdb4a5837cd462 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { + ELFLinuxPrStatus prstatus{}; + prstatus.pr_pid = thread_sp->GetID(); + lldb::ProcessSP process_sp = thread_sp->GetProcess(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prstatus.pr_ppid = info.GetParentProcessID(); + prstatus.pr_pgrp = info.GetProcessGroupID(); + prstatus.pr_sid = info.GetProcessSessionID(); + prstatus.pr_utime = copy_timespecs(info.GetUserTime()); + prstatus.pr_stime = copy_timespecs(info.GetSystemTime()); + prstatus.pr_cutime = copy_timespecs(info.GetCumulativeUserTime()); + prstatus.pr_cstime = copy_timespecs(info.GetCumulativeSystemTime()); + return prstatus; +} + // Parse PRPSINFO from NOTE entry ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { memset(this, 0, sizeof(ELFLinuxPrPsInfo)); @@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +ELFLinuxPrPsInfo::Populate(const lldb::ProcessSP &process_sp) { + ELFLinuxPrPsInfo prpsinfo{}; + prpsinfo.pr_pid = process_sp->GetID(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prpsinfo.pr_nice = info.GetPriorityValue().value_or(0); + prpsinfo.pr_zomb = 0; + if (auto zombie_opt = info.IsZombie(); zombie_opt.value_or(false)) { +prpsinfo.pr_zomb = 1; + } + /** + * In the linux kernel this comes from: + * state = READ_ONCE(p->__state); + * i = state ? ffz(~state) + 1 : 0; + * psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i]; + * + * So we replicate that here. From proc_pid_stats(5) + * R = Running + * S = Sleeping on uninterrutible wait + * D = Waiting on uninterruptable disk sleep + * T = Tracing stop + * Z = Zombie + * W = Paging + */ + lldb::StateType process_state = process_sp->GetState(); + switch (process_state) { + case lldb::StateType::eStateSuspended: +prpsinfo.pr_sname = 'S'; +prpsinfo.pr_state = 1; +break; + case lldb::StateType::eStateStopped: +[[fallthrough]]; + case lldb::StateType::eStateStepping: +prpsinfo.pr_sname = 'T'; +prpsinfo.pr_state = 3; +break; + case lldb::StateType::eStateUnloaded: +[[fallthrough]]; + case lldb::StateType::eStateRunning: +prpsinfo.pr_sname = 'R'; +prpsinfo.pr_state = 0; +break; + default: +break; + } + + /** + * pr_flags is left as 0. The values (in linux) are specific + * to the kernel. We recover them from the proc filesystem + * but don't put them in ProcessInfo because it would really + * become very linux specific and the utility here seems pretty + * dubious + */ + + if (info.EffectiveUserIDIsValid()) { +prpsinfo.pr_uid = info.GetUserID(); + } + if (info.EffectiveGroupIDIsValid()) { +prpsinfo.pr_gid = info.GetGroupID(); + } + + if (info.ParentProcessIDIsValid()) { +prpsinfo.pr_ppid = info.GetParentProcessID(); + } + + if (info.ProcessGroupIDIsValid()) { +prpsinfo.pr_pgrp = info.GetProcessGroupID(); + } + + if (info.ProcessSessionIDIsValid()) { +prpsinfo.pr_sid = info.GetProcessSessionID(); + } + constexpr size_t fname_len = std::extent_v; + static_assert(fname_len > 0, "This shou
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -0,0 +1,162 @@ +//===-- ThreadElfCoreTest.cpp *- C++ +//-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +#include "Plugins/Process/elf-core/ThreadElfCore.h" +#include "Plugins/Platform/Linux/PlatformLinux.h" +#include "TestingSupport/TestUtilities.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/Listener.h" +#include "llvm/TargetParser/Triple.h" +#include "gtest/gtest.h" + +#include +#include +#include +#include + +using namespace lldb_private; + +namespace { + +struct ElfCoreTest : public testing::Test { + static void SetUpTestCase() { +FileSystem::Initialize(); +HostInfo::Initialize(); +platform_linux::PlatformLinux::Initialize(); +std::call_once(TestUtilities::g_debugger_initialize_flag, + []() { Debugger::Initialize(nullptr); }); + } + static void TearDownTestCase() { +platform_linux::PlatformLinux::Terminate(); +HostInfo::Terminate(); +FileSystem::Terminate(); + } +}; + +struct DummyProcess : public Process { + DummyProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp) + : Process(target_sp, listener_sp) { +SetID(getpid()); + } + + bool CanDebug(lldb::TargetSP target, bool plugin_specified_by_name) override { +return true; + } + Status DoDestroy() override { return {}; } + void RefreshStateAfterStop() override {} + size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, + Status &error) override { +return 0; + } + bool DoUpdateThreadList(ThreadList &old_thread_list, + ThreadList &new_thread_list) override { +return false; + } + llvm::StringRef GetPluginName() override { return "Dummy"; } +}; + +struct DummyThread : public Thread { + using Thread::Thread; + + ~DummyThread() override { DestroyThread(); } + + void RefreshStateAfterStop() override {} + + lldb::RegisterContextSP GetRegisterContext() override { return nullptr; } + + lldb::RegisterContextSP + CreateRegisterContextForFrame(StackFrame *frame) override { +return nullptr; + } + + bool CalculateStopInfo() override { return false; } +}; + +lldb::TargetSP CreateTarget(lldb::DebuggerSP &debugger_sp, ArchSpec &arch) { + lldb::PlatformSP platform_sp; + lldb::TargetSP target_sp; + debugger_sp->GetTargetList().CreateTarget( + *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp); + return target_sp; +} + +lldb::ThreadSP CreateThread(lldb::ProcessSP &process_sp) { + lldb::ThreadSP thread_sp = + std::make_shared(*process_sp.get(), gettid()); + if (thread_sp == nullptr) { +return nullptr; + } + process_sp->GetThreadList().AddThread(thread_sp); + + return thread_sp; +} + +} // namespace + +TEST_F(ElfCoreTest, PopulatePrpsInfoTest) { + ArchSpec arch{HostInfo::GetTargetTriple()}; + lldb::DebuggerSP debugger_sp = Debugger::CreateInstance(); + ASSERT_TRUE(debugger_sp); + + lldb::TargetSP target_sp = CreateTarget(debugger_sp, arch); + ASSERT_TRUE(target_sp); + + lldb::ListenerSP listener_sp(Listener::MakeListener("dummy")); + lldb::ProcessSP process_sp = + std::make_shared(target_sp, listener_sp); + ASSERT_TRUE(process_sp); + auto prpsinfo_opt = ELFLinuxPrPsInfo::Populate(process_sp); feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][Data Formatters] Calculate average and total time for summary providers within lldb (PR #102708)
https://github.com/Jlalond updated https://github.com/llvm/llvm-project/pull/102708 >From c0a7286b0107d3161b18de8f05d4d016150e96a5 Mon Sep 17 00:00:00 2001 From: Jacob Lalonde Date: Thu, 8 Aug 2024 08:58:52 -0700 Subject: [PATCH 01/11] Initial attempt at new classes Summary statistics in SummaryStatistics.h/cpp. --- lldb/include/lldb/Target/SummaryStatistics.h | 37 lldb/include/lldb/Target/Target.h| 5 +++ lldb/source/Core/ValueObject.cpp | 5 +++ lldb/source/Target/CMakeLists.txt| 1 + lldb/source/Target/SummaryStatistics.cpp | 26 ++ lldb/source/Target/Target.cpp| 9 + 6 files changed, 83 insertions(+) create mode 100644 lldb/include/lldb/Target/SummaryStatistics.h create mode 100644 lldb/source/Target/SummaryStatistics.cpp diff --git a/lldb/include/lldb/Target/SummaryStatistics.h b/lldb/include/lldb/Target/SummaryStatistics.h new file mode 100644 index 00..0198249ba0b170 --- /dev/null +++ b/lldb/include/lldb/Target/SummaryStatistics.h @@ -0,0 +1,37 @@ +//===-- SummaryStatistics.h -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLDB_TARGET_SUMMARYSTATISTICS_H +#define LLDB_TARGET_SUMMARYSTATISTICS_H + + +#include "lldb/Target/Statistics.h" +#include "llvm/ADT/StringRef.h" + +namespace lldb_private { + +class SummaryStatistics { +public: + SummaryStatistics(lldb_private::ConstString name) : +m_total_time(), m_name(name), m_summary_count(0) {} + + lldb_private::StatsDuration &GetDurationReference(); + + lldb_private::ConstString GetName() const; + + uint64_t GetSummaryCount() const; + +private: + lldb_private::StatsDuration m_total_time; + lldb_private::ConstString m_name; + uint64_t m_summary_count; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_SUMMARYSTATISTICS_H diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 119dff4d498199..ee6a009b0af95d 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -30,6 +30,7 @@ #include "lldb/Target/PathMappingList.h" #include "lldb/Target/SectionLoadHistory.h" #include "lldb/Target/Statistics.h" +#include "lldb/Target/SummaryStatistics.h" #include "lldb/Target/ThreadSpec.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Broadcaster.h" @@ -258,6 +259,7 @@ class TargetProperties : public Properties { bool GetDebugUtilityExpression() const; + private: std::optional GetExperimentalPropertyValue(size_t prop_idx, @@ -1221,6 +1223,8 @@ class Target : public std::enable_shared_from_this, void ClearAllLoadedSections(); + lldb_private::StatsDuration& GetSummaryProviderDuration(lldb_private::ConstString summary_provider_name); + /// Set the \a Trace object containing processor trace information of this /// target. /// @@ -1554,6 +1558,7 @@ class Target : public std::enable_shared_from_this, std::string m_label; ModuleList m_images; ///< The list of images for this process (shared /// libraries and anything dynamically loaded). + std::map m_summary_stats_map; SectionLoadHistory m_section_load_history; BreakpointList m_breakpoint_list; BreakpointList m_internal_breakpoint_list; diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 8f72efc2299b4f..bed4ab8d69cbda 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -615,6 +615,11 @@ bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr, m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on // the synthetic children being // up-to-date (e.g. ${svar%#}) +StatsDuration &summary_duration = GetExecutionContextRef() +.GetProcessSP() +->GetTarget() + .GetSummaryProviderDuration(GetTypeName()); +ElapsedTime elapsed(summary_duration); summary_ptr->FormatObject(this, destination, actual_options); } m_flags.m_is_getting_summary = false; diff --git a/lldb/source/Target/CMakeLists.txt b/lldb/source/Target/CMakeLists.txt index a42c44b761dc56..e51da37cd84db3 100644 --- a/lldb/source/Target/CMakeLists.txt +++ b/lldb/source/Target/CMakeLists.txt @@ -46,6 +46,7 @@ add_lldb_library(lldbTarget Statistics.cpp StopInfo.cpp StructuredDataPlugin.cpp + SummaryStatistics.cpp SystemRuntime.cpp Target.cpp TargetList.cpp diff --git a/lldb/source/Target/SummaryStatistics.cpp b/lldb/so
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { feg208 wrote: yes we should. In linux (and I guess in FreeBSD as well) a prstatus object is created for each thread which you can see in ProcessELFCore ``` 904 case ELF::NT_PRSTATUS: { 905 have_prstatus = true; 906 ELFLinuxPrStatus prstatus; 907 Status status = prstatus.Parse(note.data, arch); 908 if (status.Fail()) 909 return status.ToError(); 910 thread_data.prstatus_sig = prstatus.pr_cursig; 911 thread_data.tid = prstatus.pr_pid; 912 uint32_t header_size = ELFLinuxPrStatus::GetSize(arch); 913 size_t len = note.data.GetByteSize() - header_size; 914 thread_data.gpregset = DataExtractor(note.data, header_size, len); 915 break; ``` The tid is the pid. So in SaveCore we'll need to iterate over all the threads to build each struct. https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/104109 >From 8f2f84294ea3875c88ce36a4980fd3a3afce01de Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 18 Jun 2024 10:38:09 -0700 Subject: [PATCH 1/4] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus To create elf core files there are multiple notes in the core file that contain these structs as the note. These populate methods take a Process and produce fully specified structures that can be used to fill these note sections. The pr also adds tests to ensure these structs are correctly populated. --- .../Process/elf-core/ThreadElfCore.cpp| 134 +++ .../Plugins/Process/elf-core/ThreadElfCore.h | 7 + lldb/unittests/Process/CMakeLists.txt | 1 + .../unittests/Process/elf-core/CMakeLists.txt | 15 ++ .../Process/elf-core/ThreadElfCoreTest.cpp| 162 ++ 5 files changed, 319 insertions(+) create mode 100644 lldb/unittests/Process/elf-core/CMakeLists.txt create mode 100644 lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 2a83163884e168..fdb4a5837cd462 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { + ELFLinuxPrStatus prstatus{}; + prstatus.pr_pid = thread_sp->GetID(); + lldb::ProcessSP process_sp = thread_sp->GetProcess(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prstatus.pr_ppid = info.GetParentProcessID(); + prstatus.pr_pgrp = info.GetProcessGroupID(); + prstatus.pr_sid = info.GetProcessSessionID(); + prstatus.pr_utime = copy_timespecs(info.GetUserTime()); + prstatus.pr_stime = copy_timespecs(info.GetSystemTime()); + prstatus.pr_cutime = copy_timespecs(info.GetCumulativeUserTime()); + prstatus.pr_cstime = copy_timespecs(info.GetCumulativeSystemTime()); + return prstatus; +} + // Parse PRPSINFO from NOTE entry ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { memset(this, 0, sizeof(ELFLinuxPrPsInfo)); @@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +ELFLinuxPrPsInfo::Populate(const lldb::ProcessSP &process_sp) { + ELFLinuxPrPsInfo prpsinfo{}; + prpsinfo.pr_pid = process_sp->GetID(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prpsinfo.pr_nice = info.GetPriorityValue().value_or(0); + prpsinfo.pr_zomb = 0; + if (auto zombie_opt = info.IsZombie(); zombie_opt.value_or(false)) { +prpsinfo.pr_zomb = 1; + } + /** + * In the linux kernel this comes from: + * state = READ_ONCE(p->__state); + * i = state ? ffz(~state) + 1 : 0; + * psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i]; + * + * So we replicate that here. From proc_pid_stats(5) + * R = Running + * S = Sleeping on uninterrutible wait + * D = Waiting on uninterruptable disk sleep + * T = Tracing stop + * Z = Zombie + * W = Paging + */ + lldb::StateType process_state = process_sp->GetState(); + switch (process_state) { + case lldb::StateType::eStateSuspended: +prpsinfo.pr_sname = 'S'; +prpsinfo.pr_state = 1; +break; + case lldb::StateType::eStateStopped: +[[fallthrough]]; + case lldb::StateType::eStateStepping: +prpsinfo.pr_sname = 'T'; +prpsinfo.pr_state = 3; +break; + case lldb::StateType::eStateUnloaded: +[[fallthrough]]; + case lldb::StateType::eStateRunning: +prpsinfo.pr_sname = 'R'; +prpsinfo.pr_state = 0; +break; + default: +break; + } + + /** + * pr_flags is left as 0. The values (in linux) are specific + * to the kernel. We recover them from the proc filesystem + * but don't put them in ProcessInfo because it would really + * become very linux specific and the utility here seems pretty + * dubious + */ + + if (info.EffectiveUserIDIsValid()) { +prpsinfo.pr_uid = info.GetUserID(); + } + if (info.EffectiveGroupIDIsValid()) { +prpsinfo.pr_gid = info.GetGroupID(); + } + + if (info.ParentProcessIDIsValid()) { +prpsinfo.pr_ppid = info.GetParentProcessID(); + } + + if (info.ProcessGroupIDIsValid()) { +prpsinfo.pr_pgrp = info.GetProcessGroupID(); + } + + if (info.ProcessSessionIDIsValid()) { +prpsinfo.pr_sid = info.GetProcessSessionID(); + } + constexpr size_t fname_len = std::extent_v; + static_assert(fname_len > 0, "This shou
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { + ELFLinuxPrStatus prstatus{}; + prstatus.pr_pid = thread_sp->GetID(); + lldb::ProcessSP process_sp = thread_sp->GetProcess(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/104109 >From 8f2f84294ea3875c88ce36a4980fd3a3afce01de Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 18 Jun 2024 10:38:09 -0700 Subject: [PATCH 1/5] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus To create elf core files there are multiple notes in the core file that contain these structs as the note. These populate methods take a Process and produce fully specified structures that can be used to fill these note sections. The pr also adds tests to ensure these structs are correctly populated. --- .../Process/elf-core/ThreadElfCore.cpp| 134 +++ .../Plugins/Process/elf-core/ThreadElfCore.h | 7 + lldb/unittests/Process/CMakeLists.txt | 1 + .../unittests/Process/elf-core/CMakeLists.txt | 15 ++ .../Process/elf-core/ThreadElfCoreTest.cpp| 162 ++ 5 files changed, 319 insertions(+) create mode 100644 lldb/unittests/Process/elf-core/CMakeLists.txt create mode 100644 lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 2a83163884e168..fdb4a5837cd462 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { + ELFLinuxPrStatus prstatus{}; + prstatus.pr_pid = thread_sp->GetID(); + lldb::ProcessSP process_sp = thread_sp->GetProcess(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prstatus.pr_ppid = info.GetParentProcessID(); + prstatus.pr_pgrp = info.GetProcessGroupID(); + prstatus.pr_sid = info.GetProcessSessionID(); + prstatus.pr_utime = copy_timespecs(info.GetUserTime()); + prstatus.pr_stime = copy_timespecs(info.GetSystemTime()); + prstatus.pr_cutime = copy_timespecs(info.GetCumulativeUserTime()); + prstatus.pr_cstime = copy_timespecs(info.GetCumulativeSystemTime()); + return prstatus; +} + // Parse PRPSINFO from NOTE entry ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { memset(this, 0, sizeof(ELFLinuxPrPsInfo)); @@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +ELFLinuxPrPsInfo::Populate(const lldb::ProcessSP &process_sp) { + ELFLinuxPrPsInfo prpsinfo{}; + prpsinfo.pr_pid = process_sp->GetID(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prpsinfo.pr_nice = info.GetPriorityValue().value_or(0); + prpsinfo.pr_zomb = 0; + if (auto zombie_opt = info.IsZombie(); zombie_opt.value_or(false)) { +prpsinfo.pr_zomb = 1; + } + /** + * In the linux kernel this comes from: + * state = READ_ONCE(p->__state); + * i = state ? ffz(~state) + 1 : 0; + * psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i]; + * + * So we replicate that here. From proc_pid_stats(5) + * R = Running + * S = Sleeping on uninterrutible wait + * D = Waiting on uninterruptable disk sleep + * T = Tracing stop + * Z = Zombie + * W = Paging + */ + lldb::StateType process_state = process_sp->GetState(); + switch (process_state) { + case lldb::StateType::eStateSuspended: +prpsinfo.pr_sname = 'S'; +prpsinfo.pr_state = 1; +break; + case lldb::StateType::eStateStopped: +[[fallthrough]]; + case lldb::StateType::eStateStepping: +prpsinfo.pr_sname = 'T'; +prpsinfo.pr_state = 3; +break; + case lldb::StateType::eStateUnloaded: +[[fallthrough]]; + case lldb::StateType::eStateRunning: +prpsinfo.pr_sname = 'R'; +prpsinfo.pr_state = 0; +break; + default: +break; + } + + /** + * pr_flags is left as 0. The values (in linux) are specific + * to the kernel. We recover them from the proc filesystem + * but don't put them in ProcessInfo because it would really + * become very linux specific and the utility here seems pretty + * dubious + */ + + if (info.EffectiveUserIDIsValid()) { +prpsinfo.pr_uid = info.GetUserID(); + } + if (info.EffectiveGroupIDIsValid()) { +prpsinfo.pr_gid = info.GetGroupID(); + } + + if (info.ParentProcessIDIsValid()) { +prpsinfo.pr_ppid = info.GetParentProcessID(); + } + + if (info.ProcessGroupIDIsValid()) { +prpsinfo.pr_pgrp = info.GetProcessGroupID(); + } + + if (info.ProcessSessionIDIsValid()) { +prpsinfo.pr_sid = info.GetProcessSessionID(); + } + constexpr size_t fname_len = std::extent_v; + static_assert(fname_len > 0, "This shou
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,107 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +ELFLinuxPrPsInfo::Populate(const lldb::ProcessSP &process_sp) { + ELFLinuxPrPsInfo prpsinfo{}; + prpsinfo.pr_pid = process_sp->GetID(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prpsinfo.pr_nice = info.GetPriorityValue().value_or(0); + prpsinfo.pr_zomb = 0; + if (auto zombie_opt = info.IsZombie(); zombie_opt.value_or(false)) { +prpsinfo.pr_zomb = 1; + } + /** + * In the linux kernel this comes from: + * state = READ_ONCE(p->__state); + * i = state ? ffz(~state) + 1 : 0; + * psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i]; + * + * So we replicate that here. From proc_pid_stats(5) + * R = Running + * S = Sleeping on uninterrutible wait + * D = Waiting on uninterruptable disk sleep + * T = Tracing stop + * Z = Zombie + * W = Paging + */ + lldb::StateType process_state = process_sp->GetState(); + switch (process_state) { + case lldb::StateType::eStateSuspended: +prpsinfo.pr_sname = 'S'; +prpsinfo.pr_state = 1; +break; + case lldb::StateType::eStateStopped: +[[fallthrough]]; + case lldb::StateType::eStateStepping: +prpsinfo.pr_sname = 'T'; +prpsinfo.pr_state = 3; +break; + case lldb::StateType::eStateUnloaded: +[[fallthrough]]; + case lldb::StateType::eStateRunning: +prpsinfo.pr_sname = 'R'; +prpsinfo.pr_state = 0; +break; + default: +break; + } + + /** + * pr_flags is left as 0. The values (in linux) are specific + * to the kernel. We recover them from the proc filesystem + * but don't put them in ProcessInfo because it would really + * become very linux specific and the utility here seems pretty + * dubious + */ + + if (info.EffectiveUserIDIsValid()) { +prpsinfo.pr_uid = info.GetUserID(); + } + if (info.EffectiveGroupIDIsValid()) { +prpsinfo.pr_gid = info.GetGroupID(); + } + + if (info.ParentProcessIDIsValid()) { +prpsinfo.pr_ppid = info.GetParentProcessID(); + } + + if (info.ProcessGroupIDIsValid()) { +prpsinfo.pr_pgrp = info.GetProcessGroupID(); + } + + if (info.ProcessSessionIDIsValid()) { +prpsinfo.pr_sid = info.GetProcessSessionID(); + } + constexpr size_t fname_len = std::extent_v; + static_assert(fname_len > 0, "This should always be non zero"); + const llvm::StringRef fname = info.GetNameAsStringRef(); + auto fname_begin = fname.begin(); + std::copy_n(fname_begin, std::min(fname_len, fname.size()), + prpsinfo.pr_fname); + prpsinfo.pr_fname[fname_len - 1] = '\0'; + auto args = info.GetArguments(); + auto argentry_iterator = std::begin(args); + char *psargs = prpsinfo.pr_psargs; + char *psargs_end = std::end(prpsinfo.pr_psargs); + while (psargs < psargs_end && argentry_iterator != args.end()) { +llvm::StringRef argentry = argentry_iterator->ref(); +size_t len = +std::min(std::distance(psargs, psargs_end), argentry.size()); +auto arg_iterator = std::begin(argentry); +psargs = std::copy_n(arg_iterator, len, psargs); +if (psargs != psargs_end) { + *(psargs++) = ' '; +} feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,107 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +ELFLinuxPrPsInfo::Populate(const lldb::ProcessSP &process_sp) { + ELFLinuxPrPsInfo prpsinfo{}; + prpsinfo.pr_pid = process_sp->GetID(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prpsinfo.pr_nice = info.GetPriorityValue().value_or(0); + prpsinfo.pr_zomb = 0; + if (auto zombie_opt = info.IsZombie(); zombie_opt.value_or(false)) { +prpsinfo.pr_zomb = 1; + } + /** + * In the linux kernel this comes from: + * state = READ_ONCE(p->__state); + * i = state ? ffz(~state) + 1 : 0; + * psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i]; + * + * So we replicate that here. From proc_pid_stats(5) + * R = Running + * S = Sleeping on uninterrutible wait + * D = Waiting on uninterruptable disk sleep + * T = Tracing stop + * Z = Zombie + * W = Paging + */ + lldb::StateType process_state = process_sp->GetState(); + switch (process_state) { + case lldb::StateType::eStateSuspended: +prpsinfo.pr_sname = 'S'; +prpsinfo.pr_state = 1; +break; + case lldb::StateType::eStateStopped: +[[fallthrough]]; + case lldb::StateType::eStateStepping: +prpsinfo.pr_sname = 'T'; +prpsinfo.pr_state = 3; +break; + case lldb::StateType::eStateUnloaded: +[[fallthrough]]; + case lldb::StateType::eStateRunning: +prpsinfo.pr_sname = 'R'; +prpsinfo.pr_state = 0; +break; + default: +break; + } + + /** + * pr_flags is left as 0. The values (in linux) are specific + * to the kernel. We recover them from the proc filesystem + * but don't put them in ProcessInfo because it would really + * become very linux specific and the utility here seems pretty + * dubious + */ + + if (info.EffectiveUserIDIsValid()) { +prpsinfo.pr_uid = info.GetUserID(); + } + if (info.EffectiveGroupIDIsValid()) { +prpsinfo.pr_gid = info.GetGroupID(); + } + + if (info.ParentProcessIDIsValid()) { +prpsinfo.pr_ppid = info.GetParentProcessID(); + } + + if (info.ProcessGroupIDIsValid()) { +prpsinfo.pr_pgrp = info.GetProcessGroupID(); + } + + if (info.ProcessSessionIDIsValid()) { +prpsinfo.pr_sid = info.GetProcessSessionID(); + } feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,107 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +ELFLinuxPrPsInfo::Populate(const lldb::ProcessSP &process_sp) { + ELFLinuxPrPsInfo prpsinfo{}; + prpsinfo.pr_pid = process_sp->GetID(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prpsinfo.pr_nice = info.GetPriorityValue().value_or(0); + prpsinfo.pr_zomb = 0; + if (auto zombie_opt = info.IsZombie(); zombie_opt.value_or(false)) { +prpsinfo.pr_zomb = 1; + } + /** + * In the linux kernel this comes from: + * state = READ_ONCE(p->__state); + * i = state ? ffz(~state) + 1 : 0; + * psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i]; + * + * So we replicate that here. From proc_pid_stats(5) + * R = Running + * S = Sleeping on uninterrutible wait + * D = Waiting on uninterruptable disk sleep + * T = Tracing stop + * Z = Zombie + * W = Paging + */ + lldb::StateType process_state = process_sp->GetState(); + switch (process_state) { + case lldb::StateType::eStateSuspended: +prpsinfo.pr_sname = 'S'; +prpsinfo.pr_state = 1; +break; + case lldb::StateType::eStateStopped: +[[fallthrough]]; + case lldb::StateType::eStateStepping: +prpsinfo.pr_sname = 'T'; +prpsinfo.pr_state = 3; +break; + case lldb::StateType::eStateUnloaded: +[[fallthrough]]; + case lldb::StateType::eStateRunning: +prpsinfo.pr_sname = 'R'; +prpsinfo.pr_state = 0; +break; + default: +break; + } + + /** + * pr_flags is left as 0. The values (in linux) are specific + * to the kernel. We recover them from the proc filesystem + * but don't put them in ProcessInfo because it would really + * become very linux specific and the utility here seems pretty + * dubious + */ + + if (info.EffectiveUserIDIsValid()) { +prpsinfo.pr_uid = info.GetUserID(); + } + if (info.EffectiveGroupIDIsValid()) { +prpsinfo.pr_gid = info.GetGroupID(); + } + + if (info.ParentProcessIDIsValid()) { +prpsinfo.pr_ppid = info.GetParentProcessID(); + } + + if (info.ProcessGroupIDIsValid()) { +prpsinfo.pr_pgrp = info.GetProcessGroupID(); + } feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,107 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +ELFLinuxPrPsInfo::Populate(const lldb::ProcessSP &process_sp) { + ELFLinuxPrPsInfo prpsinfo{}; + prpsinfo.pr_pid = process_sp->GetID(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prpsinfo.pr_nice = info.GetPriorityValue().value_or(0); + prpsinfo.pr_zomb = 0; + if (auto zombie_opt = info.IsZombie(); zombie_opt.value_or(false)) { +prpsinfo.pr_zomb = 1; + } + /** + * In the linux kernel this comes from: + * state = READ_ONCE(p->__state); + * i = state ? ffz(~state) + 1 : 0; + * psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i]; + * + * So we replicate that here. From proc_pid_stats(5) + * R = Running + * S = Sleeping on uninterrutible wait + * D = Waiting on uninterruptable disk sleep + * T = Tracing stop + * Z = Zombie + * W = Paging + */ + lldb::StateType process_state = process_sp->GetState(); + switch (process_state) { + case lldb::StateType::eStateSuspended: +prpsinfo.pr_sname = 'S'; +prpsinfo.pr_state = 1; +break; + case lldb::StateType::eStateStopped: +[[fallthrough]]; + case lldb::StateType::eStateStepping: +prpsinfo.pr_sname = 'T'; +prpsinfo.pr_state = 3; +break; + case lldb::StateType::eStateUnloaded: +[[fallthrough]]; + case lldb::StateType::eStateRunning: +prpsinfo.pr_sname = 'R'; +prpsinfo.pr_state = 0; +break; + default: +break; + } + + /** + * pr_flags is left as 0. The values (in linux) are specific + * to the kernel. We recover them from the proc filesystem + * but don't put them in ProcessInfo because it would really + * become very linux specific and the utility here seems pretty + * dubious + */ + + if (info.EffectiveUserIDIsValid()) { +prpsinfo.pr_uid = info.GetUserID(); + } + if (info.EffectiveGroupIDIsValid()) { +prpsinfo.pr_gid = info.GetGroupID(); + } + + if (info.ParentProcessIDIsValid()) { +prpsinfo.pr_ppid = info.GetParentProcessID(); + } feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,107 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +ELFLinuxPrPsInfo::Populate(const lldb::ProcessSP &process_sp) { + ELFLinuxPrPsInfo prpsinfo{}; + prpsinfo.pr_pid = process_sp->GetID(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prpsinfo.pr_nice = info.GetPriorityValue().value_or(0); + prpsinfo.pr_zomb = 0; + if (auto zombie_opt = info.IsZombie(); zombie_opt.value_or(false)) { +prpsinfo.pr_zomb = 1; + } + /** + * In the linux kernel this comes from: + * state = READ_ONCE(p->__state); + * i = state ? ffz(~state) + 1 : 0; + * psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i]; + * + * So we replicate that here. From proc_pid_stats(5) + * R = Running + * S = Sleeping on uninterrutible wait + * D = Waiting on uninterruptable disk sleep + * T = Tracing stop + * Z = Zombie + * W = Paging + */ + lldb::StateType process_state = process_sp->GetState(); + switch (process_state) { + case lldb::StateType::eStateSuspended: +prpsinfo.pr_sname = 'S'; +prpsinfo.pr_state = 1; +break; + case lldb::StateType::eStateStopped: +[[fallthrough]]; + case lldb::StateType::eStateStepping: +prpsinfo.pr_sname = 'T'; +prpsinfo.pr_state = 3; +break; + case lldb::StateType::eStateUnloaded: +[[fallthrough]]; + case lldb::StateType::eStateRunning: +prpsinfo.pr_sname = 'R'; +prpsinfo.pr_state = 0; +break; + default: +break; + } + + /** + * pr_flags is left as 0. The values (in linux) are specific + * to the kernel. We recover them from the proc filesystem + * but don't put them in ProcessInfo because it would really + * become very linux specific and the utility here seems pretty + * dubious + */ + + if (info.EffectiveUserIDIsValid()) { +prpsinfo.pr_uid = info.GetUserID(); + } + if (info.EffectiveGroupIDIsValid()) { +prpsinfo.pr_gid = info.GetGroupID(); + } feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
@@ -394,6 +420,107 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +ELFLinuxPrPsInfo::Populate(const lldb::ProcessSP &process_sp) { + ELFLinuxPrPsInfo prpsinfo{}; + prpsinfo.pr_pid = process_sp->GetID(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prpsinfo.pr_nice = info.GetPriorityValue().value_or(0); + prpsinfo.pr_zomb = 0; + if (auto zombie_opt = info.IsZombie(); zombie_opt.value_or(false)) { +prpsinfo.pr_zomb = 1; + } + /** + * In the linux kernel this comes from: + * state = READ_ONCE(p->__state); + * i = state ? ffz(~state) + 1 : 0; + * psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i]; + * + * So we replicate that here. From proc_pid_stats(5) + * R = Running + * S = Sleeping on uninterrutible wait + * D = Waiting on uninterruptable disk sleep + * T = Tracing stop + * Z = Zombie + * W = Paging + */ + lldb::StateType process_state = process_sp->GetState(); + switch (process_state) { + case lldb::StateType::eStateSuspended: +prpsinfo.pr_sname = 'S'; +prpsinfo.pr_state = 1; +break; + case lldb::StateType::eStateStopped: +[[fallthrough]]; + case lldb::StateType::eStateStepping: +prpsinfo.pr_sname = 'T'; +prpsinfo.pr_state = 3; +break; + case lldb::StateType::eStateUnloaded: +[[fallthrough]]; + case lldb::StateType::eStateRunning: +prpsinfo.pr_sname = 'R'; +prpsinfo.pr_state = 0; +break; + default: +break; + } + + /** + * pr_flags is left as 0. The values (in linux) are specific + * to the kernel. We recover them from the proc filesystem + * but don't put them in ProcessInfo because it would really + * become very linux specific and the utility here seems pretty + * dubious + */ + + if (info.EffectiveUserIDIsValid()) { +prpsinfo.pr_uid = info.GetUserID(); + } feg208 wrote: done https://github.com/llvm/llvm-project/pull/104109 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][Data Formatters] Calculate average and total time for summary providers within lldb (PR #102708)
https://github.com/mbucko approved this pull request. Just a couple of small things https://github.com/llvm/llvm-project/pull/102708 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][Data Formatters] Calculate average and total time for summary providers within lldb (PR #102708)
https://github.com/mbucko edited https://github.com/llvm/llvm-project/pull/102708 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][Data Formatters] Calculate average and total time for summary providers within lldb (PR #102708)
@@ -174,6 +177,83 @@ struct StatisticsOptions { std::optional m_include_transcript; }; +/// A class that represents statistics about a TypeSummaryProviders invocations +class SummaryStatistics { +public: + explicit SummaryStatistics(std::string name, std::string impl_type) + : m_total_time(), m_impl_type(impl_type), m_name(name), +m_count(0) {} + + std::string GetName() const { return m_name; }; + double GetTotalTime() const { return m_total_time.get().count(); } + + uint64_t GetSummaryCount() const { +return m_count.load(std::memory_order_relaxed); + } + + StatsDuration &GetDurationReference() { return m_total_time; }; + + std::string GetSummaryKindName() const { return m_impl_type; } + + llvm::json::Value ToJSON() const; + + + /// Basic RAII class to increment the summary count when the call is complete. + /// In the future this can be extended to collect information about the + /// elapsed time for a single request. + class SummaryInvocation{ + public: +SummaryInvocation(std::shared_ptr summary_stats) +: m_stats(summary_stats), + m_elapsed_time(summary_stats->GetDurationReference()) {} +~SummaryInvocation() { m_stats->OnInvoked(); } + +/// Delete the copy constructor and assignment operator to prevent +/// accidental double counting. +/// @{ +SummaryInvocation(const SummaryInvocation &) = delete; +SummaryInvocation &operator=(const SummaryInvocation &) = delete; +/// @} + + private: +std::shared_ptr m_stats; +ElapsedTime m_elapsed_time; + }; + +private: + void OnInvoked() { +m_count.fetch_add(1, std::memory_order_relaxed); + } + lldb_private::StatsDuration m_total_time; + std::string m_impl_type; + std::string m_name; mbucko wrote: this one too https://github.com/llvm/llvm-project/pull/102708 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][Data Formatters] Calculate average and total time for summary providers within lldb (PR #102708)
@@ -174,6 +177,83 @@ struct StatisticsOptions { std::optional m_include_transcript; }; +/// A class that represents statistics about a TypeSummaryProviders invocations +class SummaryStatistics { +public: + explicit SummaryStatistics(std::string name, std::string impl_type) + : m_total_time(), m_impl_type(impl_type), m_name(name), +m_count(0) {} + + std::string GetName() const { return m_name; }; + double GetTotalTime() const { return m_total_time.get().count(); } + + uint64_t GetSummaryCount() const { +return m_count.load(std::memory_order_relaxed); + } + + StatsDuration &GetDurationReference() { return m_total_time; }; + + std::string GetSummaryKindName() const { return m_impl_type; } + + llvm::json::Value ToJSON() const; + + + /// Basic RAII class to increment the summary count when the call is complete. + /// In the future this can be extended to collect information about the + /// elapsed time for a single request. + class SummaryInvocation{ + public: +SummaryInvocation(std::shared_ptr summary_stats) +: m_stats(summary_stats), + m_elapsed_time(summary_stats->GetDurationReference()) {} +~SummaryInvocation() { m_stats->OnInvoked(); } + +/// Delete the copy constructor and assignment operator to prevent +/// accidental double counting. +/// @{ +SummaryInvocation(const SummaryInvocation &) = delete; +SummaryInvocation &operator=(const SummaryInvocation &) = delete; +/// @} + + private: +std::shared_ptr m_stats; +ElapsedTime m_elapsed_time; + }; + +private: + void OnInvoked() { +m_count.fetch_add(1, std::memory_order_relaxed); + } + lldb_private::StatsDuration m_total_time; + std::string m_impl_type; mbucko wrote: this can be const https://github.com/llvm/llvm-project/pull/102708 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][Data Formatters] Calculate average and total time for summary providers within lldb (PR #102708)
@@ -174,6 +177,84 @@ struct StatisticsOptions { std::optional m_include_transcript; }; +/// A class that represents statistics about a TypeSummaryProviders invocations +class SummaryStatistics { +public: + explicit SummaryStatistics(lldb_private::ConstString name, + lldb_private::ConstString impl_type) + : m_total_time(), m_impl_type(impl_type), m_name(name), +m_summary_count(0) {} + + lldb_private::ConstString GetName() const { return m_name; }; + double GetTotalTime() const { return m_total_time.get().count(); } + + uint64_t GetSummaryCount() const { +return m_summary_count.load(std::memory_order_relaxed); + } + + StatsDuration &GetDurationReference() { return m_total_time; } + + ConstString GetImplType() const { return m_impl_type; } + + llvm::json::Value ToJSON() const; + + // Basic RAII class to increment the summary count when the call is complete. + // In the future this can be extended to collect information about the + // elapsed time for a single request. + class SummaryInvocation { + public: +SummaryInvocation(SummaryStatistics &summary) +: m_summary(summary), m_elapsed_time(summary.GetDurationReference()) {} +~SummaryInvocation() { m_summary.OnInvoked(); } + +// Delete the copy constructor and assignment operator to prevent +// accidental double counting. +SummaryInvocation(const SummaryInvocation &) = delete; +SummaryInvocation &operator=(const SummaryInvocation &) = delete; + + private: +SummaryStatistics &m_summary; +ElapsedTime m_elapsed_time; + }; + + SummaryInvocation GetSummaryInvocation() { return SummaryInvocation(*this); } + +private: + /// Called when Summary Invocation is destructed. + void OnInvoked() noexcept { +m_summary_count.fetch_add(1, std::memory_order_relaxed); + } + + lldb_private::StatsDuration m_total_time; + lldb_private::ConstString m_impl_type; + lldb_private::ConstString m_name; + std::atomic m_summary_count; +}; + +/// A class that wraps a std::map of SummaryStatistics objects behind a mutex. +class SummaryStatisticsCache { +public: + /// Get the SummaryStatistics object for a given provider name, or insert + /// if statistics for that provider is not in the map. + lldb_private::SummaryStatistics & + GetSummaryStatisticsForProviderName(lldb_private::TypeSummaryImpl &provider) { +std::lock_guard guard(m_map_mutex); +m_summary_stats_map.try_emplace(provider.GetName(), provider.GetName(), +provider.GetImplType()); + +SummaryStatistics &summary_stats = +m_summary_stats_map.at(provider.GetName()); +return summary_stats; + } + + llvm::json::Value ToJSON(); + +private: + std::map + m_summary_stats_map; Jlalond wrote: Ended up going with Shared Pointers as it simplifies lifetime management and frees the object's being shared from the underlying storage impl. https://github.com/llvm/llvm-project/pull/102708 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][Data Formatters] Calculate average and total time for summary providers within lldb (PR #102708)
https://github.com/Jlalond updated https://github.com/llvm/llvm-project/pull/102708 >From c0a7286b0107d3161b18de8f05d4d016150e96a5 Mon Sep 17 00:00:00 2001 From: Jacob Lalonde Date: Thu, 8 Aug 2024 08:58:52 -0700 Subject: [PATCH 01/11] Initial attempt at new classes Summary statistics in SummaryStatistics.h/cpp. --- lldb/include/lldb/Target/SummaryStatistics.h | 37 lldb/include/lldb/Target/Target.h| 5 +++ lldb/source/Core/ValueObject.cpp | 5 +++ lldb/source/Target/CMakeLists.txt| 1 + lldb/source/Target/SummaryStatistics.cpp | 26 ++ lldb/source/Target/Target.cpp| 9 + 6 files changed, 83 insertions(+) create mode 100644 lldb/include/lldb/Target/SummaryStatistics.h create mode 100644 lldb/source/Target/SummaryStatistics.cpp diff --git a/lldb/include/lldb/Target/SummaryStatistics.h b/lldb/include/lldb/Target/SummaryStatistics.h new file mode 100644 index 00..0198249ba0b170 --- /dev/null +++ b/lldb/include/lldb/Target/SummaryStatistics.h @@ -0,0 +1,37 @@ +//===-- SummaryStatistics.h -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLDB_TARGET_SUMMARYSTATISTICS_H +#define LLDB_TARGET_SUMMARYSTATISTICS_H + + +#include "lldb/Target/Statistics.h" +#include "llvm/ADT/StringRef.h" + +namespace lldb_private { + +class SummaryStatistics { +public: + SummaryStatistics(lldb_private::ConstString name) : +m_total_time(), m_name(name), m_summary_count(0) {} + + lldb_private::StatsDuration &GetDurationReference(); + + lldb_private::ConstString GetName() const; + + uint64_t GetSummaryCount() const; + +private: + lldb_private::StatsDuration m_total_time; + lldb_private::ConstString m_name; + uint64_t m_summary_count; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_SUMMARYSTATISTICS_H diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 119dff4d498199..ee6a009b0af95d 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -30,6 +30,7 @@ #include "lldb/Target/PathMappingList.h" #include "lldb/Target/SectionLoadHistory.h" #include "lldb/Target/Statistics.h" +#include "lldb/Target/SummaryStatistics.h" #include "lldb/Target/ThreadSpec.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Broadcaster.h" @@ -258,6 +259,7 @@ class TargetProperties : public Properties { bool GetDebugUtilityExpression() const; + private: std::optional GetExperimentalPropertyValue(size_t prop_idx, @@ -1221,6 +1223,8 @@ class Target : public std::enable_shared_from_this, void ClearAllLoadedSections(); + lldb_private::StatsDuration& GetSummaryProviderDuration(lldb_private::ConstString summary_provider_name); + /// Set the \a Trace object containing processor trace information of this /// target. /// @@ -1554,6 +1558,7 @@ class Target : public std::enable_shared_from_this, std::string m_label; ModuleList m_images; ///< The list of images for this process (shared /// libraries and anything dynamically loaded). + std::map m_summary_stats_map; SectionLoadHistory m_section_load_history; BreakpointList m_breakpoint_list; BreakpointList m_internal_breakpoint_list; diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 8f72efc2299b4f..bed4ab8d69cbda 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -615,6 +615,11 @@ bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr, m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on // the synthetic children being // up-to-date (e.g. ${svar%#}) +StatsDuration &summary_duration = GetExecutionContextRef() +.GetProcessSP() +->GetTarget() + .GetSummaryProviderDuration(GetTypeName()); +ElapsedTime elapsed(summary_duration); summary_ptr->FormatObject(this, destination, actual_options); } m_flags.m_is_getting_summary = false; diff --git a/lldb/source/Target/CMakeLists.txt b/lldb/source/Target/CMakeLists.txt index a42c44b761dc56..e51da37cd84db3 100644 --- a/lldb/source/Target/CMakeLists.txt +++ b/lldb/source/Target/CMakeLists.txt @@ -46,6 +46,7 @@ add_lldb_library(lldbTarget Statistics.cpp StopInfo.cpp StructuredDataPlugin.cpp + SummaryStatistics.cpp SystemRuntime.cpp Target.cpp TargetList.cpp diff --git a/lldb/source/Target/SummaryStatistics.cpp b/lldb/so
[Lldb-commits] [lldb] [LLDB][Data Formatters] Calculate average and total time for summary providers within lldb (PR #102708)
https://github.com/Jlalond updated https://github.com/llvm/llvm-project/pull/102708 >From c0a7286b0107d3161b18de8f05d4d016150e96a5 Mon Sep 17 00:00:00 2001 From: Jacob Lalonde Date: Thu, 8 Aug 2024 08:58:52 -0700 Subject: [PATCH 01/12] Initial attempt at new classes Summary statistics in SummaryStatistics.h/cpp. --- lldb/include/lldb/Target/SummaryStatistics.h | 37 lldb/include/lldb/Target/Target.h| 5 +++ lldb/source/Core/ValueObject.cpp | 5 +++ lldb/source/Target/CMakeLists.txt| 1 + lldb/source/Target/SummaryStatistics.cpp | 26 ++ lldb/source/Target/Target.cpp| 9 + 6 files changed, 83 insertions(+) create mode 100644 lldb/include/lldb/Target/SummaryStatistics.h create mode 100644 lldb/source/Target/SummaryStatistics.cpp diff --git a/lldb/include/lldb/Target/SummaryStatistics.h b/lldb/include/lldb/Target/SummaryStatistics.h new file mode 100644 index 00..0198249ba0b170 --- /dev/null +++ b/lldb/include/lldb/Target/SummaryStatistics.h @@ -0,0 +1,37 @@ +//===-- SummaryStatistics.h -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLDB_TARGET_SUMMARYSTATISTICS_H +#define LLDB_TARGET_SUMMARYSTATISTICS_H + + +#include "lldb/Target/Statistics.h" +#include "llvm/ADT/StringRef.h" + +namespace lldb_private { + +class SummaryStatistics { +public: + SummaryStatistics(lldb_private::ConstString name) : +m_total_time(), m_name(name), m_summary_count(0) {} + + lldb_private::StatsDuration &GetDurationReference(); + + lldb_private::ConstString GetName() const; + + uint64_t GetSummaryCount() const; + +private: + lldb_private::StatsDuration m_total_time; + lldb_private::ConstString m_name; + uint64_t m_summary_count; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_SUMMARYSTATISTICS_H diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 119dff4d498199..ee6a009b0af95d 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -30,6 +30,7 @@ #include "lldb/Target/PathMappingList.h" #include "lldb/Target/SectionLoadHistory.h" #include "lldb/Target/Statistics.h" +#include "lldb/Target/SummaryStatistics.h" #include "lldb/Target/ThreadSpec.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Broadcaster.h" @@ -258,6 +259,7 @@ class TargetProperties : public Properties { bool GetDebugUtilityExpression() const; + private: std::optional GetExperimentalPropertyValue(size_t prop_idx, @@ -1221,6 +1223,8 @@ class Target : public std::enable_shared_from_this, void ClearAllLoadedSections(); + lldb_private::StatsDuration& GetSummaryProviderDuration(lldb_private::ConstString summary_provider_name); + /// Set the \a Trace object containing processor trace information of this /// target. /// @@ -1554,6 +1558,7 @@ class Target : public std::enable_shared_from_this, std::string m_label; ModuleList m_images; ///< The list of images for this process (shared /// libraries and anything dynamically loaded). + std::map m_summary_stats_map; SectionLoadHistory m_section_load_history; BreakpointList m_breakpoint_list; BreakpointList m_internal_breakpoint_list; diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 8f72efc2299b4f..bed4ab8d69cbda 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -615,6 +615,11 @@ bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr, m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on // the synthetic children being // up-to-date (e.g. ${svar%#}) +StatsDuration &summary_duration = GetExecutionContextRef() +.GetProcessSP() +->GetTarget() + .GetSummaryProviderDuration(GetTypeName()); +ElapsedTime elapsed(summary_duration); summary_ptr->FormatObject(this, destination, actual_options); } m_flags.m_is_getting_summary = false; diff --git a/lldb/source/Target/CMakeLists.txt b/lldb/source/Target/CMakeLists.txt index a42c44b761dc56..e51da37cd84db3 100644 --- a/lldb/source/Target/CMakeLists.txt +++ b/lldb/source/Target/CMakeLists.txt @@ -46,6 +46,7 @@ add_lldb_library(lldbTarget Statistics.cpp StopInfo.cpp StructuredDataPlugin.cpp + SummaryStatistics.cpp SystemRuntime.cpp Target.cpp TargetList.cpp diff --git a/lldb/source/Target/SummaryStatistics.cpp b/lldb/so
[Lldb-commits] [lldb] Remove redundant symbol lookups in IRExecutionUnit::FindInSymbols (PR #102835)
Michael137 wrote: > > Could you please explain to me why we use different rules in symbol > > lookups? Namely: > > > > * > > [ClangExpressionDeclMap::GetSymbolAddress](https://github.com/llvm/llvm-project/pull/102835/files#diff-5d2da8306a4f4991885836925979f188658789adc8041c37811c243f2cdca24c) > > doesn't search in the ModuleList if a module is given even if the search > > provides no results. > > * > > [SymbolContext::FindBestGlobalDataSymbol](https://github.com/llvm/llvm-project/pull/102835/files#diff-da1a374f5098c39acfebae4b87a261f143a842e613082c2296de7ee28df12a33) > > searches in the module first, then checks the results; if exactly one > > external or internal symbol is found returns it. Otherwise, if more than 1 > > is found it produces an error. But if nothing is found in the module it > > searches in the module list and repeats the checks. > > So theoretically there could be multiple results in the module list that > > would trigger an error, but we don't check for them. > > Also, it seems an external symbol takes precedence over an internal > > symbol. If we found an internal symbol in the module, we still could find > > an external symbol in the module list, but we don't search for it. Is this > > correct? Does an internal symbol of the module actually take precedence > > over an external symbol from the module list? > > * > > [IRExecutionUnit::FindInSymbols](https://github.com/llvm/llvm-project/pull/102835/files#diff-717a850c4315286c025e2739ebe9dacbf27e626b7679c72479b05c996d721112) > > looks similar to the previous one, but actually very different. It returns > > early if and only if the found symbol is external(see > > LoadAddressResolver::Resolve), otherwise it does a full search in the > > module list. And only then if an external symbol isn't found - returns the > > first internal symbol(if any). > > > > It's hard to generalize the optimization since all the callers post-process > > the results differently. > > Yes, each use case is specialized. Since this is the case, maybe the callback > mechanism should be used and we give back the results starting with the > `hint` module first, and then proceed to the entire module list. If return > value of the callback will say "keep going" or "stop". This allows clients to > pick and choose what they do. Unless we can break down the changes into > something that fits all of these. > > Most of these lookups are trying to figure out the right thing to do given a > symbol context (module, compile unit, function, inlined function etc), and it > falls back onto the module list from the target (one for each of the shared > libraries loaded into your process) to find results. > > If you think about it, starting with the current module makes sense because > that is where the expression is being evaluated (in some stack frame whose PC > is in a module). So if we find a symbol in the current module, we can go with > it. If we can't find a symbol in the current module, then we want to go with > the right one, but there shouldn't be duplicate symbols if those symbols are > exported. If a user types `printf(...)`, and lets say we don't find it in our > current module, then we should look for an external symbol that matches, and > if there is more than one external symbol for `printf`, that would be an > error because we wouldn't know which one to call. But if we have a local > `printf` function in the current module, we might want that one to take > precedence. Of course if `printf` is a method in a class, and our expression > is being run from another method in the class, then we should call the > `::printf`. But if things fall back to finding symbols, then we need > to have some way to resolve ambiguous symbols. So this is the system we came > up with. > > If you have an expression like `my_global`, you really want to look at the > compile unit your expression is being run from, and if that compile unit has > a global or static variable named `my_global`, we should pick that one. If > there isn't a match in the current compile unit, then we should search in the > current module. If it has one, that is most likely the global the user wants. > If there isn't one in the current module, then we must search around in all > modules and if we find more than one, lets say we find a global variable from > `liba.so` where the variable is exported, and another from `libb.so` that is > a static variable, then we should pick the global variable to try and match > the visibility that a program would have to a global variable from another > shared library. The public one wins. But it we have two libraries that both > have a exported `my_global` variables, we don't know which to pick, so we > return an error. > > `IRExecutionUnit::FindInSymbols` might be the function that is called to > search for symbols in the first place and > `ClangExpressionDeclMap::GetSymbolAddress` might be used to get the address > o
[Lldb-commits] [lldb] [lldb] Realpath symlinks for breakpoints (PR #102223)
https://github.com/royitaqi edited https://github.com/llvm/llvm-project/pull/102223 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][Data Formatters] Calculate average and total time for summary providers within lldb (PR #102708)
@@ -174,6 +177,86 @@ struct StatisticsOptions { std::optional m_include_transcript; }; +/// A class that represents statistics about a TypeSummaryProviders invocations +class SummaryStatistics { +public: + explicit SummaryStatistics(std::string name, std::string impl_type) + : m_total_time(), m_impl_type(impl_type), m_name(name), Michael137 wrote: ```suggestion : m_total_time(), m_impl_type(std::move(impl_type)), m_name(std::move(name)), ``` https://github.com/llvm/llvm-project/pull/102708 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][Data Formatters] Calculate average and total time for summary providers within lldb (PR #102708)
@@ -174,6 +177,86 @@ struct StatisticsOptions { std::optional m_include_transcript; }; +/// A class that represents statistics about a TypeSummaryProviders invocations +class SummaryStatistics { +public: + explicit SummaryStatistics(std::string name, std::string impl_type) + : m_total_time(), m_impl_type(impl_type), m_name(name), +m_summary_count(0) {} + + std::string GetName() const { return m_name; }; + double GetTotalTime() const { return m_total_time.get().count(); } + + uint64_t GetSummaryCount() const { +return m_summary_count.load(std::memory_order_relaxed); + } + + StatsDuration &GetDurationReference() { return m_total_time; }; + + std::string GetSummaryKindName() const { return m_impl_type; } + + llvm::json::Value ToJSON() const; + + void IncrementSummaryCount() { +m_summary_count.fetch_add(1, std::memory_order_relaxed); + } + +private: + lldb_private::StatsDuration m_total_time; + std::string m_impl_type; + std::string m_name; + std::atomic m_summary_count; +}; + +/// A class that wraps a std::map of SummaryStatistics objects behind a mutex. +class SummaryStatisticsCache { +public: + /// Basic RAII class to increment the summary count when the call is complete. + /// In the future this can be extended to collect information about the + /// elapsed time for a single request. + class SummaryInvocation { + public: +SummaryInvocation(SummaryStatistics &summary, SummaryStatisticsCache &cache) +: m_provider_key(summary.GetName()), m_cache(cache), + m_elapsed_time(summary.GetDurationReference()) {} +~SummaryInvocation() { m_cache.OnInvoked(m_provider_key); } + +/// Delete the copy constructor and assignment operator to prevent +/// accidental double counting. +/// @{ +SummaryInvocation(const SummaryInvocation &) = delete; +SummaryInvocation &operator=(const SummaryInvocation &) = delete; +/// @} + + private: +std::string m_provider_key; +SummaryStatisticsCache &m_cache; +ElapsedTime m_elapsed_time; + }; + + /// Get the SummaryStatistics object for a given provider name, or insert + /// if statistics for that provider is not in the map. + SummaryStatisticsCache::SummaryInvocation + GetSummaryStatisticsForProviderName(lldb_private::TypeSummaryImpl &provider) { +std::lock_guard guard(m_map_mutex); +auto pair = m_summary_stats_map.try_emplace( +provider.GetName(), provider.GetName(), provider.GetSummaryKindName()); + +return SummaryInvocation(pair.first->second, *this); + } + + llvm::json::Value ToJSON(); + +private: + /// Called when Summary Invocation is destructed. + void OnInvoked(std::string provider_name) noexcept { Michael137 wrote: ```suggestion void OnInvoked(llvm::StringRef provider_name) noexcept { ``` Just to avoid copying the string around? https://github.com/llvm/llvm-project/pull/102708 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][Data Formatters] Calculate average and total time for summary providers within lldb (PR #102708)
@@ -174,6 +176,82 @@ struct StatisticsOptions { std::optional m_include_transcript; }; +/// A class that represents statistics about a TypeSummaryProviders invocations +class SummaryStatistics { +public: + explicit SummaryStatistics(std::string name, std::string impl_type) + : m_total_time(), m_impl_type(impl_type), m_name(name), m_count(0) {} + + std::string GetName() const { return m_name; }; + double GetTotalTime() const { return m_total_time.get().count(); } + + uint64_t GetSummaryCount() const { +return m_count.load(std::memory_order_relaxed); + } + + StatsDuration &GetDurationReference() { return m_total_time; }; + + std::string GetSummaryKindName() const { return m_impl_type; } + + llvm::json::Value ToJSON() const; + + /// Basic RAII class to increment the summary count when the call is complete. + class SummaryInvocation { + public: +SummaryInvocation(std::shared_ptr summary_stats) +: m_stats(summary_stats), + m_elapsed_time(summary_stats->GetDurationReference()) {} +~SummaryInvocation() { m_stats->OnInvoked(); } + +/// Delete the copy constructor and assignment operator to prevent +/// accidental double counting. +/// @{ +SummaryInvocation(const SummaryInvocation &) = delete; +SummaryInvocation &operator=(const SummaryInvocation &) = delete; +/// @} + + private: +std::shared_ptr m_stats; +ElapsedTime m_elapsed_time; + }; + +private: + void OnInvoked() noexcept { m_count.fetch_add(1, std::memory_order_relaxed); } + lldb_private::StatsDuration m_total_time; + const std::string m_impl_type; + const std::string m_name; + std::atomic m_count; +}; + +typedef std::shared_ptr SummaryStatisticsSP; + +/// A class that wraps a std::map of SummaryStatistics objects behind a mutex. +class SummaryStatisticsCache { +public: + /// Get the SummaryStatistics object for a given provider name, or insert + /// if statistics for that provider is not in the map. + SummaryStatisticsSP + GetSummaryStatisticsForProviderName(lldb_private::TypeSummaryImpl &provider) { Michael137 wrote: Personally I'm still not very happy with this setup, but if others are fine with how this is structured, I won't block this PR. I think handing out references/pointers to data in the presence of threads shouldn't be taken lightly. All we want to do here is: 1. Collect stats 2. Update stats in the thread-safe map If we can just have a `SummaryStatisticsCache::Update(SummaryInvocation)` API. The summary invocation just records `ElapsedTime`. Then in the `Update` API we do: 1. If no `SummaryStats` entry exists. Create one 2. Otherwise, add `ElapsedTime` to the running total. Increment the m_count counter. That'd make (in my opinion) all of this much easier to reason about. And would also avoid copying/moving all these strings around. Wdyt? @bulbazord @clayborg @Jlalond https://github.com/llvm/llvm-project/pull/102708 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 47721d4 - [lldb] Realpath symlinks for breakpoints (#102223)
Author: royitaqi Date: 2024-08-15T11:26:24-07:00 New Revision: 47721d46187f89c12a13d07b5857496301cf5d6e URL: https://github.com/llvm/llvm-project/commit/47721d46187f89c12a13d07b5857496301cf5d6e DIFF: https://github.com/llvm/llvm-project/commit/47721d46187f89c12a13d07b5857496301cf5d6e.diff LOG: [lldb] Realpath symlinks for breakpoints (#102223) Improve the chance of resolving file/line breakpoints by realpath'ing the support files before doing a second match attempt, with some conditions applied. A working [hello-world example](https://github.com/royitaqi/lldb_demos/blob/main/realpath/README.md). See [patch](https://github.com/llvm/llvm-project/pull/102223) for more info about problem/motivation, details of the feature, new settings, telemetries and tests. Added: lldb/include/lldb/Utility/RealpathPrefixes.h lldb/source/Utility/RealpathPrefixes.cpp lldb/test/API/functionalities/breakpoint/breakpoint_with_realpath_and_source_map/Makefile lldb/test/API/functionalities/breakpoint/breakpoint_with_realpath_and_source_map/TestBreakpoint.py lldb/test/API/functionalities/breakpoint/breakpoint_with_realpath_and_source_map/main.c lldb/test/API/functionalities/breakpoint/breakpoint_with_realpath_and_source_map/real/bar.h lldb/test/API/functionalities/breakpoint/breakpoint_with_realpath_and_source_map/real/foo.h lldb/test/API/functionalities/breakpoint/breakpoint_with_realpath_and_source_map/real/qux.h lldb/test/API/functionalities/breakpoint/breakpoint_with_realpath_and_source_map/symlink1/foo.h lldb/test/API/functionalities/breakpoint/breakpoint_with_realpath_and_source_map/symlink2 lldb/test/API/functionalities/breakpoint/breakpoint_with_realpath_and_source_map/to-be-mapped/README.md lldb/unittests/Utility/FileSpecListTest.cpp lldb/unittests/Utility/MockSymlinkFileSystem.h lldb/unittests/Utility/RealpathPrefixesTest.cpp Modified: lldb/include/lldb/Symbol/CompileUnit.h lldb/include/lldb/Target/Statistics.h lldb/include/lldb/Target/Target.h lldb/include/lldb/Utility/FileSpecList.h lldb/include/lldb/lldb-forward.h lldb/source/Breakpoint/BreakpointResolverFileLine.cpp lldb/source/Symbol/CompileUnit.cpp lldb/source/Target/Statistics.cpp lldb/source/Target/Target.cpp lldb/source/Target/TargetProperties.td lldb/source/Utility/CMakeLists.txt lldb/source/Utility/FileSpecList.cpp lldb/unittests/Core/CMakeLists.txt lldb/unittests/Utility/CMakeLists.txt Removed: lldb/unittests/Core/FileSpecListTest.cpp diff --git a/lldb/include/lldb/Symbol/CompileUnit.h b/lldb/include/lldb/Symbol/CompileUnit.h index c20a37e3283075..c5bb080d211849 100644 --- a/lldb/include/lldb/Symbol/CompileUnit.h +++ b/lldb/include/lldb/Symbol/CompileUnit.h @@ -19,11 +19,13 @@ #include "lldb/Utility/Stream.h" #include "lldb/Utility/UserID.h" #include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" namespace lldb_private { + /// \class CompileUnit CompileUnit.h "lldb/Symbol/CompileUnit.h" /// A class that describes a compilation unit. /// @@ -389,10 +391,15 @@ class CompileUnit : public std::enable_shared_from_this, /// A SymbolContext list class that will get any matching /// entries appended to. /// + /// \param[in] realpath_prefixes + /// Paths that start with one of the prefixes in this list will be + /// realpath'ed to resolve any symlinks. + /// /// \see enum SymbolContext::Scope void ResolveSymbolContext(const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, -SymbolContextList &sc_list); +SymbolContextList &sc_list, +RealpathPrefixes *realpath_prefixes = nullptr); /// Get whether compiler optimizations were enabled for this compile unit /// diff --git a/lldb/include/lldb/Target/Statistics.h b/lldb/include/lldb/Target/Statistics.h index 35bd7f8a66e055..5193d099a5494d 100644 --- a/lldb/include/lldb/Target/Statistics.h +++ b/lldb/include/lldb/Target/Statistics.h @@ -10,6 +10,7 @@ #define LLDB_TARGET_STATISTICS_H #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/RealpathPrefixes.h" #include "lldb/Utility/Stream.h" #include "lldb/lldb-forward.h" #include "llvm/ADT/StringMap.h" @@ -184,6 +185,8 @@ class TargetStats { void SetFirstPrivateStopTime(); void SetFirstPublicStopTime(); void IncreaseSourceMapDeduceCount(); + void IncreaseSourceRealpathAttemptCount(uint32_t count); + void IncreaseSourceRealpathCompatibleCount(uint32_t count); StatsDuration &GetCreateTime() { return m_create_time; } StatsSuccessFail &GetExpressionStats() { return m_expr_eval; } @@ -198,6 +201,8 @@ class TargetStats { StatsSuccessFail m_frame_var{"frameVa
[Lldb-commits] [lldb] [lldb] Realpath symlinks for breakpoints (PR #102223)
https://github.com/royitaqi closed https://github.com/llvm/llvm-project/pull/102223 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][Data Formatters] Calculate average and total time for summary providers within lldb (PR #102708)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/102708 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus (PR #104109)
https://github.com/feg208 updated https://github.com/llvm/llvm-project/pull/104109 >From 8f2f84294ea3875c88ce36a4980fd3a3afce01de Mon Sep 17 00:00:00 2001 From: Fred Grim Date: Tue, 18 Jun 2024 10:38:09 -0700 Subject: [PATCH 1/6] [lldb] Add Populate Methods for ELFLinuxPrPsInfo and ELFLinuxPrStatus To create elf core files there are multiple notes in the core file that contain these structs as the note. These populate methods take a Process and produce fully specified structures that can be used to fill these note sections. The pr also adds tests to ensure these structs are correctly populated. --- .../Process/elf-core/ThreadElfCore.cpp| 134 +++ .../Plugins/Process/elf-core/ThreadElfCore.h | 7 + lldb/unittests/Process/CMakeLists.txt | 1 + .../unittests/Process/elf-core/CMakeLists.txt | 15 ++ .../Process/elf-core/ThreadElfCoreTest.cpp| 162 ++ 5 files changed, 319 insertions(+) create mode 100644 lldb/unittests/Process/elf-core/CMakeLists.txt create mode 100644 lldb/unittests/Process/elf-core/ThreadElfCoreTest.cpp diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 2a83163884e168..fdb4a5837cd462 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -318,6 +318,32 @@ Status ELFLinuxPrStatus::Parse(const DataExtractor &data, return error; } +static struct compat_timeval +copy_timespecs(const ProcessInstanceInfo::timespec &oth) { + using sec_t = decltype(compat_timeval::tv_sec); + using usec_t = decltype(compat_timeval::tv_usec); + return {static_cast(oth.tv_sec), static_cast(oth.tv_usec)}; +} + +std::optional +ELFLinuxPrStatus::Populate(const lldb::ThreadSP &thread_sp) { + ELFLinuxPrStatus prstatus{}; + prstatus.pr_pid = thread_sp->GetID(); + lldb::ProcessSP process_sp = thread_sp->GetProcess(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prstatus.pr_ppid = info.GetParentProcessID(); + prstatus.pr_pgrp = info.GetProcessGroupID(); + prstatus.pr_sid = info.GetProcessSessionID(); + prstatus.pr_utime = copy_timespecs(info.GetUserTime()); + prstatus.pr_stime = copy_timespecs(info.GetSystemTime()); + prstatus.pr_cutime = copy_timespecs(info.GetCumulativeUserTime()); + prstatus.pr_cstime = copy_timespecs(info.GetCumulativeSystemTime()); + return prstatus; +} + // Parse PRPSINFO from NOTE entry ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() { memset(this, 0, sizeof(ELFLinuxPrPsInfo)); @@ -394,6 +420,114 @@ Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data, return error; } +std::optional +ELFLinuxPrPsInfo::Populate(const lldb::ProcessSP &process_sp) { + ELFLinuxPrPsInfo prpsinfo{}; + prpsinfo.pr_pid = process_sp->GetID(); + ProcessInstanceInfo info; + if (!process_sp->GetProcessInfo(info)) { +return std::nullopt; + } + prpsinfo.pr_nice = info.GetPriorityValue().value_or(0); + prpsinfo.pr_zomb = 0; + if (auto zombie_opt = info.IsZombie(); zombie_opt.value_or(false)) { +prpsinfo.pr_zomb = 1; + } + /** + * In the linux kernel this comes from: + * state = READ_ONCE(p->__state); + * i = state ? ffz(~state) + 1 : 0; + * psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i]; + * + * So we replicate that here. From proc_pid_stats(5) + * R = Running + * S = Sleeping on uninterrutible wait + * D = Waiting on uninterruptable disk sleep + * T = Tracing stop + * Z = Zombie + * W = Paging + */ + lldb::StateType process_state = process_sp->GetState(); + switch (process_state) { + case lldb::StateType::eStateSuspended: +prpsinfo.pr_sname = 'S'; +prpsinfo.pr_state = 1; +break; + case lldb::StateType::eStateStopped: +[[fallthrough]]; + case lldb::StateType::eStateStepping: +prpsinfo.pr_sname = 'T'; +prpsinfo.pr_state = 3; +break; + case lldb::StateType::eStateUnloaded: +[[fallthrough]]; + case lldb::StateType::eStateRunning: +prpsinfo.pr_sname = 'R'; +prpsinfo.pr_state = 0; +break; + default: +break; + } + + /** + * pr_flags is left as 0. The values (in linux) are specific + * to the kernel. We recover them from the proc filesystem + * but don't put them in ProcessInfo because it would really + * become very linux specific and the utility here seems pretty + * dubious + */ + + if (info.EffectiveUserIDIsValid()) { +prpsinfo.pr_uid = info.GetUserID(); + } + if (info.EffectiveGroupIDIsValid()) { +prpsinfo.pr_gid = info.GetGroupID(); + } + + if (info.ParentProcessIDIsValid()) { +prpsinfo.pr_ppid = info.GetParentProcessID(); + } + + if (info.ProcessGroupIDIsValid()) { +prpsinfo.pr_pgrp = info.GetProcessGroupID(); + } + + if (info.ProcessSessionIDIsValid()) { +prpsinfo.pr_sid = info.GetProcessSessionID(); + } + constexpr size_t fname_len = std::extent_v; + static_assert(fname_len > 0, "This shou
[Lldb-commits] [lldb] [lldb] Realpath symlinks for breakpoints (PR #102223)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `lldb-aarch64-windows` running on `linaro-armv8-windows-msvc-05` while building `lldb` at step 4 "build". Full details are available at: https://lab.llvm.org/buildbot/#/builders/141/builds/1591 Here is the relevant piece of the build log for the reference: ``` Step 4 (build) failure: build (failure) ... 174.379 [4263/10/2102] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\Broadcaster.cpp.obj 174.573 [4262/10/2103] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\Diagnostics.cpp.obj 174.856 [4261/10/2104] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\NameMatches.cpp.obj 175.181 [4260/10/2105] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\GDBRemote.cpp.obj 176.410 [4259/10/2106] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\IOObject.cpp.obj 176.530 [4258/10/2107] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\FileSpec.cpp.obj 176.875 [4257/10/2108] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\RegularExpression.cpp.obj 177.815 [4256/10/2109] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\LLDBLog.cpp.obj 178.387 [4255/10/2110] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\Event.cpp.obj 180.815 [4254/10/2111] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\RealpathPrefixes.cpp.obj FAILED: tools/lldb/source/Utility/CMakeFiles/lldbUtility.dir/RealpathPrefixes.cpp.obj ccache C:\Users\tcwg\scoop\apps\llvm\current\bin\clang-cl.exe /nologo -TP -DGTEST_HAS_RTTI=0 -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_ENABLE_EXTENDED_ALIGNED_STORAGE -D_HAS_EXCEPTIONS=0 -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\tools\lldb\source\Utility -IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source\Utility -IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\include -IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\tools\lldb\include -IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\include -IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\llvm\include -IC:\Users\tcwg\scoop\apps\python\current\include -IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\llvm\..\clang\include -IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\tools\lldb\..\clang\include -IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source -IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\tools\lldb\source /DWIN32 /D_WINDOWS /Zc:inline /Zc:__cplusplus /Oi /Brepro /bigobj /permissive- -Werror=unguarded-availability-new /W4 -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported /Gw -Wno-deprecated-register -Wno-vla-extension /O2 /Ob2 /DNDEBUG -std:c++17 -MD -wd4018 -wd4068 -wd4150 -wd4201 -wd4251 -wd4521 -wd4530 -wd4589 /EHs-c- /GR- /showIncludes /Fotools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\RealpathPrefixes.cpp.obj /Fdtools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\lldbUtility.pdb -c -- C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source\Utility\RealpathPrefixes.cpp C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source\Utility\RealpathPrefixes.cpp(56,25): error: use of undeclared identifier 'PATH_MAX' 56 | llvm::SmallString buff; | ^ 1 error generated. 180.929 [4254/9/2112] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\Log.cpp.obj 181.375 [4254/8/2113] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\FileSpecList.cpp.obj 181.897 [4254/7/2114] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\Instrumentation.cpp.obj 182.226 [4254/6/2115] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\Listener.cpp.obj 182.285 [4254/5/2116] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\RegisterValue.cpp.obj 182.323 [4254/4/2117] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\ProcessInfo.cpp.obj 183.722 [4254/3/2118] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\Scalar.cpp.obj 184.149 [4254/2/2119] Building CXX object tools\lldb\source\Utility\CMakeFiles\lldbUtility.dir\SelectHelper.cpp.obj 187.130 [4254/1/2120] Building CXX object lib\LTO\CMakeFiles\LLVMLTO.dir\LTO.cpp.obj ninja: build stopped: subc
[Lldb-commits] [lldb] [lldb][test] Improve toolchain detection in Makefile.rules (PR #102185)
https://github.com/dzhidzhoev updated https://github.com/llvm/llvm-project/pull/102185 >From b21f63e4376dd9c390abea72a1ebd5594652e681 Mon Sep 17 00:00:00 2001 From: Vladislav Dzhidzhoev Date: Sat, 27 Jul 2024 02:39:32 +0200 Subject: [PATCH] [lldb][test] Improve toolchain detection in Makefile.rules This fix is based on a problem with cxx_compiler and cxx_linker macros on Windows. There was an issue with compiler detection in paths containing "icc". In such case, Makefile.rules thought it was provided with icc compiler. To solve that, quotes from paths are removed, that may be added when arguments are passed from Python to make, the last element of compiler's path is separated, taking into account platform path delimiter, and compiler type is extracted, with regard of possible cross-toolchain prefix. Paths for additional tools, like OBJCOPY, are initialized with tools built with LLVM if USE_LLVM_TOOLS is on, to achieve better portability for Windows. --- .../Python/lldbsuite/test/builders/builder.py | 101 +- .../Python/lldbsuite/test/make/Makefile.rules | 91 +--- .../breakpoint/breakpoint_ids/Makefile| 2 +- .../breakpoint/breakpoint_locations/Makefile | 2 +- .../consecutive_breakpoints/Makefile | 2 +- .../functionalities/breakpoint/cpp/Makefile | 2 +- .../dummy_target_breakpoints/Makefile | 2 +- .../require_hw_breakpoints/Makefile | 2 +- .../breakpoint/step_over_breakpoint/Makefile | 2 +- .../thread_plan_user_breakpoint/Makefile | 2 +- .../ObjCDataFormatterTestCase.py | 4 +- .../TestNSDictionarySynthetic.py | 4 +- .../nssetsynth/TestNSSetSynthetic.py | 4 +- .../poarray/TestPrintObjectArray.py | 4 +- .../functionalities/inline-stepping/Makefile | 2 +- .../postmortem/minidump-new/makefile.txt | 1 + .../lang/objc/orderedset/TestOrderedSet.py| 4 +- .../TestObjCSingleEntryDictionary.py | 4 +- lldb/test/API/macosx/macCatalyst/Makefile | 1 + .../macCatalystAppMacOSFramework/Makefile | 1 + .../macosx/simulator/TestSimulatorPlatform.py | 4 +- .../API/python_api/frame/inlines/Makefile | 2 +- .../lldb-server/TestAppleSimulatorOSType.py | 4 +- 23 files changed, 154 insertions(+), 93 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/builders/builder.py b/lldb/packages/Python/lldbsuite/test/builders/builder.py index 4ea9a86c1d5fc9..e6c2c99cac4948 100644 --- a/lldb/packages/Python/lldbsuite/test/builders/builder.py +++ b/lldb/packages/Python/lldbsuite/test/builders/builder.py @@ -1,10 +1,12 @@ import os +import pathlib import platform import subprocess import sys import itertools import lldbsuite.test.lldbtest as lldbtest +import lldbsuite.test.lldbplatformutil as lldbplatformutil import lldbsuite.test.lldbutil as lldbutil from lldbsuite.test import configuration from lldbsuite.test_event import build_exception @@ -96,16 +98,107 @@ def getArchSpec(self, architecture): """ return ["ARCH=" + architecture] if architecture else [] -def getCCSpec(self, compiler): +def getToolchainSpec(self, compiler): """ -Helper function to return the key-value string to specify the compiler +Helper function to return the key-value strings to specify the toolchain used for the make system. """ cc = compiler if compiler else None if not cc and configuration.compiler: cc = configuration.compiler + if cc: -return ['CC="%s"' % cc] +exe_ext = "" +if lldbplatformutil.getHostPlatform() == "windows": +exe_ext = ".exe" + +cc = cc.strip() +cc_path = pathlib.Path(cc) +cc = cc_path.as_posix() + +# We can get CC compiler string in the following formats: +# [] - such as 'xrun clang', 'xrun /usr/bin/clang' & etc +# +# Where could contain the following parts: +# [.] - sucn as 'clang', 'clang.exe' ('clamg-cl.exe'?) +# -[.] - such as 'armv7-linux-gnueabi-gcc' +# /[.]- such as '/usr/bin/clang', 'c:\path\to\compiler\clang,exe' +# /-[.]- such as '/usr/bin/clang', 'c:\path\to\compiler\clang,exe' + +cc_ext = cc_path.suffix +# Compiler name without extension +cc_name = cc_path.stem.split(" ")[-1] + +# A kind of compiler (canonical name): clang, gcc, cc & etc. +cc_type = cc_name +# A triple prefix of compiler name: gcc +cc_prefix = "" +if not "clang-cl" in cc_name and not "llvm-gcc" in cc_name: +cc_name_parts = cc_name.split("-") +cc_type = cc_name_parts[-1] +if len(cc_name_parts) > 1: +cc_prefi
[Lldb-commits] [lldb] [lldb][test] Improve toolchain detection in Makefile.rules (PR #102185)
https://github.com/dzhidzhoev updated https://github.com/llvm/llvm-project/pull/102185 >From 5130b2af8c2a274d73a9d90a4a71d77d85ac0973 Mon Sep 17 00:00:00 2001 From: Vladislav Dzhidzhoev Date: Sat, 27 Jul 2024 02:39:32 +0200 Subject: [PATCH] [lldb][test] Improve toolchain detection in Makefile.rules This fix is based on a problem with cxx_compiler and cxx_linker macros on Windows. There was an issue with compiler detection in paths containing "icc". In such case, Makefile.rules thought it was provided with icc compiler. To solve that, utilities detection has been rewritten in Python. The last element of compiler's path is separated, taking into account platform path delimiter, and compiler type is extracted, with regard of possible cross-toolchain prefix. Paths for additional tools, like OBJCOPY, are initialized with tools built with LLVM if USE_LLVM_TOOLS is on, to achieve better portability for Windows. Quotes from paths are removed in Makefile.rules, that may be added when arguments are passed from Python to make. --- .../Python/lldbsuite/test/builders/builder.py | 101 +- .../Python/lldbsuite/test/make/Makefile.rules | 91 +--- .../breakpoint/breakpoint_ids/Makefile| 2 +- .../breakpoint/breakpoint_locations/Makefile | 2 +- .../consecutive_breakpoints/Makefile | 2 +- .../functionalities/breakpoint/cpp/Makefile | 2 +- .../dummy_target_breakpoints/Makefile | 2 +- .../require_hw_breakpoints/Makefile | 2 +- .../breakpoint/step_over_breakpoint/Makefile | 2 +- .../thread_plan_user_breakpoint/Makefile | 2 +- .../ObjCDataFormatterTestCase.py | 4 +- .../TestNSDictionarySynthetic.py | 4 +- .../nssetsynth/TestNSSetSynthetic.py | 4 +- .../poarray/TestPrintObjectArray.py | 4 +- .../functionalities/inline-stepping/Makefile | 2 +- .../postmortem/minidump-new/makefile.txt | 1 + .../lang/objc/orderedset/TestOrderedSet.py| 4 +- .../TestObjCSingleEntryDictionary.py | 4 +- lldb/test/API/macosx/macCatalyst/Makefile | 1 + .../macCatalystAppMacOSFramework/Makefile | 1 + .../macosx/simulator/TestSimulatorPlatform.py | 4 +- .../API/python_api/frame/inlines/Makefile | 2 +- .../lldb-server/TestAppleSimulatorOSType.py | 4 +- 23 files changed, 154 insertions(+), 93 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/builders/builder.py b/lldb/packages/Python/lldbsuite/test/builders/builder.py index 4ea9a86c1d5fc9..e6c2c99cac4948 100644 --- a/lldb/packages/Python/lldbsuite/test/builders/builder.py +++ b/lldb/packages/Python/lldbsuite/test/builders/builder.py @@ -1,10 +1,12 @@ import os +import pathlib import platform import subprocess import sys import itertools import lldbsuite.test.lldbtest as lldbtest +import lldbsuite.test.lldbplatformutil as lldbplatformutil import lldbsuite.test.lldbutil as lldbutil from lldbsuite.test import configuration from lldbsuite.test_event import build_exception @@ -96,16 +98,107 @@ def getArchSpec(self, architecture): """ return ["ARCH=" + architecture] if architecture else [] -def getCCSpec(self, compiler): +def getToolchainSpec(self, compiler): """ -Helper function to return the key-value string to specify the compiler +Helper function to return the key-value strings to specify the toolchain used for the make system. """ cc = compiler if compiler else None if not cc and configuration.compiler: cc = configuration.compiler + if cc: -return ['CC="%s"' % cc] +exe_ext = "" +if lldbplatformutil.getHostPlatform() == "windows": +exe_ext = ".exe" + +cc = cc.strip() +cc_path = pathlib.Path(cc) +cc = cc_path.as_posix() + +# We can get CC compiler string in the following formats: +# [] - such as 'xrun clang', 'xrun /usr/bin/clang' & etc +# +# Where could contain the following parts: +# [.] - sucn as 'clang', 'clang.exe' ('clamg-cl.exe'?) +# -[.] - such as 'armv7-linux-gnueabi-gcc' +# /[.]- such as '/usr/bin/clang', 'c:\path\to\compiler\clang,exe' +# /-[.]- such as '/usr/bin/clang', 'c:\path\to\compiler\clang,exe' + +cc_ext = cc_path.suffix +# Compiler name without extension +cc_name = cc_path.stem.split(" ")[-1] + +# A kind of compiler (canonical name): clang, gcc, cc & etc. +cc_type = cc_name +# A triple prefix of compiler name: gcc +cc_prefix = "" +if not "clang-cl" in cc_name and not "llvm-gcc" in cc_name: +cc_name_parts = cc_name.split("-") +cc_type = cc_name_parts[-1] +
[Lldb-commits] [lldb] [lldb][test] Improve toolchain detection in Makefile.rules (PR #102185)
https://github.com/dzhidzhoev edited https://github.com/llvm/llvm-project/pull/102185 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][test] Improve toolchain detection in Makefile.rules (PR #102185)
dzhidzhoev wrote: > Umm... could we move this logic to python, and then just pass the final tool > paths (or whatever) into the makefile, like we did with the other patches > (for `(HOST_)OS`, etc.) ? Moved logic to Python, updated commit description. https://github.com/llvm/llvm-project/pull/102185 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Realpath symlinks for breakpoints (PR #102223)
royitaqi wrote: I'm looking at this build break with `PATH_MAX`. Trying to figure out what to use instead. If anyone knows what to use, please LMK. https://github.com/llvm/llvm-project/pull/102223 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix PATH_MAX for Windows (PR #104493)
https://github.com/royitaqi created https://github.com/llvm/llvm-project/pull/104493 Fix build break for Windows, caused by a [previous patch](https://github.com/llvm/llvm-project/pull/102223) using `PATH_MAX` which is undefined in Windows. The fix is to `#include "lldb/Host/PosixApi.h"` in the source file. >From cc75f7c1583263a2f4f8da4d7bc5e3a05be9c99d Mon Sep 17 00:00:00 2001 From: Roy Shi Date: Thu, 15 Aug 2024 13:01:32 -0700 Subject: [PATCH] Fix PATH_MAX for windows --- lldb/source/Utility/RealpathPrefixes.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/source/Utility/RealpathPrefixes.cpp b/lldb/source/Utility/RealpathPrefixes.cpp index 14c81ee6a1f571..ee1c404c899676 100644 --- a/lldb/source/Utility/RealpathPrefixes.cpp +++ b/lldb/source/Utility/RealpathPrefixes.cpp @@ -8,6 +8,7 @@ #include "lldb/Utility/RealpathPrefixes.h" +#include "lldb/Host/PosixApi.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/FileSpecList.h" #include "lldb/Utility/LLDBLog.h" ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix PATH_MAX for Windows (PR #104493)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: None (royitaqi) Changes Fix build break for Windows, caused by a [previous patch](https://github.com/llvm/llvm-project/pull/102223) using `PATH_MAX` which is undefined in Windows. The fix is to `#include "lldb/Host/PosixApi.h"` in the source file. --- Full diff: https://github.com/llvm/llvm-project/pull/104493.diff 1 Files Affected: - (modified) lldb/source/Utility/RealpathPrefixes.cpp (+1) ``diff diff --git a/lldb/source/Utility/RealpathPrefixes.cpp b/lldb/source/Utility/RealpathPrefixes.cpp index 14c81ee6a1f571..ee1c404c899676 100644 --- a/lldb/source/Utility/RealpathPrefixes.cpp +++ b/lldb/source/Utility/RealpathPrefixes.cpp @@ -8,6 +8,7 @@ #include "lldb/Utility/RealpathPrefixes.h" +#include "lldb/Host/PosixApi.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/FileSpecList.h" #include "lldb/Utility/LLDBLog.h" `` https://github.com/llvm/llvm-project/pull/104493 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] (lldb) Fix PATH_MAX for Windows (PR #104493)
https://github.com/royitaqi edited https://github.com/llvm/llvm-project/pull/104493 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] (lldb) Fix PATH_MAX for Windows (PR #104493)
royitaqi wrote: I don't have a Windows machine to test this build on. So I'm merging this blindfolded, in the hope of fixing the build break so that less folks who are working on Windows will get affected by the break. https://github.com/llvm/llvm-project/pull/104493 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] (lldb) Fix build break for Windows (`PATH_MAX`) (PR #104493)
https://github.com/royitaqi edited https://github.com/llvm/llvm-project/pull/104493 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] (lldb) Fix build break for Windows (`PATH_MAX`) (PR #104493)
royitaqi wrote: I'm waiting for the "buildkite/github-pull-requests" job to finish (so that this "fix" won't break more things). LMK if I don't need to wait for it. https://github.com/llvm/llvm-project/pull/104493 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] f377edb - (lldb) Fix PATH_MAX for Windows (#104493)
Author: royitaqi Date: 2024-08-15T13:14:26-07:00 New Revision: f377edb96abe9fd6fa458415f07b0f411e59cf24 URL: https://github.com/llvm/llvm-project/commit/f377edb96abe9fd6fa458415f07b0f411e59cf24 DIFF: https://github.com/llvm/llvm-project/commit/f377edb96abe9fd6fa458415f07b0f411e59cf24.diff LOG: (lldb) Fix PATH_MAX for Windows (#104493) The build break was caused by a [previous patch](https://github.com/llvm/llvm-project/pull/102223) using `PATH_MAX` which is undefined in Windows. Added: Modified: lldb/source/Utility/RealpathPrefixes.cpp Removed: diff --git a/lldb/source/Utility/RealpathPrefixes.cpp b/lldb/source/Utility/RealpathPrefixes.cpp index 14c81ee6a1f571..ee1c404c899676 100644 --- a/lldb/source/Utility/RealpathPrefixes.cpp +++ b/lldb/source/Utility/RealpathPrefixes.cpp @@ -8,6 +8,7 @@ #include "lldb/Utility/RealpathPrefixes.h" +#include "lldb/Host/PosixApi.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/FileSpecList.h" #include "lldb/Utility/LLDBLog.h" ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] (lldb) Fix build break for Windows (`PATH_MAX`) (PR #104493)
https://github.com/royitaqi closed https://github.com/llvm/llvm-project/pull/104493 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Reapply #100443 SBSaveCore Thread list (PR #104497)
https://github.com/Jlalond created https://github.com/llvm/llvm-project/pull/104497 Reapply #100443 and #101770. These were originally reverted due to a test failure and an MSAN failure. I changed the test attribute to restrict to x86 (following the other existing tests). I could not reproduce the test or the MSAN failure and no repo steps were provided. >From 6f7bb2005f221dfd50e575aaf411ebad5042f1c5 Mon Sep 17 00:00:00 2001 From: Jacob Lalonde Date: Mon, 5 Aug 2024 13:32:15 -0700 Subject: [PATCH 1/4] =?UTF-8?q?Reapply=20"[LLDB][SBSaveCore]=20Implement?= =?UTF-8?q?=20a=20selectable=20threadlist=20for=20Core=E2=80=A6=20(#102018?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit accf5c9bb3b5fe88628a44062a5c0c2f903fca2c. --- lldb/include/lldb/API/SBProcess.h | 1 + lldb/include/lldb/API/SBSaveCoreOptions.h | 27 +++ lldb/include/lldb/API/SBThread.h | 3 + lldb/include/lldb/Symbol/SaveCoreOptions.h| 15 +++- lldb/include/lldb/Target/Process.h| 8 +- lldb/source/API/SBSaveCoreOptions.cpp | 17 +++- lldb/source/API/SBThread.cpp | 2 + lldb/source/Core/PluginManager.cpp| 4 + .../ObjectFile/Mach-O/ObjectFileMachO.cpp | 24 +++--- .../Minidump/MinidumpFileBuilder.cpp | 72 - .../ObjectFile/Minidump/MinidumpFileBuilder.h | 10 ++- .../Minidump/ObjectFileMinidump.cpp | 5 +- lldb/source/Symbol/SaveCoreOptions.cpp| 80 +++ lldb/source/Target/Process.cpp| 30 +-- .../TestProcessSaveCoreMinidump.py| 55 + .../TestSBSaveCoreOptions.py | 55 - .../sbsavecoreoptions/basic_minidump.yaml | 26 ++ .../basic_minidump_different_pid.yaml | 26 ++ 18 files changed, 395 insertions(+), 65 deletions(-) create mode 100644 lldb/test/API/python_api/sbsavecoreoptions/basic_minidump.yaml create mode 100644 lldb/test/API/python_api/sbsavecoreoptions/basic_minidump_different_pid.yaml diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 778be795839901..1624e02070b1b2 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -586,6 +586,7 @@ class LLDB_API SBProcess { friend class SBBreakpointCallbackBaton; friend class SBBreakpointLocation; friend class SBCommandInterpreter; + friend class SBSaveCoreOptions; friend class SBDebugger; friend class SBExecutionContext; friend class SBFunction; diff --git a/lldb/include/lldb/API/SBSaveCoreOptions.h b/lldb/include/lldb/API/SBSaveCoreOptions.h index e77496bd3a4a0d..df0aa561de4080 100644 --- a/lldb/include/lldb/API/SBSaveCoreOptions.h +++ b/lldb/include/lldb/API/SBSaveCoreOptions.h @@ -10,6 +10,10 @@ #define LLDB_API_SBSAVECOREOPTIONS_H #include "lldb/API/SBDefines.h" +#include "lldb/API/SBError.h" +#include "lldb/API/SBFileSpec.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBThread.h" namespace lldb { @@ -53,6 +57,29 @@ class LLDB_API SBSaveCoreOptions { /// \return The output file spec. SBFileSpec GetOutputFile() const; + /// Set the process to save, or unset if supplied with a default constructed + /// process. + /// + /// \param process The process to save. + /// \return Success if process was set, otherwise an error + /// \note This will clear all process specific options if a different process + /// is specified than the current set process, either explicitly from this + /// api, or implicitly from any function that requires a process. + SBError SetProcess(lldb::SBProcess process); + + /// Add a thread to save in the core file. + /// + /// \param thread The thread to save. + /// \note This will set the process if it is not already set, or return + /// and error if the SBThread is not from the set process. + SBError AddThread(lldb::SBThread thread); + + /// Remove a thread from the list of threads to save. + /// + /// \param thread The thread to remove. + /// \return True if the thread was removed, false if it was not in the list. + bool RemoveThread(lldb::SBThread thread); + /// Reset all options. void Clear(); diff --git a/lldb/include/lldb/API/SBThread.h b/lldb/include/lldb/API/SBThread.h index dcf6aa9d5424e8..f8ae627da5acee 100644 --- a/lldb/include/lldb/API/SBThread.h +++ b/lldb/include/lldb/API/SBThread.h @@ -233,6 +233,7 @@ class LLDB_API SBThread { friend class SBBreakpoint; friend class SBBreakpointLocation; friend class SBBreakpointCallbackBaton; + friend class SBSaveCoreOptions; friend class SBExecutionContext; friend class SBFrame; friend class SBProcess; @@ -253,6 +254,8 @@ class LLDB_API SBThread { SBError ResumeNewPlan(lldb_private::ExecutionContext &exe_ctx, lldb_private::ThreadPlan *new_plan); + lldb::ThreadSP GetSP() const; + lldb::ExecutionContex