72

I run a program with LD_PRELOADing a specific library. Like this.

LD_PRELOAD=./my.so ./my_program

How do I run this program with gdb?

R Yoda
  • 8,358
  • 2
  • 50
  • 87
MetallicPriest
  • 29,191
  • 52
  • 200
  • 356

6 Answers6

85

Do the following.

gdb your_program

(gdb) set environment LD_PRELOAD ./yourso.so
(gdb) start
Employed Russian
  • 199,314
  • 34
  • 295
  • 362
MetallicPriest
  • 29,191
  • 52
  • 200
  • 356
20

Posting because we ran into a case where set environment didn't work:

From GDB documentation:

set exec-wrapper wrapper
show exec-wrapper
unset exec-wrapper

When ‘exec-wrapper’ is set, the specified wrapper is used to launch programs for debugging. gdb starts your program with a shell command of the form exec wrapper program. Quoting is added to program and its arguments, but not to wrapper, so you should add quotes if appropriate for your shell. The wrapper runs until it executes your program, and then gdb takes control.

You can use any program that eventually calls execve with its arguments as a wrapper. Several standard Unix utilities do this, e.g. env and nohup. Any Unix shell script ending with exec "$@" will also work.

For example, you can use env to pass an environment variable to the debugged program, without setting the variable in your shell's environment:

         (gdb) set exec-wrapper env 'LD_PRELOAD=libtest.so'
         (gdb) run
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
18

A way to set both the environment and arguments in one command:

gdb --args env LD_PRELOAD=/usr/local/lib/libstderred.so /usr/bin/ls -l

This uses env to the same effect as an exec wrapper (like Alexey Romanov's answer), except that GDB doesn't know about it. The side effect is that your session will start in env. Fortunately, GDB will follow the exec into the target program as if nothing happened, and the backtrace is identical.

The convenience of having everything in one command is that your shell history will help you run the exact same thing again.

user2394284
  • 5,520
  • 4
  • 32
  • 38
  • This is not using `env` as an exec wrapper in the sense that GDB talks about an exec-wrapper. In this case you will start by debugging `env` itself. When `env` does an `exec` to run `ls` GDB will follow the exec, but commands like `start` will not do what you expect - they will run to the start of `env`, not the start of `ls`, which probably isn't what you want. – Andrew Dec 01 '22 at 12:31
10

You can supply env as an exec-wrapper on the command line using the -iex flag:

gdb -iex "set exec-wrapper env LD_PRELOAD=./my.so" ./my_program
ecatmur
  • 152,476
  • 27
  • 293
  • 366
1

I am using gdbserver with VS Code, the simplest way is launching your program wrapped in a shell:

gdbserver :8888 sh -c 'LD_PRELOAD=/libtest.so your_prog'
-1

You can basically do it the same way, just add gdb before the program name:

LD_PRELOAD=./my.so gdb ./my.program

You can check the environment variables using:

(gdb) show environment LD_PRELOAD

In the rare case you actually need to change it inside gdb, e.g. when debugging a dlopen(), you ca do that:

(gdb) set environment LD_PRELOAD ./my.so

Oh, wait, it doesn't work for me with gdb 7.6.2! The library doesn't get loaded, that means none of the answer here are entirely correct, at least with current tools.

Pavel Šimerda
  • 5,783
  • 1
  • 31
  • 31
  • 6
    I'm guessing that the effect of the preload is unwanted for GDB itself (perhaps it's a mocking library that modifies `open()` and the like - such as `fakeroot` etc). – Toby Speight Nov 14 '17 at 13:32