I realized that with "follow-exec-mode == new", the process target
stayed pushed in the original inferior. This can cause a small
incoherence:
$ ./gdb -q -nx --data-directory=data-directory -ex "set follow-exec-mode new" --args execer args-for-execer
Reading symbols from execer...
(gdb) r
Starting program: /home/smarchi/build/binutils-gdb/gdb/execer args-for-execer
I am execer and my argv[1] is: args-for-execer
process
3562426 is executing new program: /home/smarchi/build/binutils-gdb/gdb/execee
[New inferior 2]
[New process
3562426]
I am execee and my argv[1] is: arg-for-execee
[Inferior 2 (process
3562426) exited normally]
(gdb) info inferiors
Num Description Connection Executable
1 <null> 1 (native) /home/smarchi/build/binutils-gdb/gdb/execer
* 2 <null> /home/smarchi/build/binutils-gdb/gdb/execee
(gdb) maintenance print target-stack
The current target stack is:
- exec (Local exec file)
- None (None)
(gdb) inferior 1
[Switching to inferior 1 [<null>] (/home/smarchi/build/binutils-gdb/gdb/execer)]
(gdb) maintenance print target-stack
The current target stack is:
- native (Native process)
- exec (Local exec file)
- None (None)
On exec, when execution continues into inferior 2, the native target
isn't unpushed from inferior 1. When inferior 2's execution finishes
normally, inf_child_target::mourn_inferior unpushes the native target,
because the native target has been implicitly opened.
I think that if the native target was implicitly opened, it should be
unpushed from inferior 1, just like it is unpushed from an inferior
whose execution terminate. This patch implements that.
gdb/ChangeLog:
* inf-child.h (inf_child_target) <follow_exec>: New.
* inf-child.c (inf_child_target::follow_exec): New.
Change-Id: I782cc08d73d93a990f4e53611107f68b2cb58af1
+2021-05-13 Simon Marchi <simon.marchi@efficios.com>
+
+ * inf-child.h (inf_child_target) <follow_exec>: New.
+ * inf-child.c (inf_child_target::follow_exec): New.
+
2021-05-13 Simon Marchi <simon.marchi@efficios.com>
* target.h (struct target_ops) <follow_exec>: Add ptid_t
return agent_loaded_p ();
}
+void
+inf_child_target::follow_exec (inferior *follow_inf, ptid_t ptid,
+ const char *execd_pathname)
+{
+ inferior *orig_inf = current_inferior ();
+
+ process_stratum_target::follow_exec (follow_inf, ptid, execd_pathname);
+
+ if (orig_inf != follow_inf)
+ {
+ /* If the target was implicitly push in the original inferior, unpush
+ it. */
+ scoped_restore_current_thread restore_thread;
+ switch_to_inferior_no_thread (orig_inf);
+ maybe_unpush_target ();
+ }
+}
+
/* See inf-child.h. */
void
void post_startup_inferior (ptid_t) override;
+ void follow_exec (inferior *follow_inf, ptid_t ptid,
+ const char *execd_pathname) override;
+
void mourn_inferior () override;
bool can_run () override;
return
}
+ set target_is_native [gdb_is_target_native]
+
# Set the follow-exec mode.
#
gdb_test_no_output "set follow-exec-mode $mode"
#
if {$mode == "same"} {
set expected_re "\\* 1.*process.*"
+ } elseif { $mode == "new" } {
+ # If using the native target, we want to specifically check that the
+ # process target, which was automatically pushed when running, was
+ # automatically unpushed from inferior 1 on exec. Use a
+ # different regexp that verifies the Connection field is empty.
+ if { $target_is_native } {
+ set expected_re " 1.*<null> +[string_to_regexp $binfile].*\r\n\\* 2.*process.*$testfile2 .*"
+ } else {
+ set expected_re " 1.*null.*$testfile.*\r\n\\* 2.*process.*$testfile2 .*"
+ }
} else {
- set expected_re " 1.*null.*$testfile.*\r\n\\* 2.*process.*$testfile2 .*"
+ error "Invalid mode: $mode"
}
# Check that the inferior list is correct: