From e91b7957b2d4ea2c880b303e543c711566cb7cd0 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Thu, 15 Dec 2011 03:14:23 +0000 Subject: [PATCH] Expose new read memory fucntion through python in SBProcess: size_t SBProcess::ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBError &error); uint64_t SBProcess::ReadUnsignedFromMemory (addr_t addr, uint32_t byte_size, lldb::SBError &error); lldb::addr_t SBProcess::ReadPointerFromMemory (addr_t addr, lldb::SBError &error); These ReadCStringFromMemory() has some SWIG type magic that makes it return the python string directly and the "buf" is not needed: error = SBError() max_cstr_len = 256 cstr = lldb.process.ReadCStringFromMemory (0x1000, max_cstr_len, error) if error.Success(): .... The other two functions behave as expteced. This will make it easier to get integer values from the inferior process that are correctly byte swapped. Also for pointers, the correct pointer byte size will be used. Also cleaned up a few printf style warnings for the 32 bit lldb build on darwin. llvm-svn: 146636 --- lldb/include/lldb/API/SBProcess.h | 9 ++++ lldb/include/lldb/Target/Process.h | 3 +- lldb/scripts/Python/interface/SBProcess.i | 51 ++++++++++++++++++ lldb/source/API/SBProcess.cpp | 54 +++++++++++++++++++ lldb/source/Host/macosx/Host.mm | 14 ++--- .../MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp | 9 ++-- .../AppleObjCRuntime/AppleObjCRuntime.cpp | 3 +- .../AppleObjCRuntime/AppleObjCRuntimeV2.cpp | 9 ++-- lldb/source/Target/Process.cpp | 11 +++- 9 files changed, 146 insertions(+), 17 deletions(-) diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index e126dbcada39..2a9e396be61e 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -155,6 +155,15 @@ public: size_t WriteMemory (addr_t addr, const void *buf, size_t size, lldb::SBError &error); + size_t + ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBError &error); + + uint64_t + ReadUnsignedFromMemory (addr_t addr, uint32_t byte_size, lldb::SBError &error); + + lldb::addr_t + ReadPointerFromMemory (addr_t addr, lldb::SBError &error); + // Events static lldb::StateType GetStateFromEvent (const lldb::SBEvent &event); diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 843300d0692f..730422abf74c 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -2373,7 +2373,8 @@ public: size_t ReadCStringFromMemory (lldb::addr_t vm_addr, char *cstr, - size_t cstr_max_len); + size_t cstr_max_len, + Error &error); size_t ReadMemoryFromInferior (lldb::addr_t vm_addr, diff --git a/lldb/scripts/Python/interface/SBProcess.i b/lldb/scripts/Python/interface/SBProcess.i index b2ab9231a264..920aefb4c80d 100644 --- a/lldb/scripts/Python/interface/SBProcess.i +++ b/lldb/scripts/Python/interface/SBProcess.i @@ -208,6 +208,57 @@ public: size_t WriteMemory (addr_t addr, const void *buf, size_t size, lldb::SBError &error); + %feature("autodoc", " + Reads a NULL terminated C string from the current process's address space. + It returns a python string of the exact length, or truncates the string if + the maximum character limit is reached. Example: + + # Read a C string of at most 256 bytes from address '0x1000' + error = lldb.SBError() + cstring = process.ReadMemory(0x1000, 256, error) + if error.Success(): + print 'cstring: ', cstring + else + print 'error: ', error + ") ReadCStringFromMemory; + + size_t + ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBError &error); + + %feature("autodoc", " + Reads an unsigned integer from memory given a byte size and an address. + Returns the unsigned integer that was read. Example: + + # Read a 4 byte unsigned integer from address 0x1000 + error = lldb.SBError() + uint = ReadUnsignedFromMemory(0x1000, 4, error) + if error.Success(): + print 'integer: %u' % uint + else + print 'error: ', error + + ") ReadUnsignedFromMemory; + + uint64_t + ReadUnsignedFromMemory (addr_t addr, uint32_t byte_size, lldb::SBError &error); + + %feature("autodoc", " + Reads a pointer from memory from an address and returns the value. Example: + + # Read a pointer from address 0x1000 + error = lldb.SBError() + ptr = ReadPointerFromMemory(0x1000, error) + if error.Success(): + print 'pointer: 0x%x' % ptr + else + print 'error: ', error + + ") ReadPointerFromMemory; + + lldb::addr_t + ReadPointerFromMemory (addr_t addr, lldb::SBError &error); + + // Events static lldb::StateType GetStateFromEvent (const lldb::SBEvent &event); diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp index ce8109fa0905..89932a37208e 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -765,6 +765,60 @@ SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error return bytes_read; } +size_t +SBProcess::ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBError &sb_error) +{ + size_t bytes_read = 0; + if (m_opaque_sp) + { + Error error; + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + bytes_read = m_opaque_sp->ReadCStringFromMemory (addr, (char *)buf, size, error); + sb_error.SetError (error); + } + else + { + sb_error.SetErrorString ("SBProcess is invalid"); + } + return bytes_read; +} + +uint64_t +SBProcess::ReadUnsignedFromMemory (addr_t addr, uint32_t byte_size, lldb::SBError &sb_error) +{ + if (m_opaque_sp) + { + Error error; + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + uint64_t value = m_opaque_sp->ReadUnsignedIntegerFromMemory (addr, byte_size, 0, error); + sb_error.SetError (error); + return value; + } + else + { + sb_error.SetErrorString ("SBProcess is invalid"); + } + return 0; +} + +lldb::addr_t +SBProcess::ReadPointerFromMemory (addr_t addr, lldb::SBError &sb_error) +{ + lldb::addr_t ptr = LLDB_INVALID_ADDRESS; + if (m_opaque_sp) + { + Error error; + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + ptr = m_opaque_sp->ReadPointerFromMemory (addr, error); + sb_error.SetError (error); + } + else + { + sb_error.SetErrorString ("SBProcess is invalid"); + } + return ptr; +} + size_t SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &sb_error) { diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm index de6929d68c6b..ac036e4a68b5 100644 --- a/lldb/source/Host/macosx/Host.mm +++ b/lldb/source/Host/macosx/Host.mm @@ -657,7 +657,7 @@ Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) if (log) log->Printf("Sending source file: \"%s\" and line: %d to external editor.\n", file_path, line_no); - OSStatus error; + long error; BabelAESelInfo file_and_line_info = { 0, // reserved0 @@ -678,7 +678,7 @@ Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) if (error != noErr) { if (log) - log->Printf("Error creating AEDesc: %d.\n", error); + log->Printf("Error creating AEDesc: %ld.\n", error); return false; } @@ -713,7 +713,7 @@ Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) if (error != noErr) { if (log) - log->Printf("Could not find External Editor application, error: %d.\n", error); + log->Printf("Could not find External Editor application, error: %ld.\n", error); return false; } @@ -735,7 +735,7 @@ Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) if (error != noErr) { if (log) - log->Printf("LSOpenURLsWithRole failed, error: %d.\n", error); + log->Printf("LSOpenURLsWithRole failed, error: %ld.\n", error); return false; } @@ -750,7 +750,7 @@ Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) if (error != noErr) { if (log) - log->Printf("GetProcessInformation failed, error: %d.\n", error); + log->Printf("GetProcessInformation failed, error: %ld.\n", error); using_xcode = false; } else @@ -807,7 +807,7 @@ Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) if (error != noErr) { if (log) - log->Printf("Failed to create AEDesc for Xcode AppleEvent: %d.\n", error); + log->Printf("Failed to create AEDesc for Xcode AppleEvent: %ld.\n", error); return false; } @@ -825,7 +825,7 @@ Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) if (error != noErr) { if (log) - log->Printf("Sending AppleEvent to Xcode failed, error: %d.\n", error); + log->Printf("Sending AppleEvent to Xcode failed, error: %ld.\n", error); return false; } } diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index b2b40c9d2c6c..2b5efab3489e 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -918,10 +918,13 @@ DynamicLoaderMacOSXDYLD::ReadImageInfos (lldb::addr_t image_infos_addr, image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset); char raw_path[PATH_MAX]; - m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path)); + m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path), error); // don't resolve the path - const bool resolve_path = false; - image_infos[i].file_spec.SetFile(raw_path, resolve_path); + if (error.Success()) + { + const bool resolve_path = false; + image_infos[i].file_spec.SetFile(raw_path, resolve_path); + } } return true; } diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index e614edf4be90..d584cb28d9ee 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp @@ -145,7 +145,8 @@ AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionCon size_t curr_len = full_buffer_len; while (curr_len == full_buffer_len) { - curr_len = process->ReadCStringFromMemory(result_ptr + cstr_len, buf, sizeof(buf)); + Error error; + curr_len = process->ReadCStringFromMemory(result_ptr + cstr_len, buf, sizeof(buf), error); strm.Write (buf, curr_len); cstr_len += curr_len; } diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 5442acd4b85e..ae6466803c78 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -220,10 +220,11 @@ AppleObjCRuntimeV2::RunFunctionToFindClassName(addr_t object_addr, Thread *threa } addr_t result_ptr = void_ptr_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); - size_t chars_read = m_process->ReadCStringFromMemory (result_ptr, name_dst, max_name_len); + Error error; + size_t chars_read = m_process->ReadCStringFromMemory (result_ptr, name_dst, max_name_len, error); // If we exhausted our buffer before finding a NULL we're probably off in the weeds somewhere... - if (chars_read == max_name_len) + if (error.Fail() || chars_read == max_name_len) return false; else return true; @@ -686,8 +687,8 @@ AppleObjCRuntimeV2::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa) return g_unknown; //printf("name_pointer: %llx\n", name_pointer); - char* cstr = new char[512]; - if (m_process->ReadCStringFromMemory(name_pointer, cstr, 512) > 0) + char cstr[512]; + if (m_process->ReadCStringFromMemory(name_pointer, cstr, sizeof(cstr), error) > 0) { if (::strstr(cstr, "NSKVONotify") == cstr) { diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index a138f59f6ce3..fdd6b1753c7f 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -1856,11 +1856,12 @@ Process::ReadMemory (addr_t addr, void *buf, size_t size, Error &error) size_t -Process::ReadCStringFromMemory (addr_t addr, char *dst, size_t dst_max_len) +Process::ReadCStringFromMemory (addr_t addr, char *dst, size_t dst_max_len, Error &result_error) { size_t total_cstr_len = 0; if (dst && dst_max_len) { + result_error.Clear(); // NULL out everything just to be safe memset (dst, 0, dst_max_len); Error error; @@ -1877,6 +1878,7 @@ Process::ReadCStringFromMemory (addr_t addr, char *dst, size_t dst_max_len) if (bytes_read == 0) { + result_error = error; dst[total_cstr_len] = '\0'; break; } @@ -1892,6 +1894,13 @@ Process::ReadCStringFromMemory (addr_t addr, char *dst, size_t dst_max_len) bytes_left -= bytes_read; } } + else + { + if (dst == NULL) + result_error.SetErrorString("invalid arguments"); + else + result_error.Clear(); + } return total_cstr_len; }