X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;ds=sidebyside;f=gdb%2Finfcmd.c;h=6831d6be8f93504118d9c9d9a8b1bd4a444fe550;hb=c9263853b89401a8c592669ede96947711820b48;hp=0c8b9437c66aa72aa0c0492c96b79a60346e6836;hpb=c54cfec8d4215ef2b4f8019a3431749b44ee0247;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 0c8b9437c6..6831d6be8f 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -81,6 +81,8 @@ static void float_info (char *, int); static void detach_command (char *, int); +static void disconnect_command (char *, int); + static void unset_environment_command (char *, int); static void set_environment_command (char *, int); @@ -115,8 +117,6 @@ void _initialize_infcmd (void); #define GO_USAGE "Usage: go \n" -static void breakpoint_auto_delete_contents (void *); - #define ERROR_NO_INFERIOR \ if (!target_has_execution) error ("The program is not being run."); @@ -950,112 +950,6 @@ signal_command (char *signum_exp, int from_tty) proceed (oursig == TARGET_SIGNAL_0 ? (CORE_ADDR) -1 : stop_pc, oursig, 0); } -/* Call breakpoint_auto_delete on the current contents of the bpstat - pointed to by arg (which is really a bpstat *). */ - -static void -breakpoint_auto_delete_contents (void *arg) -{ - breakpoint_auto_delete (*(bpstat *) arg); -} - - -/* Execute a "stack dummy", a piece of code stored in the stack - by the debugger to be executed in the inferior. - - To call: first, do PUSH_DUMMY_FRAME. - Then push the contents of the dummy. It should end with a breakpoint insn. - Then call here, passing address at which to start the dummy. - - The contents of all registers are saved before the dummy frame is popped - and copied into the buffer BUFFER. - - The dummy's frame is automatically popped whenever that break is hit. - If that is the first time the program stops, run_stack_dummy - returns to its caller with that frame already gone and returns 0. - - Otherwise, run_stack-dummy returns a non-zero value. - If the called function receives a random signal, we do not allow the user - to continue executing it as this may not work. The dummy frame is poped - and we return 1. - If we hit a breakpoint, we leave the frame in place and return 2 (the frame - will eventually be popped when we do hit the dummy end breakpoint). */ - -int -run_stack_dummy (CORE_ADDR addr, struct regcache *buffer) -{ - struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0); - int saved_async = 0; - struct breakpoint *bpt; - struct symtab_and_line sal; - - /* Now proceed, having reached the desired place. */ - clear_proceed_status (); - - init_sal (&sal); /* initialize to zeroes */ - if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT) - { - sal.pc = CALL_DUMMY_ADDRESS (); - } - else - { - /* If defined, CALL_DUMMY_BREAKPOINT_OFFSET is where we need to - put a breakpoint instruction. If not, the call dummy already - has the breakpoint instruction in it. - - ADDR IS THE ADDRESS of the call dummy plus the - CALL_DUMMY_START_OFFSET, so we need to subtract the - CALL_DUMMY_START_OFFSET. */ - sal.pc = addr - CALL_DUMMY_START_OFFSET + CALL_DUMMY_BREAKPOINT_OFFSET; - } - sal.section = find_pc_overlay (sal.pc); - - { - /* Set up a frame ID for the dummy frame so we can pass it to - set_momentary_breakpoint. We need to give the breakpoint a - frame ID so that the breakpoint code can correctly re-identify - the dummy breakpoint. */ - struct frame_id frame = frame_id_build (read_fp (), sal.pc); - /* Create a momentary breakpoint at the return address of the - inferior. That way it breaks when it returns. */ - bpt = set_momentary_breakpoint (sal, frame, bp_call_dummy); - bpt->disposition = disp_del; - } - - /* If all error()s out of proceed ended up calling normal_stop (and - perhaps they should; it already does in the special case of error - out of resume()), then we wouldn't need this. */ - make_cleanup (breakpoint_auto_delete_contents, &stop_bpstat); - - disable_watchpoints_before_interactive_call_start (); - proceed_to_finish = 1; /* We want stop_registers, please... */ - - if (target_can_async_p ()) - saved_async = target_async_mask (0); - - proceed (addr, TARGET_SIGNAL_0, 0); - - if (saved_async) - target_async_mask (saved_async); - - enable_watchpoints_after_interactive_call_stop (); - - discard_cleanups (old_cleanups); - - /* We can stop during an inferior call because a signal is received. */ - if (stopped_by_random_signal) - return 1; - - /* We may also stop prematurely because we hit a breakpoint in the - called routine. */ - if (!stop_stack_dummy) - return 2; - - /* On normal return, the stack dummy has been popped already. */ - regcache_cpy_no_passthrough (buffer, stop_registers); - return 0; -} - /* Proceed until we reach a different source line with pc greater than our current one or exit the function. We skip calls in both cases. @@ -1608,8 +1502,8 @@ default_print_registers_info (struct gdbarch *gdbarch, { int i; const int numregs = NUM_REGS + NUM_PSEUDO_REGS; - char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); - char *virtual_buffer = alloca (MAX_REGISTER_VIRTUAL_SIZE); + char raw_buffer[MAX_REGISTER_SIZE]; + char virtual_buffer[MAX_REGISTER_SIZE]; if (DEPRECATED_DO_REGISTERS_INFO_P ()) { @@ -1659,9 +1553,9 @@ default_print_registers_info (struct gdbarch *gdbarch, The function frame_register_read() should have returned the pre-cooked register so no conversion is necessary. */ /* Convert raw data to virtual format if necessary. */ - if (REGISTER_CONVERTIBLE (i)) + if (DEPRECATED_REGISTER_CONVERTIBLE (i)) { - REGISTER_CONVERT_TO_VIRTUAL (i, register_type (current_gdbarch, i), + DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (i, register_type (current_gdbarch, i), raw_buffer, virtual_buffer); } else @@ -1757,7 +1651,8 @@ registers_info (char *addr_exp, int fpregs) /* A register name? */ { - int regnum = frame_map_name_to_regnum (start, end - start); + int regnum = frame_map_name_to_regnum (deprecated_selected_frame, + start, end - start); if (regnum >= 0) { gdbarch_print_registers_info (current_gdbarch, gdb_stdout, @@ -1782,24 +1677,24 @@ registers_info (char *addr_exp, int fpregs) /* A register group? */ { - struct reggroup *const *group; - for (group = reggroups (current_gdbarch); - (*group) != NULL; - group++) + struct reggroup *group; + for (group = reggroup_next (current_gdbarch, NULL); + group != NULL; + group = reggroup_next (current_gdbarch, group)) { /* Don't bother with a length check. Should the user enter a short register group name, go with the first group that matches. */ - if (strncmp (start, reggroup_name ((*group)), end - start) == 0) + if (strncmp (start, reggroup_name (group), end - start) == 0) break; } - if ((*group) != NULL) + if (group != NULL) { int regnum; for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) { if (gdbarch_register_reggroup_p (current_gdbarch, regnum, - (*group))) + group)) gdbarch_print_registers_info (current_gdbarch, gdb_stdout, deprecated_selected_frame, regnum, fpregs); @@ -1914,9 +1809,9 @@ attach_command (char *args, int from_tty) don't ignore SIGSTOPs on continue requests anymore. We need a way for handle_inferior_event to reset the stop_signal variable after an attach, and this is what STOP_QUIETLY_NO_SIGSTOP is for. */ - stop_soon_quietly = STOP_QUIETLY_NO_SIGSTOP; + stop_soon = STOP_QUIETLY_NO_SIGSTOP; wait_for_inferior (); - stop_soon_quietly = NO_STOP_QUIETLY; + stop_soon = NO_STOP_QUIETLY; #endif /* @@ -1984,6 +1879,26 @@ detach_command (char *args, int from_tty) detach_hook (); } +/* Disconnect from the current target without resuming it (leaving it + waiting for a debugger). + + We'd better not have left any breakpoints in the program or the + next debugger will get confused. Currently only supported for some + remote targets, since the normal attach mechanisms don't work on + stopped processes on some native platforms (e.g. GNU/Linux). */ + +static void +disconnect_command (char *args, int from_tty) +{ + dont_repeat (); /* Not for the faint of heart */ + target_disconnect (args, from_tty); +#if defined(SOLIB_RESTART) + SOLIB_RESTART (); +#endif + if (detach_hook) + detach_hook (); +} + /* Stop the execution of the target while running in async mode, in the backgound. */ void @@ -2122,6 +2037,11 @@ to specify the program, and to load its symbol table."); If a process, it is no longer traced, and it continues its execution. If\n\ you were debugging a file, the file is closed and gdb no longer accesses it."); + add_com ("disconnect", class_run, disconnect_command, + "Disconnect from a target.\n\ +The target will wait for another debugger to connect. Not available for\n\ +all targets."); + add_com ("signal", class_run, signal_command, "Continue program giving it signal specified by the argument.\n\ An argument of \"0\" means continue program without giving it a signal.");