diff options
author | Jeff Law <law@redhat.com> | 1996-01-23 21:06:34 +0000 |
---|---|---|
committer | Jeff Law <law@redhat.com> | 1996-01-23 21:06:34 +0000 |
commit | 87273c713f0e22999692252d3dcdbb5613ab5729 (patch) | |
tree | 72dfac044f46de43245498f663f6d03a918ad3b9 /gdb/infrun.c | |
parent | b96e1ce4f80e86b0f31901b5af49d571d3c65ed1 (diff) | |
download | gdb-87273c713f0e22999692252d3dcdbb5613ab5729.zip gdb-87273c713f0e22999692252d3dcdbb5613ab5729.tar.gz gdb-87273c713f0e22999692252d3dcdbb5613ab5729.tar.bz2 |
* symfile.c (auto_solib_add): Renamed from auto_solib_add_at_startup.
All references changed.
* breakpoint.c (bpstat_what): Add shlib_event to the class types.
Update state table. Reformat so that it's still readable.
When we hit the shlib_event breakpoint, set the calss of shlib_event.
(breakpoint_1): Add "shlib events" as a breakpoint type.
Print the shlib_event breakpoint like other breakpoints.
(create_solib_event_breakpoint): New function.
(breakpoint_re_set_one): Handle solib_event breakpoints.
* breakpoint.h (enum bytype): Add bp_shlib_event breakpoint type.
(enum bpstat_what_main_action): Add BPSTAT_WHAT_CHECK_SHLIBS
action.
(create_solib_event_breakpoint): Declare.
* infrun.c (wait_for_inferior): Handle CHECK_SHLIBS bpstat.
(normal_stop): Inform the user when the inferior stoped due
to a shared library event.
(_initialize_infrun): Add new set/show variable "stop_on-solib-events"
to control whether or not gdb continues the inferior or stops it when
a shared library event occurs.
* minsyms.c (lookup_minimal_symbol_solib_trampoline): New function.
* somsolib.c (TODO list): Update.
(som_solib_create_inferior_hook): Arrange for gdb to be notified
when significant shared library events occur.
* hppa-tdep.c (find_unwind_entry): No longer static.
First cut at the machine independent changes for 7363. Also includes
code to automatically track shl_load/shl_unload calls on hpux.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r-- | gdb/infrun.c | 86 |
1 files changed, 83 insertions, 3 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c index 73647aa..19ff2d3 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1,5 +1,5 @@ /* Target-struct-independent code to start (run) and stop an inferior process. - Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994 + Copyright 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. This file is part of GDB. @@ -72,6 +72,21 @@ static int hook_stop_stub PARAMS ((char *)); #define SKIP_TRAMPOLINE_CODE(pc) 0 #endif +/* Dynamic function trampolines are similar to solib trampolines in that they + are between the caller and the callee. The difference is that when you + enter a dynamic trampoline, you can't determine the callee's address. Some + (usually complex) code needs to run in the dynamic trampoline to figure out + the callee's address. This macro is usually called twice. First, when we + enter the trampoline (looks like a normal function call at that point). It + should return the PC of a point within the trampoline where the callee's + address is known. Second, when we hit the breakpoint, this routine returns + the callee's address. At that point, things proceed as per a step resume + breakpoint. */ + +#ifndef DYNAMIC_TRAMPOLINE_NEXTPC +#define DYNAMIC_TRAMPOLINE_NEXTPC(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. */ @@ -136,6 +151,10 @@ static struct symbol *step_start_function; static int trap_expected; +/* Nonzero if we want to give control to the user when we're notified + of shared library events by the dynamic linker. */ +static int stop_on_solib_events; + #ifdef HP_OS_BUG /* Nonzero if the next time we try to continue the inferior, it will step one instruction and generate a spurious trace trap. @@ -1015,6 +1034,35 @@ wait_for_inferior () another_trap = 1; break; +#ifdef SOLIB_ADD + case BPSTAT_WHAT_CHECK_SHLIBS: + { + extern int auto_solib_add; + + /* Check for any newly added shared libraries if we're + supposed to be adding them automatically. */ + if (auto_solib_add) + SOLIB_ADD (NULL, 0, NULL); + + /* If requested, stop when the dynamic linker notifies + gdb of events. This allows the user to get control + and place breakpoints in initializer routines for + dynamically loaded objects (among other things). */ + if (stop_on_solib_events) + { + stop_print_frame = 0; + goto stop_stepping; + } + else + { + /* We want to step over this breakpoint, then keep going. */ + another_trap = 1; + remove_breakpoints_on_following_step = 1; + break; + } + } +#endif + case BPSTAT_WHAT_LAST: /* Not a real code, but listed here to shut up gcc -Wall. */ @@ -1208,8 +1256,9 @@ wait_for_inferior () handling_longjmp stuff is working. */ )) #else -/* This is experimental code which greatly simplifies the subroutine call - test. I've actually tested on the Alpha, and it works great. -Stu */ + /* This test is a much more streamlined, (but hopefully correct) + replacement for the code above. It's been tested on the Sparc, + Mips, PA, and Power architectures with good results. */ if (stop_pc == stop_func_start /* Quick test */ || in_prologue (stop_pc, stop_func_start) @@ -1241,6 +1290,22 @@ wait_for_inferior () tmp = SKIP_TRAMPOLINE_CODE (stop_pc); if (tmp != 0) stop_func_start = tmp; + else + { + tmp = DYNAMIC_TRAMPOLINE_NEXTPC (stop_pc); + if (tmp) + { + struct symtab_and_line xxx; + + xxx.pc = tmp; + xxx.symtab = NULL; + xxx.line = 0; + step_resume_breakpoint = + set_momentary_breakpoint (xxx, NULL, bp_step_resume); + insert_breakpoints (); + goto keep_going; + } + } /* If we have line number information for the function we are thinking of stepping into, step into it. @@ -1593,6 +1658,9 @@ Further execution is probably impossible.\n"); target_terminal_ours (); + if (stop_bpstat && stop_bpstat->breakpoint_at->type == bp_shlib_event) + printf_filtered ("Stopped due to shared library event\n"); + /* Look up the hook_stop and run it if it exists. */ if (stop_command->hook) @@ -2121,4 +2189,16 @@ of the program stops.", &cmdlist); signal_print[TARGET_SIGNAL_POLL] = 0; signal_stop[TARGET_SIGNAL_URG] = 0; signal_print[TARGET_SIGNAL_URG] = 0; + +#ifdef SOLIB_ADD + add_show_from_set + (add_set_cmd ("stop-on-solib-events", class_support, var_zinteger, + (char *) &stop_on_solib_events, + "Set stopping for shared library events.\n\ +If nonzero, gdb will give control to the user when the dynamic linker\n\ +notifies gdb of shared library events. The most common event of interest\n\ +to the user would be loading/unloading of a new library.\n", + &setlist), + &showlist); +#endif } |