diff options
-rw-r--r-- | gdb/arch-utils.c | 26 | ||||
-rw-r--r-- | gdb/arch-utils.h | 13 | ||||
-rw-r--r-- | gdb/corelow.c | 3 | ||||
-rw-r--r-- | gdb/linux-tdep.c | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/corefile-exec-context.exp | 63 |
5 files changed, 106 insertions, 5 deletions
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index a2ed2a2..3cc6d99 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -1499,6 +1499,32 @@ gdbarch_initialized_p (gdbarch *arch) return arch->initialized_p; } +/* See arch-utils.h. */ + +gdb_environ +core_file_exec_context::environment () const +{ + gdb_environ e; + + for (const auto &entry : m_environment) + { + char *eq = strchr (entry.get (), '='); + + /* If there's no '=' character, then skip this entry. */ + if (eq == nullptr) + continue; + + const char *value = eq + 1; + const char *var = entry.get (); + + *eq = '\0'; + e.set (var, value); + *eq = '='; + } + + return e; +} + void _initialize_gdbarch_utils (); void _initialize_gdbarch_utils () diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index 00ec847..cae0363 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -21,6 +21,7 @@ #define GDB_ARCH_UTILS_H #include "gdbarch.h" +#include "gdbsupport/environ.h" class frame_info_ptr; struct minimal_symbol; @@ -88,9 +89,11 @@ struct core_file_exec_context found but not ARGV then use the no-argument constructor to create an empty context object. */ core_file_exec_context (gdb::unique_xmalloc_ptr<char> exec_name, - std::vector<gdb::unique_xmalloc_ptr<char>> argv) + std::vector<gdb::unique_xmalloc_ptr<char>> argv, + std::vector<gdb::unique_xmalloc_ptr<char>> envp) : m_exec_name (std::move (exec_name)), - m_arguments (std::move (argv)) + m_arguments (std::move (argv)), + m_environment (std::move (envp)) { gdb_assert (m_exec_name != nullptr); } @@ -115,6 +118,9 @@ struct core_file_exec_context const std::vector<gdb::unique_xmalloc_ptr<char>> &args () const { return m_arguments; } + /* Return the environment variables from this context. */ + gdb_environ environment () const; + private: /* The executable filename as reported in the core file. Can be nullptr @@ -124,6 +130,9 @@ private: /* List of arguments. Doesn't include argv[0] which is the executable name, for this look at m_exec_name field. */ std::vector<gdb::unique_xmalloc_ptr<char>> m_arguments; + + /* List of environment strings. */ + std::vector<gdb::unique_xmalloc_ptr<char>> m_environment; }; /* Default implementation of gdbarch_displaced_hw_singlestep. */ diff --git a/gdb/corelow.c b/gdb/corelow.c index 97ca48f..7100399 100644 --- a/gdb/corelow.c +++ b/gdb/corelow.c @@ -1073,6 +1073,9 @@ core_target_open (const char *arg, int from_tty) argv.push_back (a.get ()); gdb::array_view<char * const> view (argv.data (), argv.size ()); current_inferior ()->set_args (view); + + /* And now copy the environment. */ + current_inferior ()->environment = ctx.environment (); } else { diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index 8d506fe..6d90e89 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -2074,8 +2074,7 @@ linux_corefile_parse_exec_context_1 (struct gdbarch *gdbarch, bfd *cbfd) be pointing at the first environment string. */ ptr += ptr_bytes; - /* Parse the environment strings. Nothing is done with this yet, but - will be in a later commit. */ + /* Parse the environment strings. */ std::vector<gdb::unique_xmalloc_ptr<char>> environment; while ((v = deref (ptr)) != 0) { @@ -2092,7 +2091,8 @@ linux_corefile_parse_exec_context_1 (struct gdbarch *gdbarch, bfd *cbfd) return {}; return core_file_exec_context (std::move (execfn), - std::move (arguments)); + std::move (arguments), + std::move (environment)); } /* Parse and return execution context details from core file CBFD. */ diff --git a/gdb/testsuite/gdb.base/corefile-exec-context.exp b/gdb/testsuite/gdb.base/corefile-exec-context.exp index b18a810..ac97754 100644 --- a/gdb/testsuite/gdb.base/corefile-exec-context.exp +++ b/gdb/testsuite/gdb.base/corefile-exec-context.exp @@ -100,3 +100,66 @@ gdb_test_multiple "core-file $corefile_2" "load core file with args" { # Also, the argument list should be available through 'show args'. gdb_test "show args" \ "Argument list to give program being debugged when it is started is \"$args\"\\." + +# Find the name of an environment variable that is not set. +set env_var_base "GDB_TEST_ENV_VAR_" +set env_var_name "" + +for { set i 0 } { $i < 10 } { incr i } { + set tmp_name ${env_var_base}${i} + if { ! [info exists ::env($tmp_name)] } { + set env_var_name $tmp_name + break + } +} + +if { $env_var_name eq "" } { + unsupported "couldn't find suitable environment variable name" + return -1 +} + +# Generate a core file with this environment variable set. +set env_var_value "TEST VALUE" +save_vars { ::env($env_var_name) } { + setenv $env_var_name $env_var_value + + set corefile [core_find $binfile {} $args] + if {$corefile == ""} { + untested "unable to create corefile" + return 0 + } +} +set corefile_3 "$binfile.2.core" +remote_exec build "mv $corefile $corefile_3" + +# Restart, load the core file, and check the environment variable +# shows up. +clean_restart $binfile + +# Check for environment variable VAR_NAME in the environment, its +# value should be VAR_VALUE. +proc check_for_env_var { var_name var_value } { + set saw_var false + gdb_test_multiple "show environment" "" { + -re "^$var_name=$var_value\r\n" { + set saw_var true + exp_continue + } + -re "^\[^\r\n\]*\r\n" { + exp_continue + } + -re "^$::gdb_prompt $" { + } + } + return $saw_var +} + +gdb_assert { ![check_for_env_var $env_var_name $env_var_value] } \ + "environment variable is not set before core file load" + +gdb_test "core-file $corefile_3" \ + "Core was generated by `[string_to_regexp $binfile] $args'\\.\r\n.*" \ + "load core file for environment test" + +gdb_assert { [check_for_env_var $env_var_name $env_var_value] } \ + "environment variable is set after core file load" |