diff options
author | Greg Clayton <gclayton@apple.com> | 2012-07-11 22:18:24 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2012-07-11 22:18:24 +0000 |
commit | c3a86bf9f0e774b68b41582937a076d6706f1d30 (patch) | |
tree | e509ab7f6dcd2305671a7af9efbe086167b1e745 | |
parent | 570ae0b1f73f1c2d710648289b4b1088960cf010 (diff) | |
download | bcm5719-llvm-c3a86bf9f0e774b68b41582937a076d6706f1d30.tar.gz bcm5719-llvm-c3a86bf9f0e774b68b41582937a076d6706f1d30.zip |
Modifying the "address" format, which prints a pointer and a description of what it points to, to detect when the deref of that pointer points to something valid. So if you have:
% cat sp.cpp
#include <tr1/memory>
class A
{
public:
A (): m_i (12) {}
virtual ~A() {}
private:
int m_i;
};
int main (int argc, char const *argv[], char const *envp[])
{
A *a_pointers[2] = { NULL, NULL };
A a1;
A a2;
a_pointers[0] = &a1;
a_pointers[1] = &a2;
return 0;
}
And you stop at the "return 0", you can now read memory using the "address" format and see:
(lldb) memory read --format address `&a_pointers`
0x7fff5fbff870: 0x00007fff5fbff860 -> 0x00000001000010b0 vtable for A + 16
0x7fff5fbff878: 0x00007fff5fbff850 -> 0x00000001000010b0 vtable for A + 16
0x7fff5fbff880: 0x00007fff5fbff8d0
0x7fff5fbff888: 0x00007fff5fbff8c0
0x7fff5fbff890: 0x0000000000000001
0x7fff5fbff898: 0x36d54c275add2294
0x7fff5fbff8a0: 0x00007fff5fbff8b0
0x7fff5fbff8a8: 0x0000000100000bb4 a.out`start + 52
Note the extra dereference that was applied to 0x00007fff5fbff860 and 0x00007fff5fbff850 so we can see that these are "A" classes.
llvm-svn: 160085
-rw-r--r-- | lldb/include/lldb/Core/Address.h | 4 | ||||
-rw-r--r-- | lldb/source/Core/Address.cpp | 36 | ||||
-rw-r--r-- | lldb/source/Core/DataExtractor.cpp | 21 |
3 files changed, 51 insertions, 10 deletions
diff --git a/lldb/include/lldb/Core/Address.h b/lldb/include/lldb/Core/Address.h index 423bafa69c4..6a97e87b87c 100644 --- a/lldb/include/lldb/Core/Address.h +++ b/lldb/include/lldb/Core/Address.h @@ -86,8 +86,10 @@ public: ///< and file and line), to information about what the pointer points to ///< if the address is in a section (section of pointers, c strings, etc). DumpStyleResolvedDescriptionNoModule, - DumpStyleDetailedSymbolContext ///< Detailed symbol context information for an address for all symbol + DumpStyleDetailedSymbolContext, ///< Detailed symbol context information for an address for all symbol ///< context members. + DumpStyleResolvedPointerDescription ///< Dereference a pointer at the current address and then lookup the + ///< dereferenced address using DumpStyleResolvedDescription } DumpStyle; //------------------------------------------------------------------ diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp index e4dc06312f3..0308812bc56 100644 --- a/lldb/source/Core/Address.cpp +++ b/lldb/source/Core/Address.cpp @@ -354,9 +354,10 @@ Address::SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target) bool Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const { - // If the section was NULL, only load address is going to work. + // If the section was NULL, only load address is going to work unless we are + // trying to deref a pointer SectionSP section_sp (GetSection()); - if (!section_sp) + if (!section_sp && style != DumpStyleResolvedPointerDescription) style = DumpStyleLoadAddress; ExecutionContext exe_ctx (exe_scope); @@ -728,6 +729,37 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum return false; } break; + case DumpStyleResolvedPointerDescription: + { + Process *process = exe_ctx.GetProcessPtr(); + if (process) + { + addr_t load_addr = GetLoadAddress (target); + if (load_addr != LLDB_INVALID_ADDRESS) + { + Error memory_error; + addr_t dereferenced_load_addr = process->ReadPointerFromMemory(load_addr, memory_error); + if (dereferenced_load_addr != LLDB_INVALID_ADDRESS) + { + Address dereferenced_addr; + if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr, target)) + { + StreamString strm; + if (dereferenced_addr.Dump (&strm, exe_scope, DumpStyleResolvedDescription, DumpStyleInvalid, addr_size)) + { + s->Address (dereferenced_load_addr, addr_size, " -> ", " "); + s->Write(strm.GetData(), strm.GetSize()); + return true; + } + } + } + } + } + if (fallback_style != DumpStyleInvalid) + return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); + return false; + } + break; } return true; diff --git a/lldb/source/Core/DataExtractor.cpp b/lldb/source/Core/DataExtractor.cpp index da52be8d865..24d1dc12c27 100644 --- a/lldb/source/Core/DataExtractor.cpp +++ b/lldb/source/Core/DataExtractor.cpp @@ -1737,14 +1737,21 @@ DataExtractor::Dump (Stream *s, { TargetSP target_sp (exe_scope->CalculateTarget()); lldb_private::Address so_addr; - if (target_sp && target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) + if (target_sp) { - s->PutChar(' '); - so_addr.Dump (s, - exe_scope, - Address::DumpStyleResolvedDescription, - Address::DumpStyleModuleWithFileAddress); - break; + if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) + { + s->PutChar(' '); + so_addr.Dump (s, + exe_scope, + Address::DumpStyleResolvedDescription, + Address::DumpStyleModuleWithFileAddress); + } + else + { + so_addr.SetOffset(addr); + so_addr.Dump (s, exe_scope, Address::DumpStyleResolvedPointerDescription); + } } } } |