Using DYLD_LIBRARY_PATH and lldb


I'm fairly new to lldb, been using gdb most of my life.

I'm currently hacking on a small library which I'm building without
installing. Usually I'm running tests for the library also without
installing, but rather using DYLD_LIBRARY_PATH in this manner:
DYLD_LIBRARY_PATH=<mydylibpath> mytestbinary

On linux using gdb when I want to debug an issue I usually just stick
gdb in there, which I can't do with lldb on darwin it seems:
DYLD_LIBRARY_PATH=<mydylibpath> lldb mytestbinary

lldb gives me this result:
(lldb) target create "<mytestbinary>"
Current executable set to '<mytestbinary>' (x86_64).
(lldb) r
Process 4904 launched: '<mytestbinary>' (x86_64)
dyld: Library not loaded: /usr/local/lib/<mydylib>
  Referenced from: <mytestbinary>
  Reason: image not found
Process 4904 stopped
* thread #1: tid = 0xfe39, 0x00007fff5fc01075 dyld`dyld_fatal_error +
1, stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
    frame #0: 0x00007fff5fc01075 dyld`dyld_fatal_error + 1
-> 0x7fff5fc01075 <+1>: nop

    0x7fff5fc01076 <+0>: pushq %rbp
    0x7fff5fc01077 <+1>: movq %rsp, %rbp
    0x7fff5fc0107a <+4>: pushq %r15

so it's not picking up the dylib from DYLD_LIBRARY_PATH.

I guess my question is whether this is a bug or not? Am I doing
anything wrong, or should I not use DYLD_LIBRARY_PATH this way? Any
suggestions and/or education would be appreciated!
To work around this issue I've used 'install_name_tool -change old new
<mytestbinary>' which obviously works.

Thanks, best regards
Haakon Sporsheim

I am surprised that this doesn't work as we make an effort to pass the current environment down to any processes that you spawn by default (at least on MacOSX we do), but the solution is easy: use the --environment variable with the "process launch" command:

(lldb) process launch --environment DYLD_LIBRARY_PATH=<mydylibpath> -- arg1 arg2 arg3

or using the short -v option:

(lldb) process launch -v DYLD_LIBRARY_PATH=<mydylibpath> -- arg1 arg2 arg3

r is an alias to "process launch --". Note that "process launch" can have arguments and the arguments you want to pass to your program might have options, so you can terminate your "process launch" arguments with "--" so that you can add your program arguments:

(lldb) process launch --environment DYLD_LIBRARY_PATH=<mydylibpath> -- --program-option=123 --environment BAR=BAZ

Note that I actually used an option "--environment BAR=BAZ" that I am passing to the program to be debugged...

It is better to use --environment because then your current LLDB or any processes that LLDB spawns won't have that environment variable set. Hope this helps.

Greg Clayton

If it's on Mac OS X 10.11, I saw this the other day. e.g.

sh-3.2$ cat a.c
#include <stdio.h>
#include <stdlib.h>
int main()
    printf("%s\n", getenv("DYLD_LIBRARY_PATH"));
sh-3.2$ clang a.c

sh-3.2$ lldb -x a.out
(lldb) target create "a.out"
Current executable set to 'a.out' (x86_64).
(lldb) pro lau -v DYLD_LIBRARY_PATH=/tmp
Process 66509 launched: '/private/tmp/a.out' (x86_64)
Process 66509 exited with status = 0 (0x00000000)
(lldb) q

sh-3.2$ DYLD_LIBRARY_PATH=/tmp lldb -x -- a.out
(lldb) target create "a.out"
Current executable set to 'a.out' (x86_64).
(lldb) r
Process 66776 launched: '/private/tmp/a.out' (x86_64)
Process 66776 exited with status = 0 (0x00000000)
(lldb) q

The DYLD_LIBRARY_PATH isn't being passed into lldb, it seems. If I attach to that lldb with another lldb,

(lldb) pro att -n lldb
Executable module set to "/Applications/".
Architecture set to: x86_64-apple-macosx.
(lldb) p (char*)getenv("DYLD_LIBRARY_PATH")
(char *) $0 = 0x0000000000000000
(lldb) ^D

yep, it's not being passed through.