|
|
|
@ -1,6 +1,6 @@ |
|
|
|
/* Target-struct-independent code to start (run) and stop an inferior process.
|
|
|
|
Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996 |
|
|
|
Free Software Foundation, Inc. |
|
|
|
Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, |
|
|
|
1998 Free Software Foundation, Inc. |
|
|
|
|
|
|
|
This file is part of GDB. |
|
|
|
|
|
|
|
@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
|
|
|
#include "target.h" |
|
|
|
#include "gdbthread.h" |
|
|
|
#include "annotate.h" |
|
|
|
#include "symfile.h" /* for overlay functions */ |
|
|
|
|
|
|
|
#include <signal.h> |
|
|
|
|
|
|
|
@ -82,6 +83,15 @@ static void delete_breakpoint_current_contents PARAMS ((PTR)); |
|
|
|
#define DYNAMIC_TRAMPOLINE_NEXTPC(pc) 0 |
|
|
|
#endif |
|
|
|
|
|
|
|
/* On SVR4 based systems, determining the callee's address is exceedingly
|
|
|
|
difficult and depends on the implementation of the run time loader. |
|
|
|
If we are stepping at the source level, we single step until we exit |
|
|
|
the run time loader code and reach the callee's address. */ |
|
|
|
|
|
|
|
#ifndef IN_SOLIB_DYNSYM_RESOLVE_CODE |
|
|
|
#define IN_SOLIB_DYNSYM_RESOLVE_CODE(pc) 0 |
|
|
|
#endif |
|
|
|
|
|
|
|
/* For SVR4 shared libraries, each call goes through a small piece of
|
|
|
|
trampoline code in the ".plt" section. IN_SOLIB_CALL_TRAMPOLINE evaluates |
|
|
|
to nonzero if we are current stopped in one of these. */ |
|
|
|
@ -489,6 +499,10 @@ wait_for_inferior () |
|
|
|
|
|
|
|
while (1) |
|
|
|
{ |
|
|
|
extern int overlay_cache_invalid; /* declared in symfile.h */ |
|
|
|
|
|
|
|
overlay_cache_invalid = 1; |
|
|
|
|
|
|
|
/* We have to invalidate the registers BEFORE calling target_wait because
|
|
|
|
they can be loaded from the target while in target_wait. This makes |
|
|
|
remote debugging a bit more efficient for those targets that provide |
|
|
|
@ -512,11 +526,12 @@ wait_for_inferior () |
|
|
|
|
|
|
|
/* If it's a new process, add it to the thread database */ |
|
|
|
|
|
|
|
if (pid != inferior_pid |
|
|
|
if (w.kind != TARGET_WAITKIND_EXITED |
|
|
|
&& pid != inferior_pid |
|
|
|
&& !in_thread_list (pid)) |
|
|
|
{ |
|
|
|
fprintf_unfiltered (gdb_stderr, "[New %s]\n", target_pid_to_str (pid)); |
|
|
|
add_thread (pid); |
|
|
|
printf_filtered ("[New %s]\n", target_pid_to_str (pid)); |
|
|
|
|
|
|
|
/* We may want to consider not doing a resume here in order to give
|
|
|
|
the user a chance to play with the new thread. It might be good |
|
|
|
@ -533,12 +548,35 @@ wait_for_inferior () |
|
|
|
switch (w.kind) |
|
|
|
{ |
|
|
|
case TARGET_WAITKIND_LOADED: |
|
|
|
/* Ignore it gracefully. */ |
|
|
|
/* Ignore gracefully during startup of the inferior, as it
|
|
|
|
might be the shell which has just loaded some objects, |
|
|
|
otherwise add the symbols for the newly loaded objects. */ |
|
|
|
#ifdef SOLIB_ADD |
|
|
|
if (!stop_soon_quietly) |
|
|
|
{ |
|
|
|
extern int auto_solib_add; |
|
|
|
|
|
|
|
/* Remove breakpoints, SOLIB_ADD might adjust
|
|
|
|
breakpoint addresses via breakpoint_re_set. */ |
|
|
|
if (breakpoints_inserted) |
|
|
|
remove_breakpoints (); |
|
|
|
|
|
|
|
/* Check for any newly added shared libraries if we're
|
|
|
|
supposed to be adding them automatically. */ |
|
|
|
if (auto_solib_add) |
|
|
|
{ |
|
|
|
mark_breakpoints_out (); |
|
|
|
/* Switch terminal for any messages produced by
|
|
|
|
breakpoint_re_set. */ |
|
|
|
target_terminal_ours_for_output (); |
|
|
|
SOLIB_ADD (NULL, 0, NULL); |
|
|
|
target_terminal_inferior (); |
|
|
|
} |
|
|
|
|
|
|
|
/* Reinsert breakpoints and continue. */ |
|
|
|
if (breakpoints_inserted) |
|
|
|
insert_breakpoints (); |
|
|
|
} |
|
|
|
#endif |
|
|
|
resume (0, TARGET_SIGNAL_0); |
|
|
|
continue; |
|
|
|
|
|
|
|
@ -710,7 +748,6 @@ wait_for_inferior () |
|
|
|
&step_frame_address, &handling_longjmp, |
|
|
|
&another_trap); |
|
|
|
printf_filtered ("[Switching to %s]\n", target_pid_to_str (pid)); |
|
|
|
|
|
|
|
flush_cached_frames (); |
|
|
|
} |
|
|
|
|
|
|
|
@ -778,6 +815,7 @@ wait_for_inferior () |
|
|
|
write_pc (stop_pc - DECR_PC_AFTER_BREAK); |
|
|
|
|
|
|
|
remove_breakpoints (); |
|
|
|
registers_changed(); |
|
|
|
target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */ |
|
|
|
|
|
|
|
if (target_wait_hook) |
|
|
|
@ -1181,6 +1219,13 @@ wait_for_inferior () |
|
|
|
|
|
|
|
/* We stepped out of the stepping range. */ |
|
|
|
|
|
|
|
/* If we are stepping at the source level and entered the runtime
|
|
|
|
loader dynamic symbol resolution code, we keep on single stepping |
|
|
|
until we exit the run time loader code and reach the callee's |
|
|
|
address. */ |
|
|
|
if (step_over_calls < 0 && IN_SOLIB_DYNSYM_RESOLVE_CODE (stop_pc)) |
|
|
|
goto keep_going; |
|
|
|
|
|
|
|
/* We can't update step_sp every time through the loop, because
|
|
|
|
reading the stack pointer would slow down stepping too much. |
|
|
|
But we can update it every time we leave the step range. */ |
|
|
|
@ -1208,6 +1253,7 @@ wait_for_inferior () |
|
|
|
|
|
|
|
INIT_SAL (&sr_sal); /* initialize to zeroes */ |
|
|
|
sr_sal.pc = prev_pc; |
|
|
|
sr_sal.section = find_pc_overlay (sr_sal.pc); |
|
|
|
/* We could probably be setting the frame to
|
|
|
|
step_frame_address; I don't think anyone thought to try it. */ |
|
|
|
step_resume_breakpoint = |
|
|
|
@ -1344,6 +1390,7 @@ wait_for_inferior () |
|
|
|
other s_a_l's where this code is duplicated? */ |
|
|
|
INIT_SAL (&xxx); /* initialize to zeroes */ |
|
|
|
xxx.pc = tmp; |
|
|
|
xxx.section = find_pc_overlay (xxx.pc); |
|
|
|
step_resume_breakpoint = |
|
|
|
set_momentary_breakpoint (xxx, NULL, bp_step_resume); |
|
|
|
insert_breakpoints (); |
|
|
|
@ -1373,11 +1420,12 @@ step_over_function: |
|
|
|
|
|
|
|
INIT_SAL (&sr_sal); /* initialize to zeroes */ |
|
|
|
sr_sal.pc = |
|
|
|
ADDR_BITS_REMOVE |
|
|
|
(SAVED_PC_AFTER_CALL (get_current_frame ())); |
|
|
|
ADDR_BITS_REMOVE (SAVED_PC_AFTER_CALL (get_current_frame ())); |
|
|
|
sr_sal.section = find_pc_overlay (sr_sal.pc); |
|
|
|
step_resume_breakpoint = |
|
|
|
set_momentary_breakpoint (sr_sal, get_current_frame (), |
|
|
|
bp_step_resume); |
|
|
|
if (!IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc)) |
|
|
|
step_resume_breakpoint->frame = step_frame_address; |
|
|
|
if (breakpoints_inserted) |
|
|
|
insert_breakpoints (); |
|
|
|
@ -1422,6 +1470,7 @@ step_into_function: |
|
|
|
|
|
|
|
INIT_SAL (&sr_sal); /* initialize to zeroes */ |
|
|
|
sr_sal.pc = stop_func_start; |
|
|
|
sr_sal.section = find_pc_overlay (stop_func_start); |
|
|
|
/* Do not specify what the fp should be when we stop
|
|
|
|
since on some machines the prologue |
|
|
|
is where the new fp value is established. */ |
|
|
|
@ -1465,6 +1514,7 @@ step_into_function: |
|
|
|
|
|
|
|
INIT_SAL (&sr_sal); /* initialize to zeroes */ |
|
|
|
sr_sal.pc = tmp; |
|
|
|
sr_sal.section = find_pc_overlay (sr_sal.pc); |
|
|
|
/* Do not specify what the fp should be when we stop
|
|
|
|
since on some machines the prologue |
|
|
|
is where the new fp value is established. */ |
|
|
|
@ -1544,6 +1594,7 @@ step_into_function: |
|
|
|
|
|
|
|
INIT_SAL (&sr_sal); /* initialize to zeroes */ |
|
|
|
sr_sal.pc = prev_pc; |
|
|
|
sr_sal.section = find_pc_overlay (sr_sal.pc); |
|
|
|
/* We perhaps could set the frame if we kept track of what
|
|
|
|
the frame corresponding to prev_pc was. But we don't, |
|
|
|
so don't. */ |
|
|
|
@ -1803,9 +1854,12 @@ sig_print_info (oursig) |
|
|
|
enum target_signal oursig; |
|
|
|
{ |
|
|
|
char *name = target_signal_to_name (oursig); |
|
|
|
int name_padding = 13 - strlen (name); |
|
|
|
if (name_padding <= 0) |
|
|
|
name_padding = 0; |
|
|
|
|
|
|
|
printf_filtered ("%s", name); |
|
|
|
printf_filtered ("%*.*s ", 13 - strlen (name), 13 - strlen (name), |
|
|
|
" "); |
|
|
|
printf_filtered ("%*.*s ", name_padding, name_padding, " "); |
|
|
|
printf_filtered ("%s\t", signal_stop[oursig] ? "Yes" : "No"); |
|
|
|
printf_filtered ("%s\t", signal_print[oursig] ? "Yes" : "No"); |
|
|
|
printf_filtered ("%s\t\t", signal_program[oursig] ? "Yes" : "No"); |
|
|
|
|