How to Access Environment Variables Inside .Gdbinit and Inside Gdb Itself

how to have conditional part in gdbinit based on the environnment

How to achieve that ?

If you have GDB with embedded Python (most recent GDB builds do), you have full power of Python at your disposal.

For example:

# ~/.gdbinit
source ~/.gdbinit.py

# ~/.gdbinit.py
import os

h = os.getenv("MY_ENV_VAR")
if h:
print "MY_ENV_VAR =", h
gdb.execute("set history size 100")
# Put other settings here ...
else:
print "MY_ENV_VAR is unset"

Let's see if it works:

$ gdb -q 
MY_ENV_VAR is unset
(gdb) q

$ MY_ENV_VAR=abc gdb -q
MY_ENV_VAR = abc
(gdb)

How to get environment of a program while debugging it in GDB

The gdb command show environment shows an environment which belongs to gdb [see note], not the environment of the program being debugged.

Calling getenv seems like a totally reasonable approach to printing the running program's environment.

Note

Gdb maintains an environment array, initially copied from its own environment, which it uses to start each new child process. show environment and set environment work on this environment, so set environment will change an environment variable for the next time you start the program being debugged. Once the program is started, the loader will have copied the environment into the program's address space, and any changes made with setenv apply to that array, not the one maintained by gdb.

Addendum: How to print the debugged program's entire environment

On Linux, every process's environment is available through the pseudofile /proc/PID/environ, where PID is replaced by the pid of the process. The value of that file is a list of null-terminated strings, so printing it out takes a small amount of work.

Inside gdb, once you've started running the program to be debugged, you can get its pid with info proc and then use that to print the entire environment:

(gdb) info proc
process 6074
...
(gdb) shell xargs -0 printf %s\\n < /proc/6074/environ
XDG_VTNR=7
KDE_MULTIHEAD=false
...

Of course, I could have done that just as easily outside of gdb, from a different terminal.

gdb specific environment variables

I noticed that there are a couple of gdb specific environment variables introduced into the stack during debugging.

You must be using some kind of IDE, or a wrapper script, that does this. GDB itself doesn't modify environment, unless you ask it to with e.g. set env command.

How to set environment variable within GDB using shell command?

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.

Curious thing when finding environment variable address in gdb

From your screenshots, I'll assume you're running on an 32-bit intel platform. I haven't spent the time to fully research an answer to this, but these are points worth noting:

  1. I'll bet that your entire environment is in about the same place, and is packed together tightly as c-style strings. (try x/100s **(char***)&environ).
  2. When I tried ths on my x86-64 installation, the only thing I saw after the environment was my command line, and some empty strings.
  3. At 0xBffff47A, you're very close to the top of user address space (which ends at 0xC0000000).

So, my guess is that what's going on here is that:

  1. The environment block and command line parameters are, at some point during startup, shoved in a packed form right at the end of user address space.
  2. The contents of your environment are different when you run your program in GDB or in the terminal. For example, I notice "_=/usr/bin/gdb" when running under GDB, and I'll just bet that's only there when running under GDB.

The result is that, while your fixed pointer tends to land somewhere in the middle of the environment block, it doesn't land in the same place every time, since the environment itself is changing between runs.

storing shell output into GDB variable in gdbinit?

If you have a new-ish version of GDB (I believe that means 7.x) with python support built, you could add a section like:

python
import subprocess
gdb.execute('set solib-search-path ' +
subprocess.check_output('which gdb',shell=True).rstrip() +
'../project/lib')
end

I can't claim it's not possible without using python, but it's the only way I know of to do it. [I also assumed you meant ../project/lib and not ..\project\lib, but that's an easy change...].

Using variables from script in GDB

Maybe this will be solution for you:

~/.gdbinit

You can put gdb commands there, and whenever gdb is started it will execute them.

Well, in fact, in your case it would be easier to use another approach:

--command=FILE


Related Topics



Leave a reply



Submit