Search code examples
c++clinuxgdbenvironment-variables

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


I am debugging a program in GDB on linux. I am using getenv and setenv calls to read and set environment variables. For example I am calling setenv("TZ", "UTC", 1); to set the TZ environment variable for timezone.

To check if the env variable is set I am using GDB command show environment. This prints all the environment variables and their values. But it dose not show TZ being set.

Even command show environment TZ says Environment variable "TZ" not defined.

Is their another way to check the environment of the debugged program?

p *(char *) getenv("TZ") reuturns correct value UTC.


Solution

  • 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.