[lldb-dev] debug server help

Greg Clayton gclayton at apple.com
Mon Sep 17 14:23:43 PDT 2012

On Sep 17, 2012, at 12:11 PM, Carlo Kok <ck at remobjects.com> wrote:

> Op 17-9-2012 19:31, Greg Clayton schreef:
>>> Cool, that worked, got it starting, continuing, and fininsh now.
>>> Only can't get it to break. It doesn't resolve the address of _main
>>> or main, even though at this point the a.out is loaded on both the
>>> server and client, I stepped through it,
>> Does this have anything to do with the windows paths?
>> "\\path\\a.out"? See comments below.
> the path on the "caller" does not exactly match the "server" no (can't really; windows is quite different). Any way to make that work? (I know what local path will match the server path)
>>> when setting the BP, inside: size_t ObjectFileMachO::ParseSymtab
>>> (bool minimize)
>>> "process" is null so it never seems to find any symbols.
>> ObjectFile subclasses usually read their contents from disk, not from
>> a process. If there is no file on disk, then LLDB will make a memory
>> based ObjectFile that reads its data from memory, then the m_process
>> will be valid. So the process is only needed if you are reading your
>> object file from memory. Unless you have a complete local copy of
>> your remote Mac system, you will end up with a lot of these, but I am
>> guessing you have at least a local copy of your main executable
>> "\path\a.out" right? One problem you might run into as well is all
>> the paths in the DWARF debug info will use the "/path/a.out" style
>> paths. I am not sure how much of this file system path stuff was
>> modified in the windows port, but it will be essential to get this
>> done right, so no matter what kind of path is supplied, that things
>> "just work".
> my DWARF files will have Windows paths (as that's where I compile from).
>>> Using this:
>>> m_debugger = SBDebugger::Create(false);
>>> m_target = m_debugger.CreateTarget ("\\path\\a.out",
>>> "x86_64-apple-macosx", NULL, true, m_error);
>> Now that you have a target, you will want to verify that things
>> actually got loaded and that LLDB was able to parse your object file
>> "\path\a.out". Try this code just after the above line that creates
>> the m_target:
>> SBModule module (m_target.FindModule(m_target.GetExecutable ())); if
>> (module.IsValid()) { SBSymbol symbol; const uint32_t num_symbols =
>> module.GetNumSymbols(); for (uint32_t i=0; i<num_symbols; ++i) {
>> symbol = module.GetSymbolAtIndex (i); printf ("symbol[%u] 0x%16.16llx
>> %s\n", i, symbol.GetName(),
>> symbol.GetStartAddress().GetFileAddress()); } }
>> After you create your target, should _should_ have a valid symbol
>> table for your main executable. If you don't you will want to debug
>> info the "module.GetNumSymbols();" code (which will parse the symbol
>> table if it already hasn't been). You might need to debug info the
>> "m_debugger.CreateTarget()" and watch it try to create a module with
>> your "\\path\\a.out" and make sure it succeeds.
> symbol[0] 0xffffffffffffffff /Users/ck/test.m
> symbol[1] 0xffffffffffffffff /var/folders/f8/pr_1fjyd1rs8p8pn_2v488j00000gn/T/te
> st-NhmVzr.o
> symbol[2] 0x0000000100000f30 main
> symbol[3] 0x0000000100000000 _mh_execute_header
> symbol[4] 0x0000000100000f56 printf
> symbol[5] 0xffffffffffffffff dyld_stub_binder
> Indeed, it loads


>>> m_process = m_target.ConnectRemote(SBListener(),
>>> "connect://", NULL, m_error);
>>> SBBreakpoint bp = m_target.BreakpointCreateByName("_main");
>>> SBCommandReturnObject o; m_commandline.HandleCommand("breakpoint
>>> list", o); << shows as not bound yet.
>>> What am I missing?
>> Don't add the underscore. The underscore is stripped as the symbols
>> are added to the symbol table. If you notice, all C++ symbols start
>> with "__Z..." (two underscores), when mangled names should only have
>> 1 underscore. So we normalize the names for you so they are in the
>> format you would expect. Again, it sounds like we just are not
>> parsing your object file.
> Oke.
>> You might try having the program you run on MacOSX run to your main
>> function and pause for 20 seconds while you then attach on windows.
>> This will allow the process to get up and loaded and already have a
>> bunch of shared libraries loaded. There might be issues with
>> attaching to a process that is stopped at __dyld_start (which is what
>> happens when you have debugserver debug an app: it starts the program
>> stopped before it runs ANY code, so _nothing_ is loaded). If you
>> attach after the shared libraries have loaded, we might be able to
>> resolve symbols. Give that a try and let me know how things go.
>> After you attach to a running program, try doing the following code:
>> uint32_t num_modules = m_target.GetNumModules (); for (uint32_t i=0;
>> i< num_modules; ++i) { module =  m_target.GetModuleAtIndex (i);
>> printf ("module[%u] %s %s/%s\n", module.GetTriple(),
>> module.GetPlatformFileSpec().GetDirectory(),
>> module.GetPlatformFileSpec().GetFilename()); }
>> This will show you what modules we discovered. If this list is empty,
>> or just contains your original module, then we are not resolving the
>> shared libraries, and this will make debugging not work. Again, you
>> only expect to see if a list of actual modules if you attach to a
>> process that has already been running, so do this with a program on
>> the mac that ran to main and is doing a "sleep(20);", then attach
>> with debugserver:
> Tried the --attach thing after 20+ seconds, only gives (my windows path):
> module[0] x86_64-apple-macosx C:\Users\Carlo\ConsoleApplication6\obj\Debug\a.out
> (Dir = that, file = NULL)
> Just one.
> breakpoint list gives:
> Current breakpoints:
> 1: name = 'main', locations = zu
>  1.1: where = `main, address = (null)[0x0000000100000f30], unresolved, hit count = 0

Yep, so we have a breakpoint we just aren't getting shared libraries to load. See below.
>> % ./a.out ... (a.out is sleeping in main) % /path/to/debugserver
>> localhost:3333 --attach <pid>
> It's like the server side never tells about the modules. Any place I can debug and step into to narrow this down?

DYLD is having trouble syncing up and figuring itself out and where stuff lives in it. 

You will need to debug through "DynamicLoaderMacOSXDYLD::LocateDYLD()" and let me know what path it is taking and how it is failing.

The basics of what this function will try to do:
1 - it will use a hint address given to us by "debugserver" to locate an important data structure in /usr/lib/dylb
2 - it will try and figure out the base address of dyld in memory
	I would expect this to work and I would expect us to execute and succeed with a call to DynamicLoaderMacOSXDYLD.cpp:257:
                 return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress);
3 - all image infos will be loaded in the above command. Debug it and let me know what is failing

Greg Clayton

More information about the lldb-dev mailing list