aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@efficios.com>2021-05-13 15:27:55 -0400
committerSimon Marchi <simon.marchi@polymtl.ca>2021-05-13 15:29:00 -0400
commit2af87c859fe450d4a3a841cf19637a91d53c9486 (patch)
treed143b2f59b988b4785b782a16508be00d831f78f
parentbab9eb490b76038ec3283fc8bfcf689cd8af7e42 (diff)
downloadbinutils-2af87c859fe450d4a3a841cf19637a91d53c9486.zip
binutils-2af87c859fe450d4a3a841cf19637a91d53c9486.tar.gz
binutils-2af87c859fe450d4a3a841cf19637a91d53c9486.tar.bz2
gdb: call target_follow_exec when "set follow-exec-mode" is "same"
target_follow_exec is currently only called in the "follow-exec-mode == new" branch of follow_exec, not the "follow-exec-mode == same" branch. I think it would make sense to call it regardless of the mode to let targets do some necessary handling. This is needed in the context of rocm-gdb [1], where a target is pushed on top of the linux-nat target. On exec, it needs to do some bookkeeping, close some file descriptors / handles that were related to the process pre-exec and open some new ones for the process post-exec. However, by looking at the only in-tree implementation of target_ops::follow_exec, remote_target::follow_exec, I found that it would be useful for the extended-remote target too, to align its behavior with native debugging (although I think that behavior is not very user-friendly, see PR 27745 [2]). Using two programs, one (let's call it "execer") that execs the other (let's call it "execee"), with native: $ ./gdb -q -nx --data-directory=data-directory ./execer Reading symbols from ./execer... (gdb) r Starting program: /home/simark/build/binutils-gdb/gdb/execer I am execer process 1495622 is executing new program: /home/simark/build/binutils-gdb/gdb/execee I am execee [Inferior 1 (process 1495622) exited normally] (gdb) r Starting program: /home/simark/build/binutils-gdb/gdb/execee I am execee [Inferior 1 (process 1495626) exited normally] And now with gdbserver (some irrelevant output lines removed for brevity): $ ./gdbserver --once --multi :1234 ... $ ./gdb -q -nx --data-directory=data-directory ./execer -ex "set remote exec-file /home/simark/build/binutils-gdb/gdb/execer" -ex "tar ext :1234" Reading symbols from ./execer... Remote debugging using :1234 (gdb) r Starting program: /home/simark/build/binutils-gdb/gdb/execer process 1495724 is executing new program: /home/simark/build/binutils-gdb/gdb/execee [Inferior 1 (process 1495724) exited normally] (gdb) r `target:/home/simark/build/binutils-gdb/gdb/execee' has disappeared; keeping its symbols. Starting program: target:/home/simark/build/binutils-gdb/gdb/execee warning: Build ID mismatch between current exec-file target:/home/simark/build/binutils-gdb/gdb/execee and automatically determined exec-file target:/home/simark/build/binutils-gdb/gdb/execer exec-file-mismatch handling is currently "ask" Reading /home/simark/build/binutils-gdb/gdb/execer from remote target... Load new symbol table from "target:/home/simark/build/binutils-gdb/gdb/execer"? (y or n) When handling the exec, GDB updates the exec-file of the inferior to be the execee. This means that a subsequent "run" will run the execee, not the original executable (execer). remote_target::follow_exec is meant to update the "remote exec-file", which is the file on the remote system that will be executed if you "run" the inferior, to the execee as well. However, this is not called when follow-exec-mode is same, because target_follow_exec is not called in this branch. As a result, GDB thinks the inferior is executing execee but the remote side is really executing execer, hence the mismatch message. By calling target_follow_exec in the "same" branch of the follow_exec function, we ensure that everybody agrees, and we get the same behavior with the extended-remote target as we get with the native target, the execee is executed on the second run: $ ./gdbserver --once --multi :1234 ... $ ./gdb -q -nx --data-directory=data-directory ./execer -ex "set remote exec-file /home/simark/build/binutils-gdb/gdb/execer" -ex "tar ext :1234" Reading symbols from ./execer... Remote debugging using :1234 (gdb) r Starting program: /home/simark/build/binutils-gdb/gdb/execer process 1501445 is executing new program: /home/simark/build/binutils-gdb/gdb/execee [Inferior 1 (process 1501445) exited normally] (gdb) r `target:/home/simark/build/binutils-gdb/gdb/execee' has disappeared; keeping its symbols. Starting program: target:/home/simark/build/binutils-gdb/gdb/execee [Inferior 1 (process 1501447) exited normally] (gdb) This scenario is tested in gdb.base/foll-exec-mode.exp, and in fact this patch fixes the test for me when using --target_board=native-extended-gdbserver. gdb/ChangeLog: * infrun.c (follow_exec): Call target_follow_fork when follow-exec-mode is same. * target.h (target_follow_fork): Improve doc. [1] https://github.com/ROCm-Developer-Tools/ROCgdb [2] https://sourceware.org/bugzilla/show_bug.cgi?id=27745 Change-Id: I4ee84a875e39bf3f8eaf3e6789a4bfe23a2a430e
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/infrun.c1
-rw-r--r--gdb/target.h7
3 files changed, 12 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index de66783..f0ae77e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2021-05-13 Simon Marchi <simon.marchi@efficios.com>
+
+ * infrun.c (follow_exec): Call target_follow_fork when
+ follow-exec-mode is same.
+ * target.h (target_follow_fork): Improve doc.
+
2021-05-13 Simon Marchi <simon.marchi@polymtl.ca>
* cli/cli-decode.h (struct cmd_list_element) <pre_show_hook>:
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 90bab8d..3e386aa 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -1198,6 +1198,7 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
around (its description is later cleared/refetched on
restart). */
target_clear_description ();
+ target_follow_exec (inf, exec_file_target);
}
gdb_assert (current_program_space == inf->pspace);
diff --git a/gdb/target.h b/gdb/target.h
index 48bf734..b80cf88 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -1714,8 +1714,11 @@ extern int target_remove_vfork_catchpoint (int pid);
void target_follow_fork (bool follow_child, bool detach_fork);
-/* Handle the target-specific bookkeeping required when the inferior
- makes an exec call. INF is the exec'd inferior. */
+/* Handle the target-specific bookkeeping required when the inferior makes an
+ exec call. The current inferior is the inferior that has executed the exec
+ call. INF is the inferior in which execution continues post-exec. It is the
+ same inferior as the current one if "follow-exec-mode" is "same" but is a new
+ one if "follow-exec-mode" is "new". */
void target_follow_exec (struct inferior *inf, const char *execd_pathname);