static struct gdb_exception run_inferior_call (struct thread_info *call_thread, CORE_ADDR real_pc) { volatile struct gdb_exception e; int saved_in_infcall = call_thread->control.in_infcall; ptid_t call_thread_ptid = call_thread->ptid; call_thread->control.in_infcall = 1; clear_proceed_status (); disable_watchpoints_before_interactive_call_start (); /* We want stop_registers, please... */ call_thread->control.proceed_to_finish = 1; TRY_CATCH (e, RETURN_MASK_ALL) { proceed (real_pc, TARGET_SIGNAL_0, 0); /* Inferior function calls are always synchronous, even if the target supports asynchronous execution. Do here what `proceed' itself does in sync mode. */ if (target_can_async_p () && is_running (inferior_ptid)) { wait_for_inferior (); normal_stop (); } }
static void osf_solib_create_inferior_hook (void) { /* Nothing to do for statically bound executables. */ if (symfile_objfile == NULL || symfile_objfile->obfd == NULL || ((bfd_get_file_flags (symfile_objfile->obfd) & DYNAMIC) == 0)) return; /* Now run the target. It will eventually get a SIGTRAP, at which point all of the libraries will have been mapped in and we can go groveling around in the rld structures to find out what we need to know about them. */ clear_proceed_status (); stop_soon = STOP_QUIETLY; stop_signal = TARGET_SIGNAL_0; do { target_resume (minus_one_ptid, 0, stop_signal); wait_for_inferior (0); } while (stop_signal != TARGET_SIGNAL_TRAP); /* solib_add will call reinit_frame_cache. But we are stopped in the runtime loader and we do not have symbols for the runtime loader. So heuristic_proc_start will be called and will put out an annoying warning. Delaying the resetting of stop_soon until after symbol loading suppresses the warning. */ solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add); stop_soon = NO_STOP_QUIETLY; }
void startup_inferior (int ntraps) { int pending_execs = ntraps; int terminal_initted = 0; /* The process was started by the fork that created it, but it will have stopped one instruction after execing the shell. Here we must get it up to actual execution of the real program. */ clear_proceed_status (); init_wait_for_inferior (); inferior_ignoring_leading_exec_events = target_reported_exec_events_per_exec_call () - 1; while (1) { /* Make wait_for_inferior be quiet. */ stop_soon = STOP_QUIETLY; wait_for_inferior (); if (stop_signal != TARGET_SIGNAL_TRAP) { /* Let shell child handle its own signals in its own way. FIXME: what if child has exited? Must exit loop somehow. */ resume (0, stop_signal); } else { /* We handle SIGTRAP, however; it means child did an exec. */ if (!terminal_initted) { /* Now that the child has exec'd we know it has already set its process group. On POSIX systems, tcsetpgrp will fail with EPERM if we try it before the child's setpgid. */ /* Set up the "saved terminal modes" of the inferior based on what modes we are starting it with. */ target_terminal_init (); /* Install inferior's terminal modes. */ target_terminal_inferior (); terminal_initted = 1; } if (--pending_execs == 0) break; resume (0, TARGET_SIGNAL_0); /* Just make it go on. */ } } stop_soon = NO_STOP_QUIETLY; }
static void osf_solib_create_inferior_hook (int from_tty) { struct inferior *inf; struct thread_info *tp; inf = current_inferior (); /* If we are attaching to the inferior, the shared libraries have already been mapped, so nothing more to do. */ if (inf->attach_flag) return; /* Nothing to do for statically bound executables. */ if (symfile_objfile == NULL || symfile_objfile->obfd == NULL || ((bfd_get_file_flags (symfile_objfile->obfd) & DYNAMIC) == 0)) return; /* Now run the target. It will eventually get a SIGTRAP, at which point all of the libraries will have been mapped in and we can go groveling around in the rld structures to find out what we need to know about them. If debugging from a core file, we cannot resume the execution of the inferior. But this is actually not an issue, because shared libraries have already been mapped anyways, which means we have nothing more to do. */ if (!target_can_run (¤t_target)) return; tp = inferior_thread (); clear_proceed_status (); inf->stop_soon = STOP_QUIETLY; tp->stop_signal = TARGET_SIGNAL_0; do { target_resume (minus_one_ptid, 0, tp->stop_signal); wait_for_inferior (0); } while (tp->stop_signal != TARGET_SIGNAL_TRAP); /* solib_add will call reinit_frame_cache. But we are stopped in the runtime loader and we do not have symbols for the runtime loader. So heuristic_proc_start will be called and will put out an annoying warning. Delaying the resetting of stop_soon until after symbol loading suppresses the warning. */ solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add); inf->stop_soon = NO_STOP_QUIETLY; }
static struct gdb_exception run_inferior_call (struct thread_info *call_thread, CORE_ADDR real_pc) { volatile struct gdb_exception e; int saved_in_infcall = call_thread->control.in_infcall; ptid_t call_thread_ptid = call_thread->ptid; int saved_sync_execution = sync_execution; /* Infcalls run synchronously, in the foreground. */ if (target_can_async_p ()) sync_execution = 1; call_thread->control.in_infcall = 1; clear_proceed_status (); disable_watchpoints_before_interactive_call_start (); /* We want stop_registers, please... */ call_thread->control.proceed_to_finish = 1; TRY_CATCH (e, RETURN_MASK_ALL) { int was_sync = sync_execution; proceed (real_pc, GDB_SIGNAL_0, 0); /* Inferior function calls are always synchronous, even if the target supports asynchronous execution. Do here what `proceed' itself does in sync mode. */ if (target_can_async_p ()) { wait_for_inferior (); normal_stop (); /* If GDB was previously in sync execution mode, then ensure that it remains so. normal_stop calls async_enable_stdin, so reset it again here. In other cases, stdin will be re-enabled by inferior_event_handler, when an exception is thrown. */ if (was_sync) async_disable_stdin (); } }
void BE_hook_kill(BE_hook * hook) { if (!hook) return; BE_hook_disable(hook); if (hook->event->type == BE_EVENT_B) { //remove breakpoint //TODO What happens if there is more than one event for this breakpoint?? //interrupt and delete breakpoint execute_command("interrupt",0); wait_for_inferior(); normal_stop(); char arg[15]; sprintf(arg, "%d", hook->event->edata.b.bp_id); delete_command(arg,0); //continue continue_command_JG(); } }
void BE_update_callgraph() { printf("\nUpdate Call Graph!\n"); execute_command("interrupt",0); wait_for_inferior(); normal_stop(); struct ME_CG * stack; BE_get_call_stack_as_CG(NULL, 0, 0, 1, &stack, the_context.FT); continue_command_JG(); if (!the_context.CG) { the_context.CG = stack; } else { ME_CG_merge_stack(the_context.CG,stack); ME_CG_delete(stack); } ME_CG_print(the_context.CG,the_context.FT); //execute_command("detach",1); }
/*============================================================*/ void BE_hook_array_handle(int breaked, char * filename, int line, int bp_id) { //check event_t int i = 0; for (i=0; i<the_context.hook_array.count;i++) { BE_hook * curr = BE_hook_array_get(i); clock_t t = clock(); if (curr->enabled) { switch (curr->event->type) { case BE_EVENT_T: if (t >= curr->event->edata.t.start + curr->event->edata.t.delay) { //stop if not stopped if (!the_context.stopped) { //Abstract this away execute_command("interrupt",0); wait_for_inferior(); normal_stop(); BE_get_file_and_line(get_selected_frame(NULL), &filename, &line); //put these in the BEC the_context.stopped = true; //continue_command_JG(); } BE_hook_handle(curr); if (curr->event->repeat) { curr->event->edata.t.start = t; } else { curr->enabled = false; } } break; case BE_EVENT_B: break; } } } //check event_b for (i=0; i<the_context.hook_array.count;i++) { BE_hook * curr = BE_hook_array_get(i); if (curr->enabled) { switch (curr->event->type) { case BE_EVENT_T: break; case BE_EVENT_B: if (breaked) { if (bp_id == curr->event->edata.b.bp_id) { printf("At the breakpoint for this event!\n"); BE_hook_handle(curr); printf("Event handled\n"); if (!curr->event->repeat) { char arg[15]; sprintf(arg, "%d", curr->event->edata.b.bp_id); delete_command(arg,0); curr->enabled = 0; } } } } } } }
static void haiku_init_debug_create_inferior(int pid) { extern int stop_after_trap; // fix inferior_ptid -- fork_inferior() sets the process ID only inferior_ptid = ptid_build (pid, 0, pid); // team ID == team main thread ID under Haiku haiku_init_child_debugging(pid, false); // eat the initial `debugged' event caused by wait_for_inferior() // TODO: Maybe we should just dequeue the event and continue the thread instead // of using gdb's mechanism, since I don't know what undesired side-effects // they may have. clear_proceed_status (); init_wait_for_inferior (); if (STARTUP_WITH_SHELL) inferior_ignoring_startup_exec_events = 2; else inferior_ignoring_startup_exec_events = 1; inferior_ignoring_leading_exec_events = 0; while (true) { thread_debug_info *thread; stop_soon = STOP_QUIETLY; wait_for_inferior(); if (stop_signal == TARGET_SIGNAL_TRAP) { thread = haiku_find_thread(&sTeamDebugInfo, pid); if (thread && thread->stopped && thread->last_event->message == B_DEBUGGER_MESSAGE_IMAGE_CREATED && thread->last_event->data.image_created.info.type == B_APP_IMAGE && thread->reprocess_event == 0 && inferior_ignoring_startup_exec_events <= 0) { // This is the trap for the last (second, if started via shell) // `load app image' event. Be done. break; } } resume(0, stop_signal); } stop_soon = NO_STOP_QUIETLY; // load shared library symbols target_terminal_ours_for_output (); SOLIB_ADD (NULL, 0, ¤t_target, auto_solib_add); target_terminal_inferior (); // startup_inferior (START_INFERIOR_TRAPS_EXPECTED); //while (1) { // stop_after_trap = 1; // wait_for_inferior (); // if (debugThread && stop_signal != TARGET_SIGNAL_TRAP) // resume (0, stop_signal); // else // break; //} //stop_after_trap = 0; // while (1) { // thread_debug_info *thread; // // stop_after_trap = 1; // wait_for_inferior (); //// TODO: Catch deadly events, so that we won't block here. // // thread = haiku_find_thread(&sTeamDebugInfo, pid); //TRACE(("haiku_init_debug_create_inferior(): wait_for_inferior() returned: " //"thread: %p (%ld)\n", thread, (thread ? thread->thread : -1))); // if (thread && thread->stopped // && thread->last_event->message // == B_DEBUGGER_MESSAGE_IMAGE_CREATED // && thread->last_event->data.image_created.info.type // == B_APP_IMAGE) { //TRACE(("haiku_init_debug_create_inferior(): Got an `app image created' " //"message\n")); // break; // } // // resume (0, stop_signal); // } }