[Lldb-commits] [PATCH] D88282: Add support for a "main bin spec" LC_NOTE for standalone/firmware corefile binaries in MachO corefiles
jasonmolenda created this revision. jasonmolenda added a reviewer: jingham. jasonmolenda added a project: LLDB. Herald added a subscriber: JDevlieghere. Herald added a reviewer: JDevlieghere. jasonmolenda requested review of this revision. This patch is primarily to ProcessMachCore to correctly load a firmware/standalone main binary in a corefile which is using the "main bin spec" LC_NOTE. There's already support for this for a "kern ver str" LC_NOTE that includes a UUID to load, this patch extends that to the other LC_NOTE and also sets the load address on the binary it locates to 0 (no-slide) as a default loading. I also stopped an unnecessary scan over the corefile looking for user-process dyld or kernel binaries once I'd already gotten one of these two LC_NOTEs. I also modified ObjectFile::GetCorefileMainBinaryInfo to pass up the type of binary that was specified, which was in the "main bin spec" but not returned previously. The test case is based on the one I wrote earlier for test/API/macosx/lc-note/kern-ver-str. It adds the ability to write both types of LC_NOTEs (kern ver str, main bin spec) and compiles two binaries (with random UUIDs). It creates a dsym-for-uuid.sh that recognizes the two UUIDs and points to the correct binaries/dSYMs, creates corefiles using the tool it built earlier, and runs lldb against the corefiles to confirm that the binaries are loaded correctly. It only runs on macOS x86_64 systems for now. I'm not sure there's anyone who's really interested in reviewing this one; ProcessMachCore is my back yard in the codebase :) but I'm open to any comments or suggestions, naturally. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D88282 Files: lldb/include/lldb/Symbol/ObjectFile.h lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp lldb/test/API/macosx/lc-note/firmware-corefile/Makefile lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py lldb/test/API/macosx/lc-note/firmware-corefile/bout.mk lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp lldb/test/API/macosx/lc-note/firmware-corefile/main.c Index: lldb/test/API/macosx/lc-note/firmware-corefile/main.c === --- /dev/null +++ lldb/test/API/macosx/lc-note/firmware-corefile/main.c @@ -0,0 +1,2 @@ +#include +int main () { puts ("this is the lc-note test program."); } Index: lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp === --- /dev/null +++ lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp @@ -0,0 +1,371 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// Create an empty corefile with a "kern ver str" LC_NOTE +// or a "main bin spec" LC_NOTE.. +// If an existing binary is given as a 3rd argument on the cmd line, +// the UUID from that binary will be encoded in the corefile. +// Otherwise a pre-set UUID will be put in the corefile that +// is created. + +struct main_bin_spec_payload { +uint32_t version; +uint32_t type; +uint64_t address; +uuid_t uuid; +uint32_t log2_pagesize; +uint32_t unused; +}; + + +union uint32_buf { +uint8_t bytebuf[4]; +uint32_t val; +}; + +union uint64_buf { +uint8_t bytebuf[8]; +uint64_t val; +}; + +void +add_uint64(std::vector &buf, uint64_t val) +{ +uint64_buf conv; +conv.val = val; +for (int i = 0; i < 8; i++) +buf.push_back(conv.bytebuf[i]); +} + +void +add_uint32(std::vector &buf, uint32_t val) +{ +uint32_buf conv; +conv.val = val; +for (int i = 0; i < 4; i++) +buf.push_back(conv.bytebuf[i]); +} + +std::vector +x86_lc_thread_load_command () +{ +std::vector data; +add_uint32 (data, LC_THREAD);// thread_command.cmd +add_uint32 (data, 184); // thread_command.cmdsize +add_uint32 (data, x86_THREAD_STATE64); // thread_command.flavor +add_uint32 (data, x86_THREAD_STATE64_COUNT); // thread_command.count +add_uint64 (data, 0x); // rax +add_uint64 (data, 0x0400); // rbx +add_uint64 (data, 0x); // rcx +add_uint64 (data, 0x); // rdx +add_uint64 (data, 0x); // rdi +add_uint64 (data, 0x); // rsi +add_uint64 (data, 0xff9246e2ba20); // rbp +add_uint64 (data, 0xff9246e2ba10); // rsp +add_uint64 (data, 0x); // r8 +add_uint64 (data, 0x); // r9 +add_uint64 (data, 0x); // r10 +add_uint64 (data, 0x); // r11 +add_uint64 (data, 0xff7f96ce5fe1); // r12 +
[Lldb-commits] [PATCH] D88229: Reland "[lldb] Don't send invalid region addresses to lldb server"
DavidSpickett updated this revision to Diff 294266. DavidSpickett added a comment. - Convert memory region to early return style to make the logic clearer - Only call ::GetLastError once when VirtualQueryEx fails Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D88229/new/ https://reviews.llvm.org/D88229 Files: lldb/source/Commands/CommandObjectMemory.cpp lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp lldb/test/API/functionalities/memory-region/TestMemoryRegion.py Index: lldb/test/API/functionalities/memory-region/TestMemoryRegion.py === --- lldb/test/API/functionalities/memory-region/TestMemoryRegion.py +++ lldb/test/API/functionalities/memory-region/TestMemoryRegion.py @@ -41,6 +41,12 @@ self.assertFalse(result.Succeeded()) self.assertRegexpMatches(result.GetError(), "Usage: memory region ADDR") +# Test that when the address fails to parse, we show an error and do not continue +interp.HandleCommand("memory region not_an_address", result) +self.assertFalse(result.Succeeded()) +self.assertEqual(result.GetError(), +"error: invalid address argument \"not_an_address\": address expression \"not_an_address\" evaluation failed\n") + # Now let's print the memory region starting at 0 which should always work. interp.HandleCommand("memory region 0x0", result) self.assertTrue(result.Succeeded()) Index: lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp === --- lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp +++ lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp @@ -405,7 +405,8 @@ MEMORY_BASIC_INFORMATION mem_info = {}; SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info)); if (result == 0) { -if (::GetLastError() == ERROR_INVALID_PARAMETER) { +DWORD last_error = ::GetLastError(); +if (last_error == ERROR_INVALID_PARAMETER) { // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with // an address past the highest accessible address. We should return a // range from the vm_addr to LLDB_INVALID_ADDRESS @@ -417,7 +418,7 @@ info.SetMapped(MemoryRegionInfo::eNo); return error; } else { - error.SetError(::GetLastError(), eErrorTypeWin32); + error.SetError(last_error, eErrorTypeWin32); LLDB_LOG(log, "VirtualQueryEx returned error {0} while getting memory " "region info for address {1:x}", @@ -460,7 +461,6 @@ info.SetMapped(MemoryRegionInfo::eNo); } - error.SetError(::GetLastError(), eErrorTypeWin32); LLDB_LOGV(log, "Memory region info for address {0}: readable={1}, " "executable={2}, writable={3}", Index: lldb/source/Commands/CommandObjectMemory.cpp === --- lldb/source/Commands/CommandObjectMemory.cpp +++ lldb/source/Commands/CommandObjectMemory.cpp @@ -1687,63 +1687,67 @@ protected: bool DoExecute(Args &command, CommandReturnObject &result) override { ProcessSP process_sp = m_exe_ctx.GetProcessSP(); -if (process_sp) { - Status error; - lldb::addr_t load_addr = m_prev_end_addr; +if (!process_sp) { m_prev_end_addr = LLDB_INVALID_ADDRESS; + result.AppendError("invalid process"); + result.SetStatus(eReturnStatusFailed); + return false; +} + +Status error; +lldb::addr_t load_addr = m_prev_end_addr; +m_prev_end_addr = LLDB_INVALID_ADDRESS; - const size_t argc = command.GetArgumentCount(); - if (argc > 1 || (argc == 0 && load_addr == LLDB_INVALID_ADDRESS)) { -result.AppendErrorWithFormat("'%s' takes one argument:\nUsage: %s\n", - m_cmd_name.c_str(), m_cmd_syntax.c_str()); +const size_t argc = command.GetArgumentCount(); +if (argc > 1 || (argc == 0 && load_addr == LLDB_INVALID_ADDRESS)) { + result.AppendErrorWithFormat("'%s' takes one argument:\nUsage: %s\n", + m_cmd_name.c_str(), m_cmd_syntax.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; +} + +if (argc == 1) { + auto load_addr_str = command[0].ref(); + load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str, + LLDB_INVALID_ADDRESS, &error); + if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) { +result.AppendErrorWithFormat( +"invalid address argument \"%s\": %s\n", command[0].c_str(), +error.AsCString()); result.SetStatus(eReturnStatusFailed); - } else { -if (command.GetArgumentCount() == 1) { - auto load_addr_str = command[0].ref(); - load_addr = OptionArgParse
[Lldb-commits] [PATCH] D88229: Reland "[lldb] Don't send invalid region addresses to lldb server"
DavidSpickett added inline comments. Comment at: lldb/source/Commands/CommandObjectMemory.cpp:1701 } else { if (command.GetArgumentCount() == 1) { auto load_addr_str = command[0].ref(); stella.stamenova wrote: > Actually, I would change the logic here a little bit to make it easier to > read. Right now it is: > > ``` > if (argc > 1 || ... ) { > } else { > if (GetArgumentCount() == 1) { > } > ... > } > ``` > > It should be: > > ``` > if (argc > 1 || ... ) { > } else if (argc == 1) { //since argc already has the value of > GetArgumentCount() > } > > if (result.Succeeded()) { > ... > } > ``` > > This will make the function more readable, fixing the bug that you found, > preserving most of its logic and keeping the single return. > You're the second person to bring this up, so I've converted the logic to return early. (I know that's more than you asked but I think it helps overall) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D88229/new/ https://reviews.llvm.org/D88229 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D88229: Reland "[lldb] Don't send invalid region addresses to lldb server"
DavidSpickett updated this revision to Diff 294272. DavidSpickett added a comment. - clang-format Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D88229/new/ https://reviews.llvm.org/D88229 Files: lldb/source/Commands/CommandObjectMemory.cpp lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp lldb/test/API/functionalities/memory-region/TestMemoryRegion.py Index: lldb/test/API/functionalities/memory-region/TestMemoryRegion.py === --- lldb/test/API/functionalities/memory-region/TestMemoryRegion.py +++ lldb/test/API/functionalities/memory-region/TestMemoryRegion.py @@ -41,6 +41,12 @@ self.assertFalse(result.Succeeded()) self.assertRegexpMatches(result.GetError(), "Usage: memory region ADDR") +# Test that when the address fails to parse, we show an error and do not continue +interp.HandleCommand("memory region not_an_address", result) +self.assertFalse(result.Succeeded()) +self.assertEqual(result.GetError(), +"error: invalid address argument \"not_an_address\": address expression \"not_an_address\" evaluation failed\n") + # Now let's print the memory region starting at 0 which should always work. interp.HandleCommand("memory region 0x0", result) self.assertTrue(result.Succeeded()) Index: lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp === --- lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp +++ lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp @@ -405,7 +405,8 @@ MEMORY_BASIC_INFORMATION mem_info = {}; SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info)); if (result == 0) { -if (::GetLastError() == ERROR_INVALID_PARAMETER) { +DWORD last_error = ::GetLastError(); +if (last_error == ERROR_INVALID_PARAMETER) { // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with // an address past the highest accessible address. We should return a // range from the vm_addr to LLDB_INVALID_ADDRESS @@ -417,7 +418,7 @@ info.SetMapped(MemoryRegionInfo::eNo); return error; } else { - error.SetError(::GetLastError(), eErrorTypeWin32); + error.SetError(last_error, eErrorTypeWin32); LLDB_LOG(log, "VirtualQueryEx returned error {0} while getting memory " "region info for address {1:x}", @@ -460,7 +461,6 @@ info.SetMapped(MemoryRegionInfo::eNo); } - error.SetError(::GetLastError(), eErrorTypeWin32); LLDB_LOGV(log, "Memory region info for address {0}: readable={1}, " "executable={2}, writable={3}", Index: lldb/source/Commands/CommandObjectMemory.cpp === --- lldb/source/Commands/CommandObjectMemory.cpp +++ lldb/source/Commands/CommandObjectMemory.cpp @@ -1687,63 +1687,66 @@ protected: bool DoExecute(Args &command, CommandReturnObject &result) override { ProcessSP process_sp = m_exe_ctx.GetProcessSP(); -if (process_sp) { - Status error; - lldb::addr_t load_addr = m_prev_end_addr; +if (!process_sp) { m_prev_end_addr = LLDB_INVALID_ADDRESS; + result.AppendError("invalid process"); + result.SetStatus(eReturnStatusFailed); + return false; +} + +Status error; +lldb::addr_t load_addr = m_prev_end_addr; +m_prev_end_addr = LLDB_INVALID_ADDRESS; - const size_t argc = command.GetArgumentCount(); - if (argc > 1 || (argc == 0 && load_addr == LLDB_INVALID_ADDRESS)) { -result.AppendErrorWithFormat("'%s' takes one argument:\nUsage: %s\n", - m_cmd_name.c_str(), m_cmd_syntax.c_str()); +const size_t argc = command.GetArgumentCount(); +if (argc > 1 || (argc == 0 && load_addr == LLDB_INVALID_ADDRESS)) { + result.AppendErrorWithFormat("'%s' takes one argument:\nUsage: %s\n", + m_cmd_name.c_str(), m_cmd_syntax.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; +} + +if (argc == 1) { + auto load_addr_str = command[0].ref(); + load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str, + LLDB_INVALID_ADDRESS, &error); + if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) { +result.AppendErrorWithFormat("invalid address argument \"%s\": %s\n", + command[0].c_str(), error.AsCString()); result.SetStatus(eReturnStatusFailed); - } else { -if (command.GetArgumentCount() == 1) { - auto load_addr_str = command[0].ref(); - load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str, - LLDB_INVALID_A
[Lldb-commits] [PATCH] D88247: Fix memory leak in SBValue::GetAddress
werat added a comment. Thanks for reviewing and writing a follow-up change! Changing the ctor to accept a const reference is indeed a cleaner solution. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D88247/new/ https://reviews.llvm.org/D88247 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D88249: [lldb] Make protected ctor and method of SBAddress take a const reference instead of a pointer.
werat accepted this revision. werat added a comment. This revision is now accepted and ready to land. Thanks for refactoring this! Repository: rLLDB LLDB CHANGES SINCE LAST ACTION https://reviews.llvm.org/D88249/new/ https://reviews.llvm.org/D88249 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D88123: Add the ability to write 'target stop-hooks' in Python
JDevlieghere accepted this revision. JDevlieghere added inline comments. This revision is now accepted and ready to land. Comment at: lldb/include/lldb/Interpreter/ScriptInterpreter.h:302 + virtual StructuredData::GenericSP + CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name, + StructuredDataImpl *args_data, Status &error) { jingham wrote: > JDevlieghere wrote: > > Could this function return an `Expected` instead? > There are a bunch of instances of objects created to insert scripting into > various lldb callbacks around in lldb. It might make sense to convert them > all to Expected's, but I wouldn't want to do it piecemeal. > > Adding a new one of these is also a bit cargo-culty (another issue we should > probably clean up as a separate bit of work) and so making the same things > look different is not doing the next person who adds one any favors. > > These are also functions that are not going to get called promiscuously, but > really from one "make me one of these" places, so they aren't crying out for > protection against calling them w/o checking for errors. > > But anyway, IMO if we're going to start restructuring the pattern for setting > these callback objects up, we should do that as a separate commit and do it > for all of them. If I counted correctly there are 2 others: `CreateScriptedThreadPlan` which takes a `std::string&` as an error and `CreateScriptedBreakpointResolver` which doesn't seem to do error handling at all. So I think we should try to refactor all three to return `Expected`s. I agree we should do that in a separate patch. Comment at: lldb/include/lldb/Target/Target.h:1231 +std::string m_class_name; +StructuredDataImpl *m_extra_args; // We own this structured data, + // but the SD itself manages the UP. jingham wrote: > JDevlieghere wrote: > > Please make these Doxygen comments (`///`) and put them on the line above > > the variable. > I didn't quite do that. > > The comment about "We own..." doesn't seem to me to be a doc comment. It > isn't something that a user of this stop hook class would need to know. It's > just an answer to a question somebody reading the code closely might ask > about why we don't have to have something keeping this m_extra_args alive. I > did add a doc comment for this field, but kept the side comment as is. It's private anyway, so I think the boundaries are pretty fluid. But I don't feel strongly about it. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D88123/new/ https://reviews.llvm.org/D88123 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D88282: Add support for a "main bin spec" LC_NOTE for standalone/firmware corefile binaries in MachO corefiles
JDevlieghere added inline comments. Comment at: lldb/include/lldb/Symbol/ObjectFile.h:94 + // If we have a corefile binary hint, this enum + // specifies the binary type which we can use to `///` Comment at: lldb/include/lldb/Symbol/ObjectFile.h:100 +eBinaryTypeUnknown, +eBinaryTypeKernel,// kernel binary +eBinaryTypeUser, // user process binary `/// <` Comment at: lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp:5567 uuid = UUID::fromOptionalData(raw_uuid, sizeof(uuid_t)); + switch (binspec_type) { + case 0: It seems like this could be outlined into a little static helper function. Something along the lines of ``` BinaryType GetBinaryType(uint32_t binspec_type); ``` Comment at: lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp:471 + if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { +LLDB_LOGF(log, + "ProcessMachCore::DoLoadCore: Using kernel corefile image " Maybe have a little lambda for the two bodies to reduce the duplication? Comment at: lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp:39 +add_uint64(std::vector &buf, uint64_t val) +{ +uint64_buf conv; This does not look clang-formatted 🤐 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D88282/new/ https://reviews.llvm.org/D88282 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D88229: Reland "[lldb] Don't send invalid region addresses to lldb server"
stella.stamenova accepted this revision. stella.stamenova added a comment. This revision is now accepted and ready to land. LGTM Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D88229/new/ https://reviews.llvm.org/D88229 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 6cd4a4c - [lldb] Pass reference instead of pointer in protected SBAddress methods.
Author: Jonas Devlieghere Date: 2020-09-25T11:47:05-07:00 New Revision: 6cd4a4cd02dba6aed33c447114587eebf6854c43 URL: https://github.com/llvm/llvm-project/commit/6cd4a4cd02dba6aed33c447114587eebf6854c43 DIFF: https://github.com/llvm/llvm-project/commit/6cd4a4cd02dba6aed33c447114587eebf6854c43.diff LOG: [lldb] Pass reference instead of pointer in protected SBAddress methods. Every call to the protected SBAddress constructor and the SetAddress method takes the address of a valid object which means we might as well pass it as a const reference instead of a pointer and drop the null check. Differential revision: https://reviews.llvm.org/D88249 Added: Modified: lldb/include/lldb/API/SBAddress.h lldb/source/API/SBAddress.cpp lldb/source/API/SBBreakpointLocation.cpp lldb/source/API/SBFrame.cpp lldb/source/API/SBFunction.cpp lldb/source/API/SBInstruction.cpp lldb/source/API/SBLineEntry.cpp lldb/source/API/SBQueueItem.cpp lldb/source/API/SBSymbol.cpp lldb/source/API/SBValue.cpp Removed: diff --git a/lldb/include/lldb/API/SBAddress.h b/lldb/include/lldb/API/SBAddress.h index cf7555dc2ee8..5a792a24cf6e 100644 --- a/lldb/include/lldb/API/SBAddress.h +++ b/lldb/include/lldb/API/SBAddress.h @@ -115,9 +115,9 @@ class LLDB_API SBAddress { const lldb_private::Address &ref() const; - SBAddress(const lldb_private::Address *lldb_object_ptr); + SBAddress(const lldb_private::Address &address); - void SetAddress(const lldb_private::Address *lldb_object_ptr); + void SetAddress(const lldb_private::Address &address); private: std::unique_ptr m_opaque_up; diff --git a/lldb/source/API/SBAddress.cpp b/lldb/source/API/SBAddress.cpp index 6444a006c0ff..7c102270a87c 100644 --- a/lldb/source/API/SBAddress.cpp +++ b/lldb/source/API/SBAddress.cpp @@ -25,11 +25,8 @@ SBAddress::SBAddress() : m_opaque_up(new Address()) { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBAddress); } -SBAddress::SBAddress(const Address *lldb_object_ptr) -: m_opaque_up(new Address()) { - if (lldb_object_ptr) -m_opaque_up = std::make_unique(*lldb_object_ptr); -} +SBAddress::SBAddress(const Address &address) +: m_opaque_up(std::make_unique(address)) {} SBAddress::SBAddress(const SBAddress &rhs) : m_opaque_up(new Address()) { LLDB_RECORD_CONSTRUCTOR(SBAddress, (const lldb::SBAddress &), rhs); @@ -101,12 +98,7 @@ void SBAddress::SetAddress(lldb::SBSection section, lldb::addr_t offset) { addr.SetOffset(offset); } -void SBAddress::SetAddress(const Address *lldb_object_ptr) { - if (lldb_object_ptr) -ref() = *lldb_object_ptr; - else -m_opaque_up = std::make_unique(); -} +void SBAddress::SetAddress(const Address &address) { ref() = address; } lldb::addr_t SBAddress::GetFileAddress() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::addr_t, SBAddress, GetFileAddress); diff --git a/lldb/source/API/SBBreakpointLocation.cpp b/lldb/source/API/SBBreakpointLocation.cpp index e29f3fd9c50e..d6bbb5faf041 100644 --- a/lldb/source/API/SBBreakpointLocation.cpp +++ b/lldb/source/API/SBBreakpointLocation.cpp @@ -80,7 +80,7 @@ SBAddress SBBreakpointLocation::GetAddress() { BreakpointLocationSP loc_sp = GetSP(); if (loc_sp) { -return LLDB_RECORD_RESULT(SBAddress(&loc_sp->GetAddress())); +return LLDB_RECORD_RESULT(SBAddress(loc_sp->GetAddress())); } return LLDB_RECORD_RESULT(SBAddress()); @@ -218,8 +218,8 @@ SBError SBBreakpointLocation::SetScriptCallbackFunction( const char *callback_function_name, SBStructuredData &extra_args) { LLDB_RECORD_METHOD(SBError, SBBreakpointLocation, SetScriptCallbackFunction, - (const char *, SBStructuredData &), - callback_function_name, extra_args); + (const char *, SBStructuredData &), callback_function_name, + extra_args); SBError sb_error; BreakpointLocationSP loc_sp = GetSP(); @@ -239,7 +239,7 @@ SBError SBBreakpointLocation::SetScriptCallbackFunction( sb_error.SetError(error); } else sb_error.SetErrorString("invalid breakpoint"); - + return LLDB_RECORD_RESULT(sb_error); } diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp index 81782dbf838f..8f9e426e066e 100644 --- a/lldb/source/API/SBFrame.cpp +++ b/lldb/source/API/SBFrame.cpp @@ -431,7 +431,7 @@ SBAddress SBFrame::GetPCAddress() const { if (stop_locker.TryLock(&process->GetRunLock())) { frame = exe_ctx.GetFramePtr(); if (frame) -sb_addr.SetAddress(&frame->GetFrameCodeAddress()); +sb_addr.SetAddress(frame->GetFrameCodeAddress()); } } return LLDB_RECORD_RESULT(sb_addr); diff --git a/lldb/source/API/SBFunction.cpp b/lldb/source/API/SBFunction.cpp index e49513bd0da5..9f3cf817fc8c 100644 --- a/lldb/source/API/SBFunction.cpp +++ b/lldb/source/API/SBFunction.cpp @@ -152,7 +152,7 @@ SBAd
[Lldb-commits] [PATCH] D88249: [lldb] Make protected ctor and method of SBAddress take a const reference instead of a pointer.
This revision was automatically updated to reflect the committed changes. Closed by commit rG6cd4a4cd02db: [lldb] Pass reference instead of pointer in protected SBAddress methods. (authored by JDevlieghere). Herald added a project: LLDB. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D88249/new/ https://reviews.llvm.org/D88249 Files: lldb/include/lldb/API/SBAddress.h lldb/source/API/SBAddress.cpp lldb/source/API/SBBreakpointLocation.cpp lldb/source/API/SBFrame.cpp lldb/source/API/SBFunction.cpp lldb/source/API/SBInstruction.cpp lldb/source/API/SBLineEntry.cpp lldb/source/API/SBQueueItem.cpp lldb/source/API/SBSymbol.cpp lldb/source/API/SBValue.cpp Index: lldb/source/API/SBValue.cpp === --- lldb/source/API/SBValue.cpp +++ lldb/source/API/SBValue.cpp @@ -1356,7 +1356,7 @@ } } - return LLDB_RECORD_RESULT(SBAddress(new Address(addr))); + return LLDB_RECORD_RESULT(SBAddress(Address(addr))); } lldb::SBData SBValue::GetPointeeData(uint32_t item_idx, uint32_t item_count) { Index: lldb/source/API/SBSymbol.cpp === --- lldb/source/API/SBSymbol.cpp +++ lldb/source/API/SBSymbol.cpp @@ -151,7 +151,7 @@ SBAddress addr; if (m_opaque_ptr && m_opaque_ptr->ValueIsAddress()) { -addr.SetAddress(&m_opaque_ptr->GetAddressRef()); +addr.SetAddress(m_opaque_ptr->GetAddressRef()); } return LLDB_RECORD_RESULT(addr); } @@ -163,7 +163,7 @@ if (m_opaque_ptr && m_opaque_ptr->ValueIsAddress()) { lldb::addr_t range_size = m_opaque_ptr->GetByteSize(); if (range_size > 0) { - addr.SetAddress(&m_opaque_ptr->GetAddressRef()); + addr.SetAddress(m_opaque_ptr->GetAddressRef()); addr->Slide(m_opaque_ptr->GetByteSize()); } } Index: lldb/source/API/SBQueueItem.cpp === --- lldb/source/API/SBQueueItem.cpp +++ lldb/source/API/SBQueueItem.cpp @@ -80,7 +80,7 @@ SBAddress result; if (m_queue_item_sp) { -result.SetAddress(&m_queue_item_sp->GetAddress()); +result.SetAddress(m_queue_item_sp->GetAddress()); } return LLDB_RECORD_RESULT(result); } Index: lldb/source/API/SBLineEntry.cpp === --- lldb/source/API/SBLineEntry.cpp +++ lldb/source/API/SBLineEntry.cpp @@ -56,7 +56,7 @@ SBAddress sb_address; if (m_opaque_up) -sb_address.SetAddress(&m_opaque_up->range.GetBaseAddress()); +sb_address.SetAddress(m_opaque_up->range.GetBaseAddress()); return LLDB_RECORD_RESULT(sb_address); } @@ -66,7 +66,7 @@ SBAddress sb_address; if (m_opaque_up) { -sb_address.SetAddress(&m_opaque_up->range.GetBaseAddress()); +sb_address.SetAddress(m_opaque_up->range.GetBaseAddress()); sb_address.OffsetAddress(m_opaque_up->range.GetByteSize()); } return LLDB_RECORD_RESULT(sb_address); Index: lldb/source/API/SBInstruction.cpp === --- lldb/source/API/SBInstruction.cpp +++ lldb/source/API/SBInstruction.cpp @@ -107,7 +107,7 @@ SBAddress sb_addr; lldb::InstructionSP inst_sp(GetOpaque()); if (inst_sp && inst_sp->GetAddress().IsValid()) -sb_addr.SetAddress(&inst_sp->GetAddress()); +sb_addr.SetAddress(inst_sp->GetAddress()); return LLDB_RECORD_RESULT(sb_addr); } Index: lldb/source/API/SBFunction.cpp === --- lldb/source/API/SBFunction.cpp +++ lldb/source/API/SBFunction.cpp @@ -152,7 +152,7 @@ SBAddress addr; if (m_opaque_ptr) -addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress()); +addr.SetAddress(m_opaque_ptr->GetAddressRange().GetBaseAddress()); return LLDB_RECORD_RESULT(addr); } @@ -163,7 +163,7 @@ if (m_opaque_ptr) { addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize(); if (byte_size > 0) { - addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress()); + addr.SetAddress(m_opaque_ptr->GetAddressRange().GetBaseAddress()); addr->Slide(byte_size); } } Index: lldb/source/API/SBFrame.cpp === --- lldb/source/API/SBFrame.cpp +++ lldb/source/API/SBFrame.cpp @@ -431,7 +431,7 @@ if (stop_locker.TryLock(&process->GetRunLock())) { frame = exe_ctx.GetFramePtr(); if (frame) -sb_addr.SetAddress(&frame->GetFrameCodeAddress()); +sb_addr.SetAddress(frame->GetFrameCodeAddress()); } } return LLDB_RECORD_RESULT(sb_addr); Index: lldb/source/API/SBBreakpointLocation.cpp === --- lldb/source/API/SBBreakpointLocation.cpp +++ lldb/source/API/SBBreakpointLocation.cpp @@ -80,7 +80,7 @@ BreakpointLocationSP loc_sp = GetSP(); if (loc_sp) { -r
[Lldb-commits] [PATCH] D88282: Add support for a "main bin spec" LC_NOTE for standalone/firmware corefile binaries in MachO corefiles
jasonmolenda added a comment. Thanks for the feedback! Comment at: lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp:5567 uuid = UUID::fromOptionalData(raw_uuid, sizeof(uuid_t)); + switch (binspec_type) { + case 0: JDevlieghere wrote: > It seems like this could be outlined into a little static helper function. > Something along the lines of > > ``` > BinaryType GetBinaryType(uint32_t binspec_type); > ``` I don't feel strongly, but all of the "main bin spec" specific knowledge is centralized here in GetCorefileMainBinaryInfo, and converting the constant values this LC_NOTE uses for binary type into the enumerated values seems best kept local to this area. Comment at: lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp:471 + if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { +LLDB_LOGF(log, + "ProcessMachCore::DoLoadCore: Using kernel corefile image " JDevlieghere wrote: > Maybe have a little lambda for the two bodies to reduce the duplication? Yeah, it's not great - but we're checking them in opposite order in the duplicated blocks, so I could make a lambda that did both, but it would need to take an arg about which to prefer and wouldn't be that much better I think. Comment at: lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp:39 +add_uint64(std::vector &buf, uint64_t val) +{ +uint64_buf conv; JDevlieghere wrote: > This does not look clang-formatted 🤐 oh my how did that happen. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D88282/new/ https://reviews.llvm.org/D88282 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 1bec6eb - Add support for firmware/standalone LC_NOTE "main bin spec" corefiles
Author: Jason Molenda Date: 2020-09-25T15:19:22-07:00 New Revision: 1bec6eb3f5cba594698bae5b2789744e0c8ee5f2 URL: https://github.com/llvm/llvm-project/commit/1bec6eb3f5cba594698bae5b2789744e0c8ee5f2 DIFF: https://github.com/llvm/llvm-project/commit/1bec6eb3f5cba594698bae5b2789744e0c8ee5f2.diff LOG: Add support for firmware/standalone LC_NOTE "main bin spec" corefiles When a Mach-O corefile has an LC_NOTE "main bin spec" for a standalone binary / firmware, with only a UUID and no load address, try to locate the binary and dSYM by UUID and if found, load it at offset 0 for the user. Add a test case that tests a firmware/standalone corefile with both the "kern ver str" and "main bin spec" LC_NOTEs. Differential Revision: https://reviews.llvm.org/D88282 Added: lldb/test/API/macosx/lc-note/firmware-corefile/Makefile lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py lldb/test/API/macosx/lc-note/firmware-corefile/bout.mk lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp lldb/test/API/macosx/lc-note/firmware-corefile/main.c Modified: lldb/include/lldb/Symbol/ObjectFile.h lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp Removed: diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h index e814015c0bf7..080724cb86bd 100644 --- a/lldb/include/lldb/Symbol/ObjectFile.h +++ b/lldb/include/lldb/Symbol/ObjectFile.h @@ -91,6 +91,17 @@ class ObjectFile : public std::enable_shared_from_this, eStrataJIT }; + /// If we have a corefile binary hint, this enum + /// specifies the binary type which we can use to + /// select the correct DynamicLoader plugin. + enum BinaryType { +eBinaryTypeInvalid = 0, +eBinaryTypeUnknown, +eBinaryTypeKernel,/// kernel binary +eBinaryTypeUser, /// user process binary +eBinaryTypeStandalone /// standalone binary / firmware + }; + struct LoadableData { lldb::addr_t Dest; llvm::ArrayRef Contents; @@ -500,12 +511,17 @@ class ObjectFile : public std::enable_shared_from_this, /// If the uuid of the binary is specified, this will be set. /// If no UUID is available, will be cleared. /// + /// \param[out] type + /// Return the type of the binary, which will dictate which + /// DynamicLoader plugin should be used. + /// /// \return /// Returns true if either address or uuid has been set. - virtual bool GetCorefileMainBinaryInfo (lldb::addr_t &address, UUID &uuid) { - address = LLDB_INVALID_ADDRESS; - uuid.Clear(); - return false; + virtual bool GetCorefileMainBinaryInfo(lldb::addr_t &address, UUID &uuid, + ObjectFile::BinaryType &type) { +address = LLDB_INVALID_ADDRESS; +uuid.Clear(); +return false; } virtual lldb::RegisterContextSP diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index babe5a384727..f9f27d0ee6c2 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -5519,7 +5519,8 @@ std::string ObjectFileMachO::GetIdentifierString() { return result; } -bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &address, UUID &uuid) { +bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &address, UUID &uuid, +ObjectFile::BinaryType &type) { address = LLDB_INVALID_ADDRESS; uuid.Clear(); ModuleSP module_sp(GetModule()); @@ -5542,24 +5543,43 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &address, UUID &uuid) { // "main bin spec" (main binary specification) data payload is // formatted: //uint32_t version [currently 1] -//uint32_t type [0 == unspecified, 1 == kernel, 2 == user -//process] uint64_t address [ UINT64_MAX if address not -//specified ] uuid_t uuid [ all zero's if uuid not -//specified ] uint32_t log2_pagesize [ process page size in log base -//2, e.g. 4k pages are 12. 0 for unspecified ] +//uint32_t type [0 == unspecified, 1 == kernel, +//2 == user process, 3 == firmware ] +//uint64_t address [ UINT64_MAX if address not specified ] +//uuid_t uuid [ all zero's if uuid not specified ] +//uint32_t log2_pagesize [ process page size in log base +// 2, e.g. 4k pages are 12. +// 0 for unspecified ] +//uint32_t unused[ for alignment ]
[Lldb-commits] [PATCH] D88282: Add support for a "main bin spec" LC_NOTE for standalone/firmware corefile binaries in MachO corefiles
This revision was not accepted when it landed; it landed in state "Needs Review". This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG1bec6eb3f5cb: Add support for firmware/standalone LC_NOTE "main bin spec" corefiles (authored by jasonmolenda). Changed prior to commit: https://reviews.llvm.org/D88282?vs=294244&id=294439#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D88282/new/ https://reviews.llvm.org/D88282 Files: lldb/include/lldb/Symbol/ObjectFile.h lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp lldb/test/API/macosx/lc-note/firmware-corefile/Makefile lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py lldb/test/API/macosx/lc-note/firmware-corefile/bout.mk lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp lldb/test/API/macosx/lc-note/firmware-corefile/main.c Index: lldb/test/API/macosx/lc-note/firmware-corefile/main.c === --- /dev/null +++ lldb/test/API/macosx/lc-note/firmware-corefile/main.c @@ -0,0 +1,2 @@ +#include +int main () { puts ("this is the lc-note test program."); } Index: lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp === --- /dev/null +++ lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp @@ -0,0 +1,347 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// Create an empty corefile with a "kern ver str" LC_NOTE +// or a "main bin spec" LC_NOTE.. +// If an existing binary is given as a 3rd argument on the cmd line, +// the UUID from that binary will be encoded in the corefile. +// Otherwise a pre-set UUID will be put in the corefile that +// is created. + +struct main_bin_spec_payload { + uint32_t version; + uint32_t type; + uint64_t address; + uuid_t uuid; + uint32_t log2_pagesize; + uint32_t unused; +}; + +union uint32_buf { + uint8_t bytebuf[4]; + uint32_t val; +}; + +union uint64_buf { + uint8_t bytebuf[8]; + uint64_t val; +}; + +void add_uint64(std::vector &buf, uint64_t val) { + uint64_buf conv; + conv.val = val; + for (int i = 0; i < 8; i++) +buf.push_back(conv.bytebuf[i]); +} + +void add_uint32(std::vector &buf, uint32_t val) { + uint32_buf conv; + conv.val = val; + for (int i = 0; i < 4; i++) +buf.push_back(conv.bytebuf[i]); +} + +std::vector x86_lc_thread_load_command() { + std::vector data; + add_uint32(data, LC_THREAD);// thread_command.cmd + add_uint32(data, 184); // thread_command.cmdsize + add_uint32(data, x86_THREAD_STATE64); // thread_command.flavor + add_uint32(data, x86_THREAD_STATE64_COUNT); // thread_command.count + add_uint64(data, 0x); // rax + add_uint64(data, 0x0400); // rbx + add_uint64(data, 0x); // rcx + add_uint64(data, 0x); // rdx + add_uint64(data, 0x); // rdi + add_uint64(data, 0x); // rsi + add_uint64(data, 0xff9246e2ba20); // rbp + add_uint64(data, 0xff9246e2ba10); // rsp + add_uint64(data, 0x); // r8 + add_uint64(data, 0x); // r9 + add_uint64(data, 0x); // r10 + add_uint64(data, 0x); // r11 + add_uint64(data, 0xff7f96ce5fe1); // r12 + add_uint64(data, 0x); // r13 + add_uint64(data, 0x); // r14 + add_uint64(data, 0xff9246e2bac0); // r15 + add_uint64(data, 0xff8015a8f6d0); // rip + add_uint64(data, 0x0001); // rflags + add_uint64(data, 0x0002); // cs + add_uint64(data, 0x0003); // fs + add_uint64(data, 0x0004); // gs + return data; +} + +void add_lc_note_kern_ver_str_load_command( +std::vector> &loadcmds, std::vector &payload, +int payload_file_offset, std::string uuid) { + std::string ident = "EFI UUID="; + ident += uuid; + std::vector loadcmd_data; + + add_uint32(loadcmd_data, LC_NOTE); // note_command.cmd + add_uint32(loadcmd_data, 40); // note_command.cmdsize + char lc_note_name[16]; + memset(lc_note_name, 0, 16); + strcpy(lc_note_name, "kern ver str"); + + // lc_note.data_owner + for (int i = 0; i < 16; i++) +loadcmd_data.push_back(lc_note_name[i]); + + // we start writing the payload at payload_file_offset to leave + // room at the start for the header & the load commands. + uint64_t current_payload_offset = payload.size() + payload_file_offset; + + add_uint64(loadcmd_data, current_payload_offset); // not
[Lldb-commits] [PATCH] D88123: Add the ability to write 'target stop-hooks' in Python
This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. jingham marked 5 inline comments as done. Closed by commit rGb65966cff65b: Add the ability to write target stop-hooks using the ScriptInterpreter. (authored by jingham). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D88123/new/ https://reviews.llvm.org/D88123 Files: lldb/bindings/python/python-swigsafecast.swig lldb/bindings/python/python-wrapper.swig lldb/docs/use/python-reference.rst lldb/include/lldb/Interpreter/ScriptInterpreter.h lldb/include/lldb/Symbol/SymbolContext.h lldb/include/lldb/Target/Target.h lldb/source/Commands/CommandObjectTarget.cpp lldb/source/Commands/Options.td lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h lldb/source/Symbol/SymbolContext.cpp lldb/source/Target/Target.cpp lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py lldb/test/API/commands/target/stop-hooks/TestStopHooks.py lldb/test/API/commands/target/stop-hooks/main.c lldb/test/API/commands/target/stop-hooks/stop_hook.py lldb/test/Shell/Commands/Inputs/stop_hook.py lldb/test/Shell/Commands/command-stop-hook-output.test lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp Index: lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp === --- lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp +++ lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp @@ -254,3 +254,17 @@ const lldb::TargetSP &target_sp) { return nullptr; } + +extern "C" void *LLDBSwigPythonCreateScriptedStopHook( +lldb::TargetSP target_sp, const char *python_class_name, +const char *session_dictionary_name, +lldb_private::StructuredDataImpl *args_impl, Status &error) { + return nullptr; +} + +extern "C" bool +LLDBSwigPythonStopHookCallHandleStop(void *implementor, + lldb::ExecutionContextRefSP exc_ctx_sp, + lldb::StreamSP stream) { + return false; +} Index: lldb/test/Shell/Commands/command-stop-hook-output.test === --- /dev/null +++ lldb/test/Shell/Commands/command-stop-hook-output.test @@ -0,0 +1,18 @@ +# RUN: %clang_host -g %S/Inputs/main.c -o %t +# RUN: %lldb %t -O 'command script import %S/Inputs/stop_hook.py' -s %s -o exit | FileCheck %s + +b main +# CHECK-LABEL: b main +# CHECK: Breakpoint 1: where = {{.*}}`main + +target stop-hook add -P stop_hook.stop_handler +# CHECK-LABEL: target stop-hook add -P stop_hook.stop_handler +# CHECK: Stop hook #1 added. + +run +# CHECK-LABEL: run +# CHECK: I did indeed run +# CHECK: Process {{.*}} stopped +# CHECK: stop reason = breakpoint 1 +# CHECK: frame #0: {{.*}}`main at main.c + Index: lldb/test/Shell/Commands/Inputs/stop_hook.py === --- /dev/null +++ lldb/test/Shell/Commands/Inputs/stop_hook.py @@ -0,0 +1,10 @@ +import lldb + +class stop_handler: +def __init__(self, target, extra_args, dict): +self.extra_args = extra_args +self.target = target + +def handle_stop(self, exe_ctx, stream): +stream.Print("I did indeed run\n") +return True Index: lldb/test/API/commands/target/stop-hooks/stop_hook.py === --- /dev/null +++ lldb/test/API/commands/target/stop-hooks/stop_hook.py @@ -0,0 +1,34 @@ +import lldb + +class stop_handler: +def __init__(self, target, extra_args, dict): +self.extra_args = extra_args +self.target = target +self.counter = 0 +ret_val = self.extra_args.GetValueForKey("return_false") +if ret_val: +self.ret_val = False +else: +self.ret_val = True + +def handle_stop(self, exe_ctx, stream): +self.counter += 1 +stream.Print("I have stopped %d times.\n"%(self.counter)) +increment = 1 +value = self.extra_args.GetValueForKey("increment") +if value: +incr_as_str = value.GetStringValue(100) +increment = int(incr_as_str) +else: +stream.Print("Could not find increment in extra_args\n") +frame = exe_ctx.GetFrame() +expression = "g_var += %d"%(increment) +expr_result = frame.EvaluateExpression(expression) +if not expr_result.GetError().Success(): +stream.Print("Error running expression: %s"%(expr_result.GetError().GetCString())) +value = exe_ctx.target.FindFirstGlobalVariable("g_var") +if not value.IsValid(): +stream.Print("Didn't get a valid value for g_var.") +else: +int_val = value.GetValueAsUnsigned
[Lldb-commits] [lldb] b65966c - Add the ability to write target stop-hooks using the ScriptInterpreter.
Author: Jim Ingham Date: 2020-09-25T15:44:55-07:00 New Revision: b65966cff65bfb66de59621347ffd97238d3f645 URL: https://github.com/llvm/llvm-project/commit/b65966cff65bfb66de59621347ffd97238d3f645 DIFF: https://github.com/llvm/llvm-project/commit/b65966cff65bfb66de59621347ffd97238d3f645.diff LOG: Add the ability to write target stop-hooks using the ScriptInterpreter. Differential Revision: https://reviews.llvm.org/D88123 Added: lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py lldb/test/API/commands/target/stop-hooks/stop_hook.py lldb/test/Shell/Commands/Inputs/stop_hook.py lldb/test/Shell/Commands/command-stop-hook-output.test Modified: lldb/bindings/python/python-swigsafecast.swig lldb/bindings/python/python-wrapper.swig lldb/docs/use/python-reference.rst lldb/include/lldb/Interpreter/ScriptInterpreter.h lldb/include/lldb/Symbol/SymbolContext.h lldb/include/lldb/Target/Target.h lldb/source/Commands/CommandObjectTarget.cpp lldb/source/Commands/Options.td lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h lldb/source/Symbol/SymbolContext.cpp lldb/source/Target/Target.cpp lldb/test/API/commands/target/stop-hooks/TestStopHooks.py lldb/test/API/commands/target/stop-hooks/main.c lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp Removed: diff --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig index d5cafbfa67cb..091fc29b1057 100644 --- a/lldb/bindings/python/python-swigsafecast.swig +++ b/lldb/bindings/python/python-swigsafecast.swig @@ -152,3 +152,10 @@ SBTypeToSWIGWrapper (lldb::SBSymbolContext* sym_ctx_sb) { return SWIG_NewPointerObj((void *) sym_ctx_sb, SWIGTYPE_p_lldb__SBSymbolContext, 0); } + +template <> +PyObject* +SBTypeToSWIGWrapper (lldb::SBStream* stream_sb) +{ +return SWIG_NewPointerObj((void *) stream_sb, SWIGTYPE_p_lldb__SBStream, 0); +} diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 516590ed5771..9e84b341d1a6 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -468,6 +468,123 @@ LLDBSwigPythonCallBreakpointResolver return ret_val; } +SWIGEXPORT void * +LLDBSwigPythonCreateScriptedStopHook +( +lldb::TargetSP target_sp, +const char *python_class_name, +const char *session_dictionary_name, +lldb_private::StructuredDataImpl *args_impl, +Status &error +) +{ +if (python_class_name == NULL || python_class_name[0] == '\0') { +error.SetErrorString("Empty class name."); +Py_RETURN_NONE; +} +if (!session_dictionary_name) { + error.SetErrorString("No session dictionary"); + Py_RETURN_NONE; +} + +PyErr_Cleaner py_err_cleaner(true); + +auto dict = +PythonModule::MainModule().ResolveName( +session_dictionary_name); +auto pfunc = +PythonObject::ResolveNameWithDictionary( +python_class_name, dict); + +if (!pfunc.IsAllocated()) { +error.SetErrorStringWithFormat("Could not find class: %s.", + python_class_name); +return nullptr; +} + +lldb::SBTarget *target_val += new lldb::SBTarget(target_sp); + +PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(target_val)); + +lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl); +PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value)); + +PythonObject result = pfunc(target_arg, args_arg, dict); + +if (result.IsAllocated()) +{ +// Check that the handle_stop callback is defined: +auto callback_func = result.ResolveName("handle_stop"); +if (callback_func.IsAllocated()) { + if (auto args_info = callback_func.GetArgInfo()) { +if ((*args_info).max_positional_args < 2) { + error.SetErrorStringWithFormat("Wrong number of args for " + "handle_stop callback, should be 2 (excluding self), got: %d", + (*args_info).max_positional_args); +} else + return result.release(); + } else { +error.SetErrorString("Couldn't get num arguments for handle_stop " + "callback."); + } + return result.release(); +} +else { + error.SetErrorStringWithFormat("Class \"%s\" is missing the required " + "handle_stop callback."); + result.release(); +} +} +Py_RETURN_NONE; +} + +SWIGEXPORT bool +LLDBSwigPythonStopHookCallHandleStop +( +void *implementor, +lldb::ExecutionContextRefSP exc_ctx_sp, +lld
[Lldb-commits] [lldb] 67782a0 - [lldb/bindings] Fix -Wformat after D88123
Author: Fangrui Song Date: 2020-09-25T17:33:12-07:00 New Revision: 67782a0f99c6a792c9d60267d42b21f7335814ba URL: https://github.com/llvm/llvm-project/commit/67782a0f99c6a792c9d60267d42b21f7335814ba DIFF: https://github.com/llvm/llvm-project/commit/67782a0f99c6a792c9d60267d42b21f7335814ba.diff LOG: [lldb/bindings] Fix -Wformat after D88123 Added: Modified: lldb/bindings/python/python-wrapper.swig Removed: diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 9e84b341d1a6..cd326046b421 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -532,7 +532,8 @@ LLDBSwigPythonCreateScriptedStopHook } else { error.SetErrorStringWithFormat("Class \"%s\" is missing the required " - "handle_stop callback."); + "handle_stop callback.", + python_class_name); result.release(); } } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits