aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/arch-utils.c26
-rw-r--r--gdb/arch-utils.h13
-rw-r--r--gdb/corelow.c3
-rw-r--r--gdb/linux-tdep.c6
-rw-r--r--gdb/testsuite/gdb.base/corefile-exec-context.exp63
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"