diff options
-rw-r--r-- | gdb/infrun.c | 39 | ||||
-rw-r--r-- | gdb/jit.c | 20 | ||||
-rw-r--r-- | gdb/linux-tdep.c | 10 | ||||
-rw-r--r-- | gdb/observable.h | 8 | ||||
-rw-r--r-- | gdb/solib.c | 3 |
5 files changed, 52 insertions, 28 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c index ba56fe3..e77ad31 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1293,7 +1293,8 @@ follow_exec (ptid_t ptid, const char *exec_file_target) previous incarnation of this process. */ no_shared_libraries (nullptr, 0); - struct inferior *inf = current_inferior (); + inferior *execing_inferior = current_inferior (); + inferior *following_inferior; if (follow_exec_mode_string == follow_exec_mode_new) { @@ -1304,19 +1305,19 @@ follow_exec (ptid_t ptid, const char *exec_file_target) inferior's pid. Having two inferiors with the same pid would confuse find_inferior_p(t)id. Transfer the terminal state and info from the old to the new inferior. */ - inferior *new_inferior = add_inferior_with_spaces (); - - swap_terminal_info (new_inferior, inf); - exit_inferior_silent (inf); + following_inferior = add_inferior_with_spaces (); - new_inferior->pid = pid; - target_follow_exec (new_inferior, ptid, exec_file_target); + swap_terminal_info (following_inferior, execing_inferior); + exit_inferior_silent (execing_inferior); - /* We continue with the new inferior. */ - inf = new_inferior; + following_inferior->pid = pid; } else { + /* follow-exec-mode is "same", we continue execution in the execing + inferior. */ + following_inferior = execing_inferior; + /* The old description may no longer be fit for the new image. E.g, a 64-bit process exec'ed a 32-bit process. Clear the old description; we'll read a new one below. No need to do @@ -1324,18 +1325,20 @@ 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, ptid, exec_file_target); } - gdb_assert (current_inferior () == inf); - gdb_assert (current_program_space == inf->pspace); + target_follow_exec (following_inferior, ptid, exec_file_target); + + gdb_assert (current_inferior () == following_inferior); + gdb_assert (current_program_space == following_inferior->pspace); /* Attempt to open the exec file. SYMFILE_DEFER_BP_RESET is used because the proper displacement for a PIE (Position Independent Executable) main symbol file will only be computed by solib_create_inferior_hook below. breakpoint_re_set would fail to insert the breakpoints with the zero displacement. */ - try_open_exec_file (exec_file_host.get (), inf, SYMFILE_DEFER_BP_RESET); + try_open_exec_file (exec_file_host.get (), following_inferior, + SYMFILE_DEFER_BP_RESET); /* If the target can specify a description, read it. Must do this after flipping to the new executable (because the target supplied @@ -1345,7 +1348,7 @@ follow_exec (ptid_t ptid, const char *exec_file_target) registers. */ target_find_description (); - gdb::observers::inferior_execd.notify (inf); + gdb::observers::inferior_execd.notify (execing_inferior, following_inferior); breakpoint_re_set (); @@ -1622,15 +1625,15 @@ infrun_inferior_exit (struct inferior *inf) } static void -infrun_inferior_execd (inferior *inf) +infrun_inferior_execd (inferior *exec_inf, inferior *follow_inf) { /* If some threads where was doing a displaced step in this inferior at the moment of the exec, they no longer exist. Even if the exec'ing thread doing a displaced step, we don't want to to any fixup nor restore displaced stepping buffer bytes. */ - inf->displaced_step_state.reset (); + follow_inf->displaced_step_state.reset (); - for (thread_info *thread : inf->threads ()) + for (thread_info *thread : follow_inf->threads ()) thread->displaced_step_state.reset (); /* Since an in-line step is done with everything else stopped, if there was @@ -1638,7 +1641,7 @@ infrun_inferior_execd (inferior *inf) thread. */ clear_step_over_info (); - inf->thread_waiting_for_vfork_done = nullptr; + follow_inf->thread_waiting_for_vfork_done = nullptr; } /* If ON, and the architecture supports it, GDB will use displaced @@ -1147,7 +1147,10 @@ jit_prepend_unwinder (struct gdbarch *gdbarch) } } -/* Register any already created translations. */ +/* Looks for the descriptor and registration symbols and breakpoints + the registration function. If it finds both, it registers all the + already JITed code. If it has already found the symbols, then it + doesn't try again. */ static void jit_inferior_init (inferior *inf) @@ -1203,10 +1206,7 @@ jit_inferior_init (inferior *inf) } } -/* Looks for the descriptor and registration symbols and breakpoints - the registration function. If it finds both, it registers all the - already JITed code. If it has already found the symbols, then it - doesn't try again. */ +/* inferior_created observer. */ static void jit_inferior_created_hook (inferior *inf) @@ -1214,6 +1214,14 @@ jit_inferior_created_hook (inferior *inf) jit_inferior_init (inf); } +/* inferior_execd observer. */ + +static void +jit_inferior_execd_hook (inferior *exec_inf, inferior *follow_inf) +{ + jit_inferior_init (follow_inf); +} + /* Exported routine to call to re-set the jit breakpoints, e.g. when a program is rerun. */ @@ -1304,7 +1312,7 @@ _initialize_jit () &maintenanceinfolist); gdb::observers::inferior_created.attach (jit_inferior_created_hook, "jit"); - gdb::observers::inferior_execd.attach (jit_inferior_created_hook, "jit"); + gdb::observers::inferior_execd.attach (jit_inferior_execd_hook, "jit"); gdb::observers::inferior_exit.attach (jit_inferior_exit_hook, "jit"); gdb::observers::breakpoint_deleted.attach (jit_breakpoint_deleted, "jit"); diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index 1fc9cb6..b5eee5e 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -244,6 +244,14 @@ invalidate_linux_cache_inf (struct inferior *inf) linux_inferior_data.clear (inf); } +/* inferior_execd observer. */ + +static void +linux_inferior_execd (inferior *exec_inf, inferior *follow_inf) +{ + invalidate_linux_cache_inf (follow_inf); +} + /* Fetch the linux cache info for INF. This function always returns a valid INFO pointer. */ @@ -2789,7 +2797,7 @@ _initialize_linux_tdep () "linux-tdep"); gdb::observers::inferior_appeared.attach (invalidate_linux_cache_inf, "linux-tdep"); - gdb::observers::inferior_execd.attach (invalidate_linux_cache_inf, + gdb::observers::inferior_execd.attach (linux_inferior_execd, "linux-tdep"); add_setshow_boolean_cmd ("use-coredump-filter", class_files, diff --git a/gdb/observable.h b/gdb/observable.h index efd0446..00955cb 100644 --- a/gdb/observable.h +++ b/gdb/observable.h @@ -90,8 +90,12 @@ extern observable<> executable_changed; information on the inferior has been printed. */ extern observable<inferior */* inferior */> inferior_created; -/* The inferior INF has exec'ed a new executable file. */ -extern observable<struct inferior */* inf */> inferior_execd; +/* The inferior EXEC_INF has exec'ed a new executable file. + + Execution continues in FOLLOW_INF, which may or may not be the same as + EXEC_INF, depending on "set follow-exec-mode". */ +extern observable<inferior */* exec_inf */, inferior */* follow_inf */> + inferior_execd; /* The status of process record for inferior inferior in gdb has changed. The process record is started if STARTED is true, and diff --git a/gdb/solib.c b/gdb/solib.c index 09bee49..1614783 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -1744,7 +1744,8 @@ _initialize_solib () { gdb::observers::free_objfile.attach (remove_user_added_objfile, "solib"); - gdb::observers::inferior_execd.attach ([] (inferior *inf) + gdb::observers::inferior_execd.attach ([] (inferior *exec_inf, + inferior *follow_inf) { solib_create_inferior_hook (0); }, "solib"); |