mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-07-15 05:01:13 +08:00
* dbxread.c, partial-stab.h (near N_SO): SO stabs with blank
names mean end of .o file. * infrun.c (wait_for_inferior): Clean up multi-thread logic near top of routine. Handle new thread notification cleanly. * lynx-nat.c (child_wait): General cleanups, handle new LynxOS thread notification scheme. * (child_resume): General cleanups, handle resumption of all threads properly.
This commit is contained in:
@ -1,3 +1,14 @@
|
|||||||
|
Tue Jun 28 15:28:01 1994 Stu Grossman (grossman@cygnus.com)
|
||||||
|
|
||||||
|
* dbxread.c, partial-stab.h (near N_SO): SO stabs with blank
|
||||||
|
names mean end of .o file.
|
||||||
|
* infrun.c (wait_for_inferior): Clean up multi-thread logic near
|
||||||
|
top of routine. Handle new thread notification cleanly.
|
||||||
|
* lynx-nat.c (child_wait): General cleanups, handle new LynxOS
|
||||||
|
thread notification scheme.
|
||||||
|
* (child_resume): General cleanups, handle resumption of all
|
||||||
|
threads properly.
|
||||||
|
|
||||||
Mon Jun 27 09:57:23 1994 Steve Chamberlain (sac@cirdan.cygnus.com)
|
Mon Jun 27 09:57:23 1994 Steve Chamberlain (sac@cirdan.cygnus.com)
|
||||||
|
|
||||||
* ser-go32.c: Rewrite to run under windows.
|
* ser-go32.c: Rewrite to run under windows.
|
||||||
|
@ -1903,11 +1903,16 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
|
|||||||
end_symtab (valu, 0, 0, objfile, SECT_OFF_TEXT);
|
end_symtab (valu, 0, 0, objfile, SECT_OFF_TEXT);
|
||||||
end_stabs ();
|
end_stabs ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Null name means this just marks the end of text for this .o file.
|
||||||
|
Don't start a new symtab in this case. */
|
||||||
|
if (*name == '\000')
|
||||||
|
break;
|
||||||
|
|
||||||
start_stabs ();
|
start_stabs ();
|
||||||
start_symtab (name, NULL, valu);
|
start_symtab (name, NULL, valu);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case N_SOL:
|
case N_SOL:
|
||||||
/* This type of symbol indicates the start of data for
|
/* This type of symbol indicates the start of data for
|
||||||
a sub-source-file, one whose contents were copied or
|
a sub-source-file, one whose contents were copied or
|
||||||
@ -2358,12 +2363,13 @@ elfstab_build_psymtabs (objfile, section_offsets, mainline,
|
|||||||
|
|
||||||
void
|
void
|
||||||
stabsect_build_psymtabs (objfile, section_offsets, mainline, stab_name,
|
stabsect_build_psymtabs (objfile, section_offsets, mainline, stab_name,
|
||||||
stabstr_name)
|
stabstr_name, text_name)
|
||||||
struct objfile *objfile;
|
struct objfile *objfile;
|
||||||
struct section_offsets *section_offsets;
|
struct section_offsets *section_offsets;
|
||||||
int mainline;
|
int mainline;
|
||||||
char *stab_name;
|
char *stab_name;
|
||||||
char *stabstr_name;
|
char *stabstr_name;
|
||||||
|
char *text_name;
|
||||||
{
|
{
|
||||||
int val;
|
int val;
|
||||||
bfd *sym_bfd = objfile->obfd;
|
bfd *sym_bfd = objfile->obfd;
|
||||||
@ -2384,9 +2390,9 @@ stabsect_build_psymtabs (objfile, section_offsets, mainline, stab_name,
|
|||||||
objfile->sym_stab_info = (PTR) xmalloc (sizeof (struct dbx_symfile_info));
|
objfile->sym_stab_info = (PTR) xmalloc (sizeof (struct dbx_symfile_info));
|
||||||
memset (DBX_SYMFILE_INFO (objfile), 0, sizeof (struct dbx_symfile_info));
|
memset (DBX_SYMFILE_INFO (objfile), 0, sizeof (struct dbx_symfile_info));
|
||||||
|
|
||||||
DBX_TEXT_SECT (objfile) = bfd_get_section_by_name (sym_bfd, ".text");
|
DBX_TEXT_SECT (objfile) = bfd_get_section_by_name (sym_bfd, text_name);
|
||||||
if (!DBX_TEXT_SECT (objfile))
|
if (!DBX_TEXT_SECT (objfile))
|
||||||
error ("Can't find .text section in symbol file");
|
error ("Can't find %s section in symbol file", text_name);
|
||||||
|
|
||||||
DBX_SYMBOL_SIZE (objfile) = sizeof (struct external_nlist);
|
DBX_SYMBOL_SIZE (objfile) = sizeof (struct external_nlist);
|
||||||
DBX_SYMCOUNT (objfile) = bfd_section_size (sym_bfd, stabsect)
|
DBX_SYMCOUNT (objfile) = bfd_section_size (sym_bfd, stabsect)
|
||||||
@ -2422,36 +2428,6 @@ stabsect_build_psymtabs (objfile, section_offsets, mainline, stab_name,
|
|||||||
dbx_symfile_read (objfile, section_offsets, 0);
|
dbx_symfile_read (objfile, section_offsets, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scan and build partial symbols for a SOM symbol file.
|
|
||||||
This SOM file has already been processed to get its minimal symbols.
|
|
||||||
|
|
||||||
OBJFILE is the object file we are reading symbols from.
|
|
||||||
ADDR is the address relative to which the symbols are (e.g.
|
|
||||||
the base address of the text segment).
|
|
||||||
MAINLINE is true if we are reading the main symbol
|
|
||||||
table (as opposed to a shared lib or dynamically loaded file).
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
somstab_build_psymtabs (objfile, section_offsets, mainline)
|
|
||||||
struct objfile *objfile;
|
|
||||||
struct section_offsets *section_offsets;
|
|
||||||
int mainline;
|
|
||||||
{
|
|
||||||
free_header_files ();
|
|
||||||
init_header_files ();
|
|
||||||
|
|
||||||
/* This is needed to debug objects assembled with gas2. */
|
|
||||||
processing_acc_compilation = 1;
|
|
||||||
|
|
||||||
/* In a SOM file, we've already installed the minimal symbols that came
|
|
||||||
from the SOM (non-stab) symbol table, so always act like an
|
|
||||||
incremental load here. */
|
|
||||||
|
|
||||||
dbx_symfile_read (objfile, section_offsets, mainline);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse the user's idea of an offset for dynamic linking, into our idea
|
/* Parse the user's idea of an offset for dynamic linking, into our idea
|
||||||
of how to represent it for fast symbol reading. */
|
of how to represent it for fast symbol reading. */
|
||||||
|
|
||||||
|
234
gdb/infrun.c
234
gdb/infrun.c
@ -294,6 +294,24 @@ proceed (addr, siggnal, step)
|
|||||||
else
|
else
|
||||||
write_pc (addr);
|
write_pc (addr);
|
||||||
|
|
||||||
|
#ifdef PREPARE_TO_PROCEED
|
||||||
|
/* In a multi-threaded task we may select another thread and then continue.
|
||||||
|
|
||||||
|
In this case the thread that stopped at a breakpoint will immediately
|
||||||
|
cause another stop, if it is not stepped over first. On the other hand,
|
||||||
|
if (ADDR != -1) we only want to single step over the breakpoint if we did
|
||||||
|
switch to another thread.
|
||||||
|
|
||||||
|
If we are single stepping, don't do any of the above.
|
||||||
|
(Note that in the current implementation single stepping another
|
||||||
|
thread after a breakpoint and then continuing will cause the original
|
||||||
|
breakpoint to be hit again, but you can always continue, so it's not
|
||||||
|
a big deal.) */
|
||||||
|
|
||||||
|
if (! step && PREPARE_TO_PROCEED && breakpoint_here_p (read_pc ()))
|
||||||
|
oneproc = 1;
|
||||||
|
#endif /* PREPARE_TO_PROCEED */
|
||||||
|
|
||||||
if (trap_expected_after_continue)
|
if (trap_expected_after_continue)
|
||||||
{
|
{
|
||||||
/* If (step == 0), a trap will be automatically generated after
|
/* If (step == 0), a trap will be automatically generated after
|
||||||
@ -437,11 +455,25 @@ wait_for_inferior ()
|
|||||||
|
|
||||||
while (1)
|
while (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
|
||||||
|
critical registers as part of their normal status mechanism. */
|
||||||
|
|
||||||
|
registers_changed ();
|
||||||
|
|
||||||
pid = target_wait (-1, &w);
|
pid = target_wait (-1, &w);
|
||||||
|
|
||||||
/* Clean up saved state that will become invalid. */
|
|
||||||
flush_cached_frames ();
|
flush_cached_frames ();
|
||||||
registers_changed ();
|
|
||||||
|
/* If it's a new process, add it to the thread database */
|
||||||
|
|
||||||
|
if (pid != inferior_pid
|
||||||
|
&& !in_thread_list (pid))
|
||||||
|
{
|
||||||
|
fprintf_unfiltered (gdb_stderr, "[New %s]\n", target_pid_to_str (pid));
|
||||||
|
add_thread (pid);
|
||||||
|
}
|
||||||
|
|
||||||
switch (w.kind)
|
switch (w.kind)
|
||||||
{
|
{
|
||||||
@ -507,125 +539,104 @@ wait_for_inferior ()
|
|||||||
|
|
||||||
stop_signal = w.value.sig;
|
stop_signal = w.value.sig;
|
||||||
|
|
||||||
if (pid != inferior_pid)
|
stop_pc = read_pc_pid (pid);
|
||||||
{
|
|
||||||
int save_pid = inferior_pid;
|
|
||||||
|
|
||||||
inferior_pid = pid; /* Setup for target memory/regs */
|
/* See if a thread hit a thread-specific breakpoint that was meant for
|
||||||
registers_changed ();
|
another thread. If so, then step that thread past the breakpoint,
|
||||||
stop_pc = read_pc ();
|
and continue it. */
|
||||||
inferior_pid = save_pid;
|
|
||||||
registers_changed ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
stop_pc = read_pc ();
|
|
||||||
|
|
||||||
if (stop_signal == TARGET_SIGNAL_TRAP
|
if (stop_signal == TARGET_SIGNAL_TRAP
|
||||||
|
&& breakpoints_inserted
|
||||||
&& breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK))
|
&& breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK))
|
||||||
{
|
{
|
||||||
|
random_signal = 0;
|
||||||
if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK, pid))
|
if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK, pid))
|
||||||
{
|
{
|
||||||
/* Saw a breakpoint, but it was hit by the wrong thread. Just continue. */
|
/* Saw a breakpoint, but it was hit by the wrong thread. Just continue. */
|
||||||
if (breakpoints_inserted)
|
write_pc (stop_pc - DECR_PC_AFTER_BREAK);
|
||||||
{
|
|
||||||
if (pid != inferior_pid)
|
|
||||||
{
|
|
||||||
int save_pid = inferior_pid;
|
|
||||||
|
|
||||||
inferior_pid = pid;
|
remove_breakpoints ();
|
||||||
registers_changed ();
|
target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */
|
||||||
write_pc (stop_pc - DECR_PC_AFTER_BREAK);
|
/* FIXME: What if a signal arrives instead of the single-step
|
||||||
inferior_pid = save_pid;
|
happening? */
|
||||||
registers_changed ();
|
target_wait (pid, &w);
|
||||||
}
|
insert_breakpoints ();
|
||||||
else
|
target_resume (pid, 0, TARGET_SIGNAL_0);
|
||||||
write_pc (stop_pc - DECR_PC_AFTER_BREAK);
|
|
||||||
|
|
||||||
remove_breakpoints ();
|
|
||||||
target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */
|
|
||||||
/* FIXME: What if a signal arrives instead of the single-step
|
|
||||||
happening? */
|
|
||||||
target_wait (pid, &w);
|
|
||||||
insert_breakpoints ();
|
|
||||||
}
|
|
||||||
target_resume (-1, 0, TARGET_SIGNAL_0);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if (pid != inferior_pid)
|
|
||||||
goto switch_thread;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
random_signal = 1;
|
||||||
|
|
||||||
|
/* See if something interesting happened to the non-current thread. If
|
||||||
|
so, then switch to that thread, and eventually give control back to
|
||||||
|
the user. */
|
||||||
|
|
||||||
if (pid != inferior_pid)
|
if (pid != inferior_pid)
|
||||||
{
|
{
|
||||||
int printed = 0;
|
int printed = 0;
|
||||||
|
|
||||||
if (!in_thread_list (pid))
|
/* If it's a random signal for a non-current thread, notify user
|
||||||
{
|
if he's expressed an interest. */
|
||||||
fprintf_unfiltered (gdb_stderr, "[New %s]\n", target_pid_to_str (pid));
|
|
||||||
add_thread (pid);
|
|
||||||
|
|
||||||
target_resume (-1, 0, TARGET_SIGNAL_0);
|
if (random_signal
|
||||||
|
&& signal_print[stop_signal])
|
||||||
|
{
|
||||||
|
printed = 1;
|
||||||
|
target_terminal_ours_for_output ();
|
||||||
|
printf_filtered ("\nProgram received signal %s, %s.\n",
|
||||||
|
target_signal_to_name (stop_signal),
|
||||||
|
target_signal_to_string (stop_signal));
|
||||||
|
gdb_flush (gdb_stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If it's not SIGTRAP and not a signal we want to stop for, then
|
||||||
|
continue the thread. */
|
||||||
|
|
||||||
|
if (stop_signal != TARGET_SIGNAL_TRAP
|
||||||
|
&& !signal_stop[stop_signal])
|
||||||
|
{
|
||||||
|
if (printed)
|
||||||
|
target_terminal_inferior ();
|
||||||
|
|
||||||
|
/* Clear the signal if it should not be passed. */
|
||||||
|
if (signal_program[stop_signal] == 0)
|
||||||
|
stop_signal = TARGET_SIGNAL_0;
|
||||||
|
|
||||||
|
target_resume (pid, 0, stop_signal);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/* It's a SIGTRAP or a signal we're interested in. Switch threads,
|
||||||
|
and fall into the rest of wait_for_inferior(). */
|
||||||
|
|
||||||
|
inferior_pid = pid;
|
||||||
|
printf_filtered ("[Switching to %s]\n", target_pid_to_str (pid));
|
||||||
|
|
||||||
|
flush_cached_frames ();
|
||||||
|
trap_expected = 0;
|
||||||
|
if (step_resume_breakpoint)
|
||||||
{
|
{
|
||||||
if (signal_print[stop_signal])
|
delete_breakpoint (step_resume_breakpoint);
|
||||||
{
|
step_resume_breakpoint = NULL;
|
||||||
printed = 1;
|
|
||||||
target_terminal_ours_for_output ();
|
|
||||||
printf_filtered ("\nProgram received signal %s, %s.\n",
|
|
||||||
target_signal_to_name (stop_signal),
|
|
||||||
target_signal_to_string (stop_signal));
|
|
||||||
gdb_flush (gdb_stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stop_signal == TARGET_SIGNAL_TRAP
|
|
||||||
|| signal_stop[stop_signal])
|
|
||||||
{
|
|
||||||
switch_thread:
|
|
||||||
inferior_pid = pid;
|
|
||||||
printf_filtered ("[Switching to %s]\n", target_pid_to_str (pid));
|
|
||||||
|
|
||||||
flush_cached_frames ();
|
|
||||||
registers_changed ();
|
|
||||||
trap_expected = 0;
|
|
||||||
if (step_resume_breakpoint)
|
|
||||||
{
|
|
||||||
delete_breakpoint (step_resume_breakpoint);
|
|
||||||
step_resume_breakpoint = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Not sure whether we need to blow this away too,
|
|
||||||
but probably it is like the step-resume
|
|
||||||
breakpoint. */
|
|
||||||
if (through_sigtramp_breakpoint)
|
|
||||||
{
|
|
||||||
delete_breakpoint (through_sigtramp_breakpoint);
|
|
||||||
through_sigtramp_breakpoint = NULL;
|
|
||||||
}
|
|
||||||
prev_pc = 0;
|
|
||||||
prev_sp = 0;
|
|
||||||
prev_func_name = NULL;
|
|
||||||
step_range_start = 0;
|
|
||||||
step_range_end = 0;
|
|
||||||
step_frame_address = 0;
|
|
||||||
handling_longjmp = 0;
|
|
||||||
another_trap = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (printed)
|
|
||||||
target_terminal_inferior ();
|
|
||||||
|
|
||||||
/* Clear the signal if it should not be passed. */
|
|
||||||
if (signal_program[stop_signal] == 0)
|
|
||||||
stop_signal = TARGET_SIGNAL_0;
|
|
||||||
|
|
||||||
target_resume (pid, 0, stop_signal);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Not sure whether we need to blow this away too,
|
||||||
|
but probably it is like the step-resume
|
||||||
|
breakpoint. */
|
||||||
|
if (through_sigtramp_breakpoint)
|
||||||
|
{
|
||||||
|
delete_breakpoint (through_sigtramp_breakpoint);
|
||||||
|
through_sigtramp_breakpoint = NULL;
|
||||||
|
}
|
||||||
|
prev_pc = 0;
|
||||||
|
prev_sp = 0;
|
||||||
|
prev_func_name = NULL;
|
||||||
|
step_range_start = 0;
|
||||||
|
step_range_end = 0;
|
||||||
|
step_frame_address = 0;
|
||||||
|
handling_longjmp = 0;
|
||||||
|
another_trap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NO_SINGLE_STEP
|
#ifdef NO_SINGLE_STEP
|
||||||
@ -1061,12 +1072,19 @@ switch_thread:
|
|||||||
goto keep_going;
|
goto keep_going;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
if (stop_func_start)
|
if (stop_func_start)
|
||||||
{
|
{
|
||||||
|
struct symtab *s;
|
||||||
|
|
||||||
/* Do this after the IN_SIGTRAMP check; it might give
|
/* Do this after the IN_SIGTRAMP check; it might give
|
||||||
an error. */
|
an error. */
|
||||||
prologue_pc = stop_func_start;
|
prologue_pc = stop_func_start;
|
||||||
SKIP_PROLOGUE (prologue_pc);
|
|
||||||
|
/* Don't skip the prologue if this is assembly source */
|
||||||
|
s = find_pc_symtab (stop_pc);
|
||||||
|
if (s && s->language != language_asm)
|
||||||
|
SKIP_PROLOGUE (prologue_pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((/* Might be a non-recursive call. If the symbols are missing
|
if ((/* Might be a non-recursive call. If the symbols are missing
|
||||||
@ -1105,6 +1123,14 @@ switch_thread:
|
|||||||
which can no longer happen here as long as the
|
which can no longer happen here as long as the
|
||||||
handling_longjmp stuff is working. */
|
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 */
|
||||||
|
|
||||||
|
if (in_prologue (stop_pc, NULL)
|
||||||
|
|| (prev_func_start != 0
|
||||||
|
&& stop_func_start == 0))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* It's a subroutine call. */
|
/* It's a subroutine call. */
|
||||||
|
|
||||||
@ -1166,7 +1192,13 @@ step_over_function:
|
|||||||
step_into_function:
|
step_into_function:
|
||||||
/* Subroutine call with source code we should not step over.
|
/* Subroutine call with source code we should not step over.
|
||||||
Do step to the first line of code in it. */
|
Do step to the first line of code in it. */
|
||||||
SKIP_PROLOGUE (stop_func_start);
|
{
|
||||||
|
struct symtab *s;
|
||||||
|
|
||||||
|
s = find_pc_symtab (stop_pc);
|
||||||
|
if (s && s->language != language_asm)
|
||||||
|
SKIP_PROLOGUE (stop_func_start);
|
||||||
|
}
|
||||||
sal = find_pc_line (stop_func_start, 0);
|
sal = find_pc_line (stop_func_start, 0);
|
||||||
/* Use the step_resume_break to step until
|
/* Use the step_resume_break to step until
|
||||||
the end of the prologue, even if that involves jumps
|
the end of the prologue, even if that involves jumps
|
||||||
|
@ -597,7 +597,7 @@ child_wait (pid, ourstatus)
|
|||||||
{
|
{
|
||||||
int save_errno;
|
int save_errno;
|
||||||
int thread;
|
int thread;
|
||||||
int status;
|
union wait status;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -632,8 +632,7 @@ child_wait (pid, ourstatus)
|
|||||||
if (pid != PIDGET (inferior_pid)) /* Some other process?!? */
|
if (pid != PIDGET (inferior_pid)) /* Some other process?!? */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* thread = WIFTID (status);*/
|
thread = status.w_tid; /* Get thread id from status */
|
||||||
thread = status >> 16;
|
|
||||||
|
|
||||||
/* Initial thread value can only be acquired via wait, so we have to
|
/* Initial thread value can only be acquired via wait, so we have to
|
||||||
resort to this hack. */
|
resort to this hack. */
|
||||||
@ -646,7 +645,26 @@ child_wait (pid, ourstatus)
|
|||||||
|
|
||||||
pid = BUILDPID (pid, thread);
|
pid = BUILDPID (pid, thread);
|
||||||
|
|
||||||
store_waitstatus (ourstatus, status);
|
if (WIFSTOPPED(status)
|
||||||
|
&& WSTOPSIG(status) == SIGTRAP
|
||||||
|
&& !in_thread_list (pid))
|
||||||
|
{
|
||||||
|
int realsig;
|
||||||
|
|
||||||
|
realsig = ptrace (PTRACE_GETTRACESIG, pid, 0);
|
||||||
|
|
||||||
|
if (realsig == SIGNEWTHREAD)
|
||||||
|
{
|
||||||
|
/* Simply ignore new thread notification, as we can't do anything
|
||||||
|
useful with such threads. All ptrace calls at this point just
|
||||||
|
fail for no apparent reason. The thread will eventually get a
|
||||||
|
real signal when it becomes real. */
|
||||||
|
child_resume (pid, 0, TARGET_SIGNAL_0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
store_waitstatus (ourstatus, status.w_status);
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
@ -662,13 +680,18 @@ child_resume (pid, step, signal)
|
|||||||
int step;
|
int step;
|
||||||
enum target_signal signal;
|
enum target_signal signal;
|
||||||
{
|
{
|
||||||
|
int func;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
/* Resume all threads. */
|
{
|
||||||
/* I think this only gets used in the non-threaded case, where "resume
|
/* Resume all threads. */
|
||||||
all threads" and "resume inferior_pid" are the same. */
|
|
||||||
pid = inferior_pid;
|
pid = inferior_pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
func = step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT;
|
||||||
|
|
||||||
/* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where
|
/* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where
|
||||||
it was. (If GDB wanted it to start some other way, we have already
|
it was. (If GDB wanted it to start some other way, we have already
|
||||||
@ -679,12 +702,7 @@ child_resume (pid, step, signal)
|
|||||||
continue request (by setting breakpoints on all possible successor
|
continue request (by setting breakpoints on all possible successor
|
||||||
instructions), so we don't have to worry about that here. */
|
instructions), so we don't have to worry about that here. */
|
||||||
|
|
||||||
if (step)
|
ptrace (func, pid, (PTRACE_ARG3_TYPE) 1, target_signal_to_host (signal));
|
||||||
ptrace (PTRACE_SINGLESTEP_ONE, pid, (PTRACE_ARG3_TYPE) 1,
|
|
||||||
target_signal_to_host (signal));
|
|
||||||
else
|
|
||||||
ptrace (PTRACE_CONT_ONE, pid, (PTRACE_ARG3_TYPE) 1,
|
|
||||||
target_signal_to_host (signal));
|
|
||||||
|
|
||||||
if (errno)
|
if (errno)
|
||||||
perror_with_name ("ptrace");
|
perror_with_name ("ptrace");
|
||||||
|
Reference in New Issue
Block a user