#include "gdbcore.h"
#include "gdbcmd.h"
#include "target.h"
-#include "thread.h"
+#include "gdbthread.h"
#include "annotate.h"
#include <signal.h>
extern void single_step (); /* Same. */
#endif /* NO_SINGLE_STEP */
+extern void write_pc_pid PARAMS ((CORE_ADDR, int));
+
\f
/* Things to clean up if we QUIT out of resume (). */
/* ARGSUSED */
CORE_ADDR stop_func_start;
CORE_ADDR stop_func_end;
char *stop_func_name;
- CORE_ADDR prologue_pc = 0, tmp;
+#if 0
+ CORE_ADDR prologue_pc = 0;
+#endif
+ CORE_ADDR tmp;
struct symtab_and_line sal;
int remove_breakpoints_on_following_step = 0;
int current_line;
else
pid = target_wait (-1, &w);
-#ifdef HAVE_NONSTEPPABLE_WATCHPOINT
+ /* Gross.
+
+ We goto this label from elsewhere in wait_for_inferior when we want
+ to continue the main loop without calling "wait" and trashing the
+ waitstatus contained in W. */
have_waited:
-#endif
flush_cached_frames ();
another thread. If so, then step that thread past the breakpoint,
and continue it. */
- if (stop_signal == TARGET_SIGNAL_TRAP
- && breakpoints_inserted
- && breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK))
+ if (stop_signal == TARGET_SIGNAL_TRAP)
{
- random_signal = 0;
- if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK, pid))
- {
- /* Saw a breakpoint, but it was hit by the wrong thread. Just continue. */
- write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, pid);
+#ifdef NO_SINGLE_STEP
+ if (one_stepped)
+ random_signal = 0;
+ else
+#endif
+ if (breakpoints_inserted
+ && breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK))
+ {
+ random_signal = 0;
+ if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK, pid))
+ {
+ /* Saw a breakpoint, but it was hit by the wrong thread. Just continue. */
+ write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, pid);
- remove_breakpoints ();
- target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */
- /* FIXME: What if a signal arrives instead of the single-step
- happening? */
+ remove_breakpoints ();
+ target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */
+ /* FIXME: What if a signal arrives instead of the single-step
+ happening? */
- if (target_wait_hook)
- target_wait_hook (pid, &w);
- else
- target_wait (pid, &w);
- insert_breakpoints ();
+ if (target_wait_hook)
+ target_wait_hook (pid, &w);
+ else
+ target_wait (pid, &w);
+ insert_breakpoints ();
- /* We need to restart all the threads now. */
- target_resume (-1, 0, TARGET_SIGNAL_0);
- continue;
- }
+ /* We need to restart all the threads now. */
+ target_resume (-1, 0, TARGET_SIGNAL_0);
+ continue;
+ }
+ }
}
else
random_signal = 1;
if (INSTRUCTION_NULLIFIED)
{
- resume (1, 0);
- continue;
+ struct target_waitstatus tmpstatus;
+
+ registers_changed ();
+ target_resume (pid, 1, TARGET_SIGNAL_0);
+
+ /* We may have received a signal that we want to pass to
+ the inferior; therefore, we must not clobber the waitstatus
+ in W. So we call wait ourselves, then continue the loop
+ at the "have_waited" label. */
+ if (target_wait_hook)
+ target_wait_hook (pid, &tmpstatus);
+ else
+ target_wait (pid, &tmpstatus);
+
+
+ goto have_waited;
}
#ifdef HAVE_STEPPABLE_WATCHPOINT
{
extern int auto_solib_add;
+ /* Remove breakpoints, we eventually want to step over the
+ shlib event breakpoint, and SOLIB_ADD might adjust
+ breakpoint addresses via breakpoint_re_set. */
+ if (breakpoints_inserted)
+ remove_breakpoints ();
+ breakpoints_inserted = 0;
+
/* Check for any newly added shared libraries if we're
supposed to be adding them automatically. */
if (auto_solib_add)
{
- /* Remove breakpoints, SOLIB_ADD might adjust breakpoint
- addresses via breakpoint_re_set. */
- if (breakpoints_inserted)
- remove_breakpoints ();
- breakpoints_inserted = 0;
-
/* Switch terminal for any messages produced by
breakpoint_re_set. */
target_terminal_ours_for_output ();
SOLIB_ADD (NULL, 0, NULL);
+ re_enable_breakpoints_in_shlibs ();
target_terminal_inferior ();
}
{
/* We want to step over this breakpoint, then keep going. */
another_trap = 1;
- remove_breakpoints_on_following_step = 1;
break;
}
}