16

I want to run gdb with only a single variable MyVar in its environment.

However, the variable's contents are rather complex, containing non-printable ASCII, and so is best set using e.g. MyVar=$(python -c 'print("\xff...")').

I'm left with two options:

  1. Set the MyVar in bash before running gdb. Then inside gdb, remove all other environment variables individually using unset environment NAME (very tedious!).

  2. Clear all environment variables using unset environment. Then inside gdb, set MyVar using a shell command (as above) (how?)

Any ideas?

imz -- Ivan Zakharyaschev
  • 4,921
  • 6
  • 53
  • 104
Shuzheng
  • 11,288
  • 20
  • 88
  • 186

2 Answers2

8

When starting gdb from shell command-line, you can specify which program to run, with which arguments (with --args), and even modify the environment of the program with the help of env!

I just did it successfully like this:

gdb --ex=run --args env LD_BIND_NOW=1 LD_DEBUG=libs \
apt-get install --yes $(cat pkgs-to-install-to-crash-apt)

--ex=run is to ask gdb to run it immediately.

In your case, you would do env -i.

It differs from the suggested env -i VAR=... gdb program in that only your examined program is under the special environment, but not gdb.

Johan Boulé
  • 1,936
  • 15
  • 19
imz -- Ivan Zakharyaschev
  • 4,921
  • 6
  • 53
  • 104
  • 3
    Even though my answer was accepted, I like this one better since it does not affect gdb itself. – jamieguinan Oct 19 '21 at 19:10
  • One thing to take into account with that: if you want to break at the beginning of your main entry point, then you have to use something else than the `start` command, otherwise, you stop in `env`'s entry point, before it replaces the program with some `exec*()`. – Johan Boulé Apr 01 '23 at 11:57
7

Option 2 is possible.

(gdb) unset environment
(gdb) python gdb.execute("set environment Myvar=\xff")
(gdb) show environment 
Myvar=ÿ

Option 1 can be done with env(1).

$ env -i MyVar=$(python -c 'print("xyz")') gdb
(gdb) show environment
MyVar=xyz
LINES=35
COLUMNS=80

Then you just have to clear LINES and COLUMNS.

jamieguinan
  • 1,640
  • 1
  • 10
  • 14
  • Thank you. Do you know what LINES and COLUMNS mean? They are environment variables set by GDB I suppose. – Shuzheng Apr 09 '19 at 15:05
  • Yes, they are the lines and columns of the terminal, and GDB sets them internally. See [here](https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=readline/terminal.c;h=8094186bba21a91ed02b962988b90769cb323312;hb=HEAD#l230) and [here](https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=readline/shell.c;h=ac0fb3604b8a9d6abcfbfcea6ee79e5f3cad549e;hb=HEAD#l124). – jamieguinan Apr 09 '19 at 15:31
  • it's wierd, I cannot get option 2 to work. After having executed the Python command, I check `show environment` and no environment variables there. The option 1 is also wierd. The stack is different from running `env -i MyVar="..." prog` with ASLR disabled - any ideas? – Shuzheng Apr 10 '19 at 08:46
  • I edited my answer to show an example for option 2. I actually like it better than option 1 now! As for ASLR, that wasn't in your original question but if I disable it with `echo 0 | sudo tee /proc/sys/kernel/randomize_va_space` then I get the same output from this program every time: `#include ` `void foo() { int x = 0; printf("&x = %p\n", &x); }` `int main() { foo(); return 0; }` – jamieguinan Apr 11 '19 at 03:46
  • Thanks again. Does all newer versions of GDB come with Python support or is it something that I need to install through addons? – Shuzheng Apr 11 '19 at 03:52
  • It looks like version 7 and up. – jamieguinan Apr 11 '19 at 04:51
  • 2
    If you need to run a program with a custom environment, it'd be better not run the whole gdb under `env`, but just the program, with `gdb --args env ...`, as demonstrated in https://stackoverflow.com/a/60571461/94687 – imz -- Ivan Zakharyaschev Jul 17 '21 at 16:12