[lldb-dev] resolved load addresses vs. unresolved offset addresses

Virgile Bello virgile.bello at gmail.com
Wed Jan 28 17:15:11 PST 2015


Hi,

Sorry, might have noticed that too late, but ran into similar issues when I
did my Win32 experiments.
https://github.com/xen2/lldb/commits/msvc12 (last 7 commits)
Had to:
- Add i686 (probably better to fix it like the way you did though)
- There is also 2 small unwinding related commits. Probably didn't do it
the "right way", but at least it allowed me to properly unwind even inside
Windows API. Not sure if they might help w/ some of your unwind issues.

Hope that helps,
Virgile

On 22 January 2015 at 15:15, Zachary Turner <zturner at google.com> wrote:

> Well, this was a fun one to debug.
>
> There were two issues, both related to triples, but it's probably just
> easiest to show the full codepath that was leading to the failure.
>
> 1) ObjectFilePECOFF didn't recognize the i686 triple, only the i386
> triple, even though they were equivalent.
> 2) Even after it did, Module::GetObjectFile was calling
> ObjectFilePECOFF::GetArchitecture(), which would stomp various fields of
> the triple even if they were known.  And worse, it would stomp them with
> "generic" values, essentially losing information.
> 3) As a result of information lost from the triple,
> ModuleList::GetSharedModule decided it couldn't find a match, and therefore
> the file must not exist.  It tried to make up its own Module, but it was
> missing some fields obviously, and its triple was wrong.
> 4) Ultimately, this leads to PlatformWindows::ResolveExecutable returning
> a triple without the Win32 OS set
> 5) DynamicLoaderWindows::CreateInstance decided it didn't know how to
> handle this process, because it was looking for OS::Win32 in the triple.
> 6) DynamicLoaderStatic responded and said that it did know how to handle
> this module, so it then called DynamicLoaderStatic::DidLaunch which called
> LoadAllImagesAtFileAddresses(), messing up the section list.
>
> I posted a patch up for review here.  http://reviews.llvm.org/D7120
>
>
> On Wed Jan 21 2015 at 6:41:37 PM Zachary Turner <zturner at google.com>
> wrote:
>
>> Maybe i need to defer execution of this code until after we get the
>> initial breakpoint? I'm currently doing it very early, so maybe that
>> confuses things.
>>
>> The way we detect module loads is different on windows than other
>> platforms, so at the moment I'm responding to these events immediately. In
>> this case, I'm calling SetLoadAddress before DoLaunch has returned, so
>> maybe LLDB doesn't expect that.
>>
>> Anyway, this gives me som ideas to play around with tomorrow.
>> On Wed, Jan 21, 2015 at 5:57 PM Zachary Turner <zturner at google.com>
>> wrote:
>>
>>> Looks like it's wrong.  Which is strange, because I've definitely Set
>>> the load address.
>>>
>>> (lldb) image lookup --verbose --address 0x00415086
>>>       Address: expr_test.exe[0x00415086] (expr_test.exe..text + 134)
>>>       Summary: expr_test.exe`main + 70 at expr_test.cpp:29
>>>        Module: file = "d:/testexe/expr_test.exe", arch = "i386"
>>>   CompileUnit: id = {0x00000000}, file = "d:/testexe/expr_test.cpp",
>>> language = "ISO C++:1998"
>>>      Function: id = {0x0000007e}, name = "main", range =
>>> [0x00415040-0x004150c2)
>>>      FuncType: id = {0x0000007e}, decl = expr_test.cpp:24, clang_type =
>>> "int (void)"
>>>        Blocks: id = {0x0000007e}, range = [0x00415040-0x004150c2)
>>>     LineEntry: [0x00415086-0x00415097): d:/testexe/expr_test.cpp:29:3
>>>
>>> (lldb) image dump sections
>>> Dumping sections for 4 modules.
>>> Sections for 'd:\testexe\expr_test.exe' (i386):
>>>   SectID     Type             Load Address
>>> File Off.  File Size  Flags      Section Name
>>>   ---------- ---------------- ---------------------------------------
>>>  ---------- ---------- ---------- ----------------------------
>>>   0x00000001 zero-fill        [0x0000000000401000-0x0000000000402e74)
>>>  0x00000000 0x00000000 0xc0000080 expr_test.exe..bss
>>>   0x00000002 data             [0x0000000000403000-0x00000000004040bc)
>>>  0x00000600 0x00001200 0xc0000040 expr_test.exe..data
>>>   0x00000003 dwarf-abbrev     [0x0000000000405000-0x0000000000405066)
>>>  0x00001800 0x00000200 0x40000040 expr_test.exe..debug_abbrev
>>>   0x00000004 dwarf-info       [0x0000000000406000-0x000000000040609b)
>>>  0x00001a00 0x00000200 0x40000040 expr_test.exe..debug_info
>>>   0x00000005 dwarf-line       [0x0000000000407000-0x0000000000407063)
>>>  0x00001c00 0x00000200 0x40000040 expr_test.exe..debug_line
>>>   0x00000006 dwarf-pubnames   [0x0000000000408000-0x0000000000408038)
>>>  0x00001e00 0x00000200 0x40000040 expr_test.exe..debug_pubnames
>>>   0x00000007 dwarf-pubtypes   [0x0000000000409000-0x000000000040901a)
>>>  0x00002000 0x00000200 0x40000040 expr_test.exe..debug_pubtypes
>>>   0x00000008 dwarf-str        [0x000000000040a000-0x000000000040a063)
>>>  0x00002200 0x00000200 0x40000040 expr_test.exe..debug_str
>>>   0x00000009 data             [0x000000000040b000-0x000000000040b8b5)
>>>  0x00002400 0x00000a00 0x40000040 expr_test.exe..idata
>>>   0x0000000a data             [0x000000000040c000-0x000000000040c0f4)
>>>  0x00002e00 0x00000200 0x40000040 expr_test.exe..idata.a⌠
>>>   0x0000000b data             [0x000000000040d000-0x000000000040d028)
>>>  0x00003000 0x00000200 0x40000040 expr_test.exe..idata.d(
>>>   0x0000000c data             [0x000000000040e000-0x000000000040e0f4)
>>>  0x00003200 0x00000200 0x40000040 expr_test.exe..idata.t⌠
>>>   0x0000000d data             [0x000000000040f000-0x000000000040f048)
>>>  0x00003400 0x00000200 0x40000040 expr_test.exe..loadcfgH
>>>   0x0000000e data             [0x0000000000410000-0x0000000000413cec)
>>>  0x00003600 0x00003e00 0x40000040 expr_test.exe..rdata
>>>   0x0000000f data             [0x0000000000414000-0x0000000000414068)
>>>  0x00007400 0x00000200 0x40000040 expr_test.exe..sxdata
>>>   0x00000010 code             [0x0000000000415000-0x0000000000420168)
>>>  0x00007600 0x0000b200 0x60000020 expr_test.exe..text
>>>   0x00000011 data             [0x0000000000421000-0x0000000000421314)
>>>  0x00012800 0x00000400 0x40000040 expr_test.exe..xdata
>>>   0x00000012 regular          [0x0000000000422000-0x0000000000422d54)
>>>  0x00012c00 0x00000e00 0x42000040 expr_test.exe..reloc
>>> Sections for 'C:\Windows\SysWOW64\ntdll.dll' (i386):
>>>   SectID     Type             Load Address
>>> File Off.  File Size  Flags      Section Name
>>>   ---------- ---------------- ---------------------------------------
>>>  ---------- ---------- ---------- ----------------------------
>>>   0x00000001 code             [0x000000006b281000-0x000000006b3765d3)
>>>  0x00000400 0x000f5600 0x60000020 ntdll.dll..text
>>>   0x00000002 code             [0x000000006b377000-0x000000006b377198)
>>>  0x000f5a00 0x00000200 0x60000020 ntdll.dll.RT
>>>   0x00000003 data             [0x000000006b378000-0x000000006b37da38)
>>>  0x000f5c00 0x00004600 0xc0000040 ntdll.dll..data
>>>   0x00000004 data             [0x000000006b37e000-0x000000006b37e24c)
>>>  0x000fa200 0x00000400 0xc0000040 ntdll.dll..mrdata
>>>   0x00000005 data             [0x000000006b37f000-0x000000006b3e1450)
>>>  0x000fa600 0x00062600 0x40000040 ntdll.dll..rsrc
>>>   0x00000006 regular          [0x000000006b3e2000-0x000000006b3e623c)
>>>  0x0015cc00 0x00004400 0x42000040 ntdll.dll..reloc
>>> Sections for 'C:\Windows\SysWOW64\kernel32.dll' (i386):
>>>   SectID     Type             Load Address
>>> File Off.  File Size  Flags      Section Name
>>>   ---------- ---------------- ---------------------------------------
>>>  ---------- ---------- ---------- ----------------------------
>>>   0x00000001 code             [0x000000006b810000-0x000000006b871fd5)
>>>  0x00001000 0x00062000 0x60000020 kernel32.dll..text
>>>   0x00000002 data             [0x000000006b880000-0x000000006b8fd4be)
>>>  0x00063000 0x0007e000 0x40000040 kernel32.dll..rdata
>>>   0x00000003 data             [0x000000006b900000-0x000000006b900bfc)
>>>  0x000e1000 0x00001000 0xc0000040 kernel32.dll..data
>>>   0x00000004 data             [0x000000006b910000-0x000000006b910520)
>>>  0x000e2000 0x00001000 0x40000040 kernel32.dll..rsrc
>>>   0x00000005 regular          [0x000000006b920000-0x000000006b939352)
>>>  0x000e3000 0x0001a000 0x42000040 kernel32.dll..reloc
>>> Sections for 'C:\Windows\SysWOW64\KernelBase.dll' (i386):
>>>   SectID     Type             Load Address
>>> File Off.  File Size  Flags      Section Name
>>>   ---------- ---------------- ---------------------------------------
>>>  ---------- ---------- ---------- ----------------------------
>>>   0x00000001 code             [0x0000000010001000-0x00000000100bd690)
>>>  0x00000400 0x000bc800 0x60000020 KernelBase.dll..text
>>>   0x00000002 data             [0x00000000100be000-0x00000000100c0cc8)
>>>  0x000bcc00 0x00002200 0xc0000040 KernelBase.dll..data
>>>   0x00000003 data             [0x00000000100c1000-0x00000000100c589a)
>>>  0x000bee00 0x00004a00 0x40000040 KernelBase.dll..idata
>>>   0x00000004 data             [0x00000000100c6000-0x00000000100c9528)
>>>  0x000c3800 0x00003600 0x40000040 KernelBase.dll..rsrc
>>>   0x00000005 regular          [0x00000000100ca000-0x00000000100cfa1c)
>>>  0x000c6e00 0x00005c00 0x42000040 KernelBase.dll..reloc
>>>
>>>
>>> If you remember back to the discussion about dynamic loaders earlier, we
>>> decided I didn't really need a dynamic loader because Windows just tells
>>> you straightforwardly exactly when DLLs load, and the exact load address.
>>> In fact, it looks like the load addresses for the dlls might even be
>>> correct (I need to verify this tomorrow using a different debugger to make
>>> sure they match).
>>>
>>> So it might just be the EXE that's wrong.  But I stepped through it in a
>>> debugger, and it's setting the load address to the correct value and
>>> calling ModulesDidLoad().  Do I need to use something other than the
>>> following code snippet for the main EXE module?
>>>
>>>     // Either we successfully attached to an existing process, or we
>>> successfully launched a new
>>>     // process under the debugger.
>>>     ModuleSP module = GetTarget().GetExecutableModule();
>>>     bool load_addr_changed;
>>>     module->SetLoadAddress(GetTarget(), image_base, false,
>>> load_addr_changed);
>>>
>>>     // Notify the target that the executable module has loaded.  This
>>> will cause any pending
>>>     // breakpoints to be resolved to explicit brekapoint sites.
>>>     ModuleList loaded_modules;
>>>     loaded_modules.Append(module);
>>>     GetTarget().ModulesDidLoad(loaded_modules);
>>>
>>> Something is working, because I can hit a breakpoint that I set by
>>> source and line number which resolves to an address in the executable
>>> module.
>>>
>>> On Wed Jan 21 2015 at 5:48:31 PM Greg Clayton <gclayton at apple.com>
>>> wrote:
>>>
>>>> Sounds like your dynamic loader is doing the wrong thing.
>>>>
>>>> What does the output of:
>>>>
>>>> (lldb) image dump sections
>>>>
>>>> What does this show? My guess if you might have overlapping sections.
>>>> You can also get info on an address by doing:
>>>>
>>>> (lldb) image lookup --verbose --address 0x00415086
>>>>
>>>> This will show you which section it thinks it resolved to and also what
>>>> debug symbols.
>>>>
>>>> On MacOSX we had issues where we had images in memory where one of the
>>>> sections wasn't really getting loaded, but we said it was (dynamic loader
>>>> error). So we had a file a.dylib:
>>>>
>>>>
>>>> a.dylib whose __TEXT section had a load addr range [0x0000 - 0x1000)
>>>> a.dylib whose __DATA section had a load addr range [0x1000 - 0x2000)
>>>> a.dylib whose __LINKEDIT section had a load addr range [0x2000 - 0x3000)
>>>>
>>>> But __LINKEDIT wasn't actually being mapped by the kernel, and we then
>>>> had:
>>>>
>>>> b.dylib whose __TEXT section had a load addr range [0x2000 - 0x3000)
>>>> b.dylib whose __DATA section had a load addr range [0x3000 - 0x4000)
>>>> b.dylib whose __LINKEDIT section had a load addr range [0x4000 - 0x5000)
>>>>
>>>> Note that a.dylib.__LINKEDIT overlaps with b.dylib. __TEXT.
>>>>
>>>> We fixed the dynamic loader to not slide _all_ sections, just the ones
>>>> that were loaded, so the map actually was:
>>>>
>>>>
>>>> a.dylib whose __TEXT section had a load addr range [0x0000 - 0x1000)
>>>> a.dylib whose __DATA section had a load addr range [0x1000 - 0x2000)
>>>> a.dylib whose __LINKEDIT not loaded in process
>>>>
>>>> But __LINKEDIT wasn't actually being mapped by the kernel, and we then
>>>> had:
>>>>
>>>> b.dylib whose __TEXT section had a load addr range [0x2000 - 0x3000)
>>>> b.dylib whose __DATA section had a load addr range [0x3000 - 0x4000)
>>>> b.dylib whose __LINKEDIT not loaded in process
>>>>
>>>> Then our address lookups all worked. Just a guess as to what might be
>>>> happening.
>>>>
>>>> Greg
>>>>
>>>>
>>>>
>>>> > On Jan 21, 2015, at 5:09 PM, Zachary Turner <zturner at google.com>
>>>> wrote:
>>>> >
>>>> > So I think my problem with stack unwinding and thread step-over (or
>>>> my immediate problem anyway) is somewhat unrelated to the long discussion
>>>> we had earlier, and is much simpler.
>>>> >
>>>> > (lldb) Process 9140 stopped
>>>> > * thread #1: tid = 0x2ef8, 0x00415086 expr_test.exe`main + 70 at
>>>> expr_test.cpp:29, stop reason = breakpoint 1.1
>>>> >     frame #0: 0x00415086 expr_test.exe`main + 70 at expr_test.cpp:29
>>>> >
>>>> > The address given here is 0x415086.  And indeed, if I disassemble
>>>> this address, I see actual code.
>>>> >
>>>> > invalid command 'frame #0:'
>>>> > (lldb) dis -n main -F intel
>>>> > ...
>>>> > -> 0x415086 <main+70>: mov    dword ptr [esp], ecx
>>>> >    0x415089 <main+73>: mov    dword ptr [ebp - 0xc], eax
>>>> >    0x41508c <main+76>: call   0x4150d7
>>>> >
>>>> > (lldb) dis -s 0x415086 -F intel
>>>> > -> 0x415086 <main+70>: mov    dword ptr [esp], ecx
>>>> >    0x415089 <main+73>: mov    dword ptr [ebp - 0xc], eax
>>>> >    0x41508c <main+76>: call   0x4150d7
>>>> >    0x415091 <main+81>: lea    ecx, [0x41006e]
>>>> >    0x415097 <main+87>: mov    dword ptr [esp], ecx
>>>> >    0x41509a <main+90>: mov    dword ptr [ebp - 0x10], eax
>>>> >    0x41509d <main+93>: call   0x4150d7
>>>> >
>>>> > But when I try to set a breakpoint at that address, bad stuff happens:
>>>> > (lldb) break set -a 0x415086
>>>> > warning: failed to set breakpoint site at 0x415086 for breakpoint
>>>> 2.1: Unable to read memory at breakpoint address.
>>>> > Breakpoint 2: where = expr_test.exe`main + 70 at expr_test.cpp:29,
>>>> address = 0x00415086
>>>> >
>>>> > I modified the source of my program to print out the image base and
>>>> the address of main at startup by adding these two lines:
>>>> >
>>>> >   printf("main = 0x%p\n", main);
>>>> >   printf("_ImageBase = 0x%p", &__ImageBase);
>>>> >
>>>> > And this prints out the following:
>>>> > main = 0x00AE5040
>>>> > _ImageBase = 0x00AD0000
>>>> >
>>>> > Note that the address of main printed by my program is quite far off
>>>> from the address reported by LLDB.
>>>> >
>>>> > If I run llvm-readobj on my COFF file, I see this:
>>>> >
>>>> >   BaseOfCode: 0x15000
>>>> >   ImageBase: 0x400000
>>>> >
>>>> > Adding these two together, I get 0x415000, which is only 0x86 bytes
>>>> away from what LLDB Is reporting as the instruction I'm broken at.
>>>> >
>>>> > So, in short: It's not taking into account the load address of the
>>>> executable module.
>>>> >
>>>> > I checked my process plugin, and when the debugger connects to the
>>>> process, it does get the load address which is 0x00AD0000 and it create a
>>>> ModuleSP for it, it calls SetLoadAddress, and then it calls ModulesDidLoad.
>>>> >
>>>> > But in the end, some part of LLDB still isn't happy.
>>>> >
>>>> > How this all relates to thread step-over is that LLDB is trying to
>>>> set an address breakpoint on a 0x415xxx address, which is only a RVA that
>>>> needs to be added to the load address.
>>>> >
>>>> > I must be missing a step somewhere, but I'm not quite sure what.
>>>> > _______________________________________________
>>>> > lldb-dev mailing list
>>>> > lldb-dev at cs.uiuc.edu
>>>> > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>>>>
>>>>
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20150129/1497f7f4/attachment.html>


More information about the lldb-dev mailing list