[binutils-gdb] gdb: implement "info proc environ"

Tankut Baris Aktemur aktemur@sourceware.org
Wed Feb 25 10:13:11 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6df31bc2120b1e8e4351409b4005ef114689785a

commit 6df31bc2120b1e8e4351409b4005ef114689785a
Author: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
Date:   Wed Feb 25 11:03:52 2026 +0100

    gdb: implement "info proc environ"
    
    Add a new "environ" subcommand to "info proc" to print the initial
    environment variables of a given process.  The environment variables
    are printed line-by-line and are indented by two spaces, so that they
    can be distinguished from the rest of the output in "info proc all".
    
    Note that the information printed by this new command is not
    necessarily the same as `show environment`, which lists the
    environment variables that will be given to the program next time it
    is started under GDB.  The two information may differ in particular
    when GDB attached to a running program that was started in an
    environment different than GDB's.
    
    Reviewed-By: Eli Zaretskii <eliz@gnu.org>
    Approved-By: Andrew Burgess <aburgess@redhat.com>

Diff:
---
 gdb/NEWS                             |  4 ++++
 gdb/defs.h                           |  3 +++
 gdb/doc/gdb.texinfo                  | 11 +++++++++++
 gdb/infcmd.c                         | 13 +++++++++++++
 gdb/linux-tdep.c                     | 25 +++++++++++++++++++++++++
 gdb/testsuite/gdb.base/info-proc.exp | 23 ++++++++++++++++++++---
 6 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index 47d8189d344..0ab0323aafa 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -104,6 +104,10 @@ show progress-bars enabled
   content, to be disabled (the set command), or to see if
   progress-bars are currently enabled or not (the show command).
 
+info proc environ
+  Print the initial environment variables of the specified process.
+  Supported on Linux.
+
 * Changed commands
 
 maintenance info program-spaces
diff --git a/gdb/defs.h b/gdb/defs.h
index 35a9eb31761..b378449343d 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -270,6 +270,9 @@ enum info_proc_what
     /* * Display `info proc cmdline'.  */
     IP_CMDLINE,
 
+    /* * Display `info proc environ'.  */
+    IP_ENVIRON,
+
     /* * Display `info proc exe'.  */
     IP_EXE,
 
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 3b2401117c7..83cf2e7ccea 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -25527,6 +25527,17 @@ supported on @sc{gnu}/Linux, FreeBSD and NetBSD.
 Show the current working directory of the process.  This command is
 supported on @sc{gnu}/Linux, FreeBSD and NetBSD.
 
+@item info proc environ
+@cindex info proc environ
+Show the initial environment variables of the process.  This command
+is supported on @sc{gnu}/Linux.  Note that the information printed by
+@code{info proc environ} is not necessarily the same as @code{show
+environment}, which lists the environment variables that will be given
+to the program next time it is started by @value{GDBN}.  The two
+information may differ in particular when @value{GDBN} attached to a
+running program that was started in an environment different than
+@value{GDBN}'s.
+
 @item info proc exe
 @cindex info proc exe
 Show the name of executable of the process.  This command is supported
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 871eeba1850..319d17d95eb 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -3260,6 +3260,14 @@ info_proc_cmd_cmdline (const char *args, int from_tty)
   info_proc_cmd_1 (args, IP_CMDLINE, from_tty);
 }
 
+/* Implement `info proc environ'.  */
+
+static void
+info_proc_cmd_environ (const char *args, int from_tty)
+{
+  info_proc_cmd_1 (args, IP_ENVIRON, from_tty);
+}
+
 /* Implement `info proc exe'.  */
 
 static void
@@ -3638,6 +3646,11 @@ List current working directory of the specified process."),
 List command line arguments of the specified process."),
 	   &info_proc_cmdlist);
 
+  add_cmd ("environ", class_info, info_proc_cmd_environ, _("\
+List initial environment variables of the specified process.\n\
+See also 'show environment' command."),
+	   &info_proc_cmdlist);
+
   add_cmd ("exe", class_info, info_proc_cmd_exe, _("\
 List absolute filename for executable of the specified process."),
 	   &info_proc_cmdlist);
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index edcf4ea2401..1cd35e5dd81 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -827,6 +827,7 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args,
   long pid;
   int cmdline_f = (what == IP_MINIMAL || what == IP_CMDLINE || what == IP_ALL);
   int cwd_f = (what == IP_MINIMAL || what == IP_CWD || what == IP_ALL);
+  int environ_f = (what == IP_ENVIRON || what == IP_ALL);
   int exe_f = (what == IP_MINIMAL || what == IP_EXE || what == IP_ALL);
   int mappings_f = (what == IP_MAPPINGS || what == IP_ALL);
   int status_f = (what == IP_STATUS || what == IP_ALL);
@@ -888,6 +889,30 @@ linux_info_proc (struct gdbarch *gdbarch, const char *args,
       else
 	warning (_("unable to read link '%s'"), filename);
     }
+  if (environ_f)
+    {
+      xsnprintf (filename, sizeof filename, "/proc/%ld/environ", pid);
+      gdb_byte *buffer;
+      LONGEST len = target_fileio_read_alloc (nullptr, filename, &buffer);
+
+      if (len > 0)
+	{
+	  gdb::unique_xmalloc_ptr<char> dealloc ((char *) buffer);
+	  gdb_printf (_("Environment variables:\n\n"));
+
+	  /* Entries are separated by the null character.
+	     Print each environment variable, line by line.  */
+	  gdb_byte *buffer_end = buffer + len;
+	  while (buffer < buffer_end)
+	    {
+	      gdb_printf ("  %s\n", buffer);
+	      /* +1 for the null character.  */
+	      buffer += strlen ((char *) buffer) + 1;
+	    }
+	}
+      else
+	warning (_("unable to open /proc file '%s'"), filename);
+    }
   if (exe_f)
     {
       xsnprintf (filename, sizeof filename, "/proc/%ld/exe", pid);
diff --git a/gdb/testsuite/gdb.base/info-proc.exp b/gdb/testsuite/gdb.base/info-proc.exp
index 8d83483bec5..1210bcb9af1 100644
--- a/gdb/testsuite/gdb.base/info-proc.exp
+++ b/gdb/testsuite/gdb.base/info-proc.exp
@@ -20,9 +20,15 @@ set ws "\[ \t\]+"
 
 standard_testfile break.c break1.c
 
-if {[prepare_for_testing "failed to prepare" $testfile \
-	 [list $srcfile $srcfile2] {debug nowarnings}]} {
-    return -1
+# Start GDB with an environment variable to test
+# "info proc environ" later.
+save_vars { env(GDB_INFO_PROC_ENVIRON_1) } {
+    set env(GDB_INFO_PROC_ENVIRON_1) "ONE"
+
+    if {[prepare_for_testing "failed to prepare" $testfile \
+	     [list $srcfile $srcfile2] {debug nowarnings}]} {
+	return -1
+    }
 }
 
 gdb_test "help info proc" "Show additional information about a process.*"
@@ -41,6 +47,7 @@ gdb_test_multiple "info proc" "info proc without a process" {
 # Set command line arguments to be verified later with "info proc
 # cmdline".  However, if we're using a stub, then "set args" would not
 # have any effect, so then just skip this.
+# Similar for "info proc environ".
 
 set cmdline ""
 if { ! [use_gdb_stub] } {
@@ -48,6 +55,10 @@ if { ! [use_gdb_stub] } {
     gdb_test_no_output "set args $cmdline" "set args"
 }
 
+# Set another environment variable, this time using a GDB command,
+# to test "info proc environ".
+gdb_test "set environment GDB_INFO_PROC_ENVIRON_2 TWO"
+
 if {![runto_main]} {
     return -1
 }
@@ -60,7 +71,13 @@ gdb_test "info proc mapping" \
 if {[istarget "*-*-linux*"]} {
     if { $cmdline != "" } {
 	gdb_test "info proc cmdline" "cmdline = '.* $cmdline'"
+
+	gdb_test "pipe info proc environ | grep GDB_INFO_PROC_ENVIRON_1" \
+	    "=ONE" "info proc environ: read env var 1"
+	gdb_test "pipe info proc environ | grep GDB_INFO_PROC_ENVIRON_2" \
+	    "=TWO" "info proc environ: read env var 2"
     }
+
     set gcorefile [standard_output_file $testfile.gcore]
     if {[gdb_gcore_cmd $gcorefile "save a core file"]} {
 	clean_restart $testfile


More information about the Gdb-cvs mailing list