mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-29 06:50:32 +00:00
* gdbserver/remote-utils.c (write_ok): Write "OK", not "Ok", to
match stubs and protocol spec. * gdbserver/remote-utils.c (remote_open): Cast to struct sockaddr when passing to function which expects that. The following changes aren't quite enough to make things work with LynxOS (apprently kernel problems). * infrun.c (wait_for_inferior): When resuming new thread, pass pid not -1 for remote case. * thread.c (info_threads_command): Give error if !target_has_stack. * infrun.c (start_remote): Call init_thread_list. * thread.c (info_threads_command): Don't call kill for remote debugging target. * target.c (normal_pid_to_str): Print "thread" not "process" for remote. * remote.c, gdbserver/*: Add 'H', 'S', and 'C' requests, 'X' response, and `thread' part of 'T' response. * gdbserver/*: If program exits, send packet to GDB before exiting. Handle termination with a signal the same as exiting with an exitstatus. * remote.c: Don't try to kill program after getting an 'X' response. * infrun.c (wait_for_inferior): Add comment about kill versus mourn.
This commit is contained in:
parent
4181c9853b
commit
4cc1b3f79d
@ -1,3 +1,29 @@
|
|||||||
|
Wed Dec 7 14:50:54 1994 Jim Kingdon <kingdon@deneb.cygnus.com>
|
||||||
|
|
||||||
|
* gdbserver/remote-utils.c (write_ok): Write "OK", not "Ok", to
|
||||||
|
match stubs and protocol spec.
|
||||||
|
* gdbserver/remote-utils.c (remote_open): Cast to struct sockaddr
|
||||||
|
when passing to function which expects that.
|
||||||
|
|
||||||
|
The following changes aren't quite enough to make things work with
|
||||||
|
LynxOS (apprently kernel problems).
|
||||||
|
* infrun.c (wait_for_inferior): When resuming new thread, pass pid
|
||||||
|
not -1 for remote case.
|
||||||
|
* thread.c (info_threads_command): Give error if !target_has_stack.
|
||||||
|
* infrun.c (start_remote): Call init_thread_list.
|
||||||
|
* thread.c (info_threads_command): Don't call kill for remote
|
||||||
|
debugging target.
|
||||||
|
* target.c (normal_pid_to_str): Print "thread" not "process" for
|
||||||
|
remote.
|
||||||
|
* remote.c, gdbserver/*: Add 'H', 'S', and 'C' requests, 'X'
|
||||||
|
response, and `thread' part of 'T' response.
|
||||||
|
* gdbserver/*: If program exits, send packet to GDB before
|
||||||
|
exiting. Handle termination with a signal the same as exiting
|
||||||
|
with an exitstatus.
|
||||||
|
* remote.c: Don't try to kill program after getting an 'X'
|
||||||
|
response.
|
||||||
|
* infrun.c (wait_for_inferior): Add comment about kill versus mourn.
|
||||||
|
|
||||||
Thu Dec 8 12:37:38 1994 Rob Savoye <rob@darkstar.cygnus.com>
|
Thu Dec 8 12:37:38 1994 Rob Savoye <rob@darkstar.cygnus.com>
|
||||||
|
|
||||||
* config/pa/tm-pro.h tm-hppap.h, hppapro.mt: Rename tm-hppap.h to
|
* config/pa/tm-pro.h tm-hppap.h, hppapro.mt: Rename tm-hppap.h to
|
||||||
|
@ -108,33 +108,57 @@ mywait (status)
|
|||||||
int pid;
|
int pid;
|
||||||
union wait w;
|
union wait w;
|
||||||
|
|
||||||
enable_async_io();
|
while (1)
|
||||||
|
{
|
||||||
|
enable_async_io();
|
||||||
|
|
||||||
pid = wait (&w);
|
pid = wait (&w);
|
||||||
|
|
||||||
disable_async_io();
|
disable_async_io();
|
||||||
|
|
||||||
if (pid != PIDGET(inferior_pid))
|
if (pid != PIDGET(inferior_pid))
|
||||||
perror_with_name ("wait");
|
perror_with_name ("wait");
|
||||||
|
|
||||||
inferior_pid = BUILDPID (inferior_pid, w.w_tid);
|
thread_from_wait = w.w_tid;
|
||||||
|
inferior_pid = BUILDPID (inferior_pid, w.w_tid);
|
||||||
|
printf ("mywait: pid=0x%x, thread=0x%x, inferior_pid=0x%x\n",
|
||||||
|
pid, w.w_tid, inferior_pid);
|
||||||
|
|
||||||
|
if (WIFSTOPPED(w)
|
||||||
|
&& WSTOPSIG(w) == SIGTRAP)
|
||||||
|
{
|
||||||
|
int realsig;
|
||||||
|
|
||||||
|
realsig = ptrace (PTRACE_GETTRACESIG, inferior_pid,
|
||||||
|
(PTRACE_ARG3_TYPE)0, 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. */
|
||||||
|
myresume (0, 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (WIFEXITED (w))
|
if (WIFEXITED (w))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "\nChild exited with status %d\n", WEXITSTATUS (w));
|
*status = 'W';
|
||||||
fprintf (stderr, "GDBserver exiting\n");
|
return ((unsigned char) WEXITSTATUS (w));
|
||||||
exit (0);
|
|
||||||
}
|
}
|
||||||
else if (!WIFSTOPPED (w))
|
else if (!WIFSTOPPED (w))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
|
*status = 'X';
|
||||||
*status = 'T';
|
|
||||||
return ((unsigned char) WTERMSIG (w));
|
return ((unsigned char) WTERMSIG (w));
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch_inferior_registers (0);
|
fetch_inferior_registers (0);
|
||||||
|
|
||||||
*status = 'S';
|
*status = 'T';
|
||||||
return ((unsigned char) WSTOPSIG (w));
|
return ((unsigned char) WSTOPSIG (w));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +172,9 @@ myresume (step, signal)
|
|||||||
int signal;
|
int signal;
|
||||||
{
|
{
|
||||||
errno = 0;
|
errno = 0;
|
||||||
ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
|
ptrace (step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT,
|
||||||
|
BUILDPID (inferior_pid, cont_thread == -1 ? 0 : cont_thread),
|
||||||
|
1, signal);
|
||||||
if (errno)
|
if (errno)
|
||||||
perror_with_name ("ptrace");
|
perror_with_name ("ptrace");
|
||||||
}
|
}
|
||||||
@ -334,7 +360,9 @@ fetch_inferior_registers (regno)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
retval = ptrace (PTRACE_GETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &ec,
|
retval = ptrace (PTRACE_GETREGS,
|
||||||
|
BUILDPID (inferior_pid, general_thread),
|
||||||
|
(PTRACE_ARG3_TYPE) &ec,
|
||||||
0);
|
0);
|
||||||
if (errno)
|
if (errno)
|
||||||
perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
|
perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
|
||||||
@ -387,7 +415,7 @@ fetch_inferior_registers (regno)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
retval = ptrace (PTRACE_GETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &fc,
|
retval = ptrace (PTRACE_GETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) &fc,
|
||||||
0);
|
0);
|
||||||
if (errno)
|
if (errno)
|
||||||
perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
|
perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
|
||||||
@ -446,7 +474,7 @@ store_inferior_registers (regno)
|
|||||||
8 * REGISTER_RAW_SIZE (O0_REGNUM));
|
8 * REGISTER_RAW_SIZE (O0_REGNUM));
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
retval = ptrace (PTRACE_SETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &ec,
|
retval = ptrace (PTRACE_SETREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) &ec,
|
||||||
0);
|
0);
|
||||||
if (errno)
|
if (errno)
|
||||||
perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
|
perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
|
||||||
@ -493,7 +521,7 @@ store_inferior_registers (regno)
|
|||||||
|
|
||||||
/* We read fcontext first so that we can get good values for fq_t... */
|
/* We read fcontext first so that we can get good values for fq_t... */
|
||||||
errno = 0;
|
errno = 0;
|
||||||
retval = ptrace (PTRACE_GETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &fc,
|
retval = ptrace (PTRACE_GETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) &fc,
|
||||||
0);
|
0);
|
||||||
if (errno)
|
if (errno)
|
||||||
perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
|
perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
|
||||||
@ -504,7 +532,7 @@ store_inferior_registers (regno)
|
|||||||
fc.fsr = read_register (FPS_REGNUM);
|
fc.fsr = read_register (FPS_REGNUM);
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
retval = ptrace (PTRACE_SETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &fc,
|
retval = ptrace (PTRACE_SETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) &fc,
|
||||||
0);
|
0);
|
||||||
if (errno)
|
if (errno)
|
||||||
perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
|
perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
|
||||||
@ -526,12 +554,12 @@ lynx_registers_addr()
|
|||||||
CORE_ADDR ecp;
|
CORE_ADDR ecp;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, inferior_pid,
|
stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, BUILDPID (inferior_pid, general_thread),
|
||||||
(PTRACE_ARG3_TYPE)0, 0);
|
(PTRACE_ARG3_TYPE)0, 0);
|
||||||
if (errno)
|
if (errno)
|
||||||
perror_with_name ("PTRACE_THREADUSER");
|
perror_with_name ("PTRACE_THREADUSER");
|
||||||
|
|
||||||
ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, inferior_pid,
|
ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, BUILDPID (inferior_pid, general_thread),
|
||||||
(PTRACE_ARG3_TYPE)ecpoff, 0);
|
(PTRACE_ARG3_TYPE)ecpoff, 0);
|
||||||
if (errno)
|
if (errno)
|
||||||
perror_with_name ("lynx_registers_addr(PTRACE_PEEKTHREAD)");
|
perror_with_name ("lynx_registers_addr(PTRACE_PEEKTHREAD)");
|
||||||
@ -562,7 +590,7 @@ fetch_inferior_registers (ignored)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
reg = ptrace (ptrace_fun, inferior_pid,
|
reg = ptrace (ptrace_fun, BUILDPID (inferior_pid, general_thread),
|
||||||
(PTRACE_ARG3_TYPE) (ecp + regmap[regno]), 0);
|
(PTRACE_ARG3_TYPE) (ecp + regmap[regno]), 0);
|
||||||
if (errno)
|
if (errno)
|
||||||
perror_with_name ("fetch_inferior_registers(PTRACE_PEEKTHREAD)");
|
perror_with_name ("fetch_inferior_registers(PTRACE_PEEKTHREAD)");
|
||||||
@ -596,7 +624,7 @@ store_inferior_registers (ignored)
|
|||||||
reg = *(unsigned long *)®isters[REGISTER_BYTE (regno)];
|
reg = *(unsigned long *)®isters[REGISTER_BYTE (regno)];
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
ptrace (ptrace_fun, inferior_pid,
|
ptrace (ptrace_fun, BUILDPID (inferior_pid, general_thread),
|
||||||
(PTRACE_ARG3_TYPE) (ecp + regmap[regno]), reg);
|
(PTRACE_ARG3_TYPE) (ecp + regmap[regno]), reg);
|
||||||
if (errno)
|
if (errno)
|
||||||
perror_with_name ("PTRACE_POKEUSER");
|
perror_with_name ("PTRACE_POKEUSER");
|
||||||
@ -632,7 +660,7 @@ read_inferior_memory (memaddr, myaddr, len)
|
|||||||
/* Read all the longwords */
|
/* Read all the longwords */
|
||||||
for (i = 0; i < count; i++, addr += sizeof (int))
|
for (i = 0; i < count; i++, addr += sizeof (int))
|
||||||
{
|
{
|
||||||
buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
|
buffer[i] = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread), addr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy appropriate bytes out of the buffer. */
|
/* Copy appropriate bytes out of the buffer. */
|
||||||
@ -662,12 +690,12 @@ write_inferior_memory (memaddr, myaddr, len)
|
|||||||
|
|
||||||
/* Fill start and end extra bytes of buffer with existing memory data. */
|
/* Fill start and end extra bytes of buffer with existing memory data. */
|
||||||
|
|
||||||
buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
|
buffer[0] = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread), addr, 0);
|
||||||
|
|
||||||
if (count > 1)
|
if (count > 1)
|
||||||
{
|
{
|
||||||
buffer[count - 1]
|
buffer[count - 1]
|
||||||
= ptrace (PTRACE_PEEKTEXT, inferior_pid,
|
= ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread),
|
||||||
addr + (count - 1) * sizeof (int), 0);
|
addr + (count - 1) * sizeof (int), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,10 +710,13 @@ write_inferior_memory (memaddr, myaddr, len)
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
errno = 0;
|
errno = 0;
|
||||||
ptrace (PTRACE_POKETEXT, inferior_pid, addr, buffer[i]);
|
ptrace (PTRACE_POKETEXT, BUILDPID (inferior_pid, general_thread), addr, buffer[i]);
|
||||||
if (errno)
|
if (errno)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ptrace (PTRACE_POKETEXT): errno=%d, inferior_pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n", errno, inferior_pid, addr, buffer[i]);
|
fprintf(stderr, "\
|
||||||
|
ptrace (PTRACE_POKETEXT): errno=%d, pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n",
|
||||||
|
errno, BUILDPID (inferior_pid, general_thread),
|
||||||
|
addr, buffer[i]);
|
||||||
fprintf(stderr, "Sleeping for 1 second\n");
|
fprintf(stderr, "Sleeping for 1 second\n");
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
@ -114,19 +114,19 @@ mywait (status)
|
|||||||
if (WIFEXITED (w))
|
if (WIFEXITED (w))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
|
fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
|
||||||
*status = 'E';
|
*status = 'W';
|
||||||
return ((unsigned char) WEXITSTATUS (w));
|
return ((unsigned char) WEXITSTATUS (w));
|
||||||
}
|
}
|
||||||
else if (!WIFSTOPPED (w))
|
else if (!WIFSTOPPED (w))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
|
fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
|
||||||
*status = 'T';
|
*status = 'X';
|
||||||
return ((unsigned char) WTERMSIG (w));
|
return ((unsigned char) WTERMSIG (w));
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch_inferior_registers (0);
|
fetch_inferior_registers (0);
|
||||||
|
|
||||||
*status = 'S';
|
*status = 'T';
|
||||||
return ((unsigned char) WSTOPSIG (w));
|
return ((unsigned char) WSTOPSIG (w));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,19 +111,19 @@ mywait (status)
|
|||||||
if (WIFEXITED (w))
|
if (WIFEXITED (w))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
|
fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
|
||||||
*status = 'E';
|
*status = 'W';
|
||||||
return ((unsigned char) WEXITSTATUS (w));
|
return ((unsigned char) WEXITSTATUS (w));
|
||||||
}
|
}
|
||||||
else if (!WIFSTOPPED (w))
|
else if (!WIFSTOPPED (w))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
|
fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
|
||||||
*status = 'T';
|
*status = 'X';
|
||||||
return ((unsigned char) WTERMSIG (w));
|
return ((unsigned char) WTERMSIG (w));
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch_inferior_registers (0);
|
fetch_inferior_registers (0);
|
||||||
|
|
||||||
*status = 'S';
|
*status = 'T';
|
||||||
return ((unsigned char) WSTOPSIG (w));
|
return ((unsigned char) WSTOPSIG (w));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
86
gdb/infrun.c
86
gdb/infrun.c
@ -43,26 +43,22 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
|
|
||||||
/* Prototypes for local functions */
|
/* Prototypes for local functions */
|
||||||
|
|
||||||
static void
|
static void signals_info PARAMS ((char *, int));
|
||||||
signals_info PARAMS ((char *, int));
|
|
||||||
|
|
||||||
static void
|
static void handle_command PARAMS ((char *, int));
|
||||||
handle_command PARAMS ((char *, int));
|
|
||||||
|
|
||||||
static void sig_print_info PARAMS ((enum target_signal));
|
static void sig_print_info PARAMS ((enum target_signal));
|
||||||
|
|
||||||
static void
|
static void sig_print_header PARAMS ((void));
|
||||||
sig_print_header PARAMS ((void));
|
|
||||||
|
|
||||||
static void
|
static void resume_cleanups PARAMS ((int));
|
||||||
resume_cleanups PARAMS ((int));
|
|
||||||
|
|
||||||
static int
|
static int hook_stop_stub PARAMS ((char *));
|
||||||
hook_stop_stub PARAMS ((char *));
|
|
||||||
|
|
||||||
/* GET_LONGJMP_TARGET returns the PC at which longjmp() will resume the
|
/* GET_LONGJMP_TARGET returns the PC at which longjmp() will resume the
|
||||||
program. It needs to examine the jmp_buf argument and extract the PC
|
program. It needs to examine the jmp_buf argument and extract the PC
|
||||||
from it. The return value is non-zero on success, zero otherwise. */
|
from it. The return value is non-zero on success, zero otherwise. */
|
||||||
|
|
||||||
#ifndef GET_LONGJMP_TARGET
|
#ifndef GET_LONGJMP_TARGET
|
||||||
#define GET_LONGJMP_TARGET(PC_ADDR) 0
|
#define GET_LONGJMP_TARGET(PC_ADDR) 0
|
||||||
#endif
|
#endif
|
||||||
@ -71,15 +67,24 @@ hook_stop_stub PARAMS ((char *));
|
|||||||
/* Some machines have trampoline code that sits between function callers
|
/* Some machines have trampoline code that sits between function callers
|
||||||
and the actual functions themselves. If this machine doesn't have
|
and the actual functions themselves. If this machine doesn't have
|
||||||
such things, disable their processing. */
|
such things, disable their processing. */
|
||||||
|
|
||||||
#ifndef SKIP_TRAMPOLINE_CODE
|
#ifndef SKIP_TRAMPOLINE_CODE
|
||||||
#define SKIP_TRAMPOLINE_CODE(pc) 0
|
#define SKIP_TRAMPOLINE_CODE(pc) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* For SVR4 shared libraries, each call goes through a small piece of
|
/* For SVR4 shared libraries, each call goes through a small piece of
|
||||||
trampoline code in the ".plt" section. IN_SOLIB_TRAMPOLINE evaluates
|
trampoline code in the ".plt" section. IN_SOLIB_CALL_TRAMPOLINE evaluates
|
||||||
to nonzero if we are current stopped in one of these. */
|
to nonzero if we are current stopped in one of these. */
|
||||||
#ifndef IN_SOLIB_TRAMPOLINE
|
|
||||||
#define IN_SOLIB_TRAMPOLINE(pc,name) 0
|
#ifndef IN_SOLIB_CALL_TRAMPOLINE
|
||||||
|
#define IN_SOLIB_CALL_TRAMPOLINE(pc,name) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* In some shared library schemes, the return path from a shared library
|
||||||
|
call may need to go through a trampoline too. */
|
||||||
|
|
||||||
|
#ifndef IN_SOLIB_RETURN_TRAMPOLINE
|
||||||
|
#define IN_SOLIB_RETURN_TRAMPOLINE(pc,name) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* On some systems, the PC may be left pointing at an instruction that won't
|
/* On some systems, the PC may be left pointing at an instruction that won't
|
||||||
@ -371,6 +376,7 @@ static char *prev_func_name;
|
|||||||
void
|
void
|
||||||
start_remote ()
|
start_remote ()
|
||||||
{
|
{
|
||||||
|
init_thread_list ();
|
||||||
init_wait_for_inferior ();
|
init_wait_for_inferior ();
|
||||||
clear_proceed_status ();
|
clear_proceed_status ();
|
||||||
stop_soon_quietly = 1;
|
stop_soon_quietly = 1;
|
||||||
@ -522,7 +528,14 @@ wait_for_inferior ()
|
|||||||
stop_signal = w.value.sig;
|
stop_signal = w.value.sig;
|
||||||
target_terminal_ours (); /* Must do this before mourn anyway */
|
target_terminal_ours (); /* Must do this before mourn anyway */
|
||||||
annotate_signalled ();
|
annotate_signalled ();
|
||||||
|
|
||||||
|
/* This looks pretty bogus to me. Doesn't TARGET_WAITKIND_SIGNALLED
|
||||||
|
mean it is already dead? This has been here since GDB 2.8, so
|
||||||
|
perhaps it means rms didn't understand unix waitstatuses?
|
||||||
|
For the moment I'm just kludging around this in remote.c
|
||||||
|
rather than trying to change it here --kingdon, 5 Dec 1994. */
|
||||||
target_kill (); /* kill mourns as well */
|
target_kill (); /* kill mourns as well */
|
||||||
|
|
||||||
printf_filtered ("\nProgram terminated with signal ");
|
printf_filtered ("\nProgram terminated with signal ");
|
||||||
annotate_signal_name ();
|
annotate_signal_name ();
|
||||||
printf_filtered ("%s", target_signal_to_name (stop_signal));
|
printf_filtered ("%s", target_signal_to_name (stop_signal));
|
||||||
@ -1142,7 +1155,7 @@ wait_for_inferior ()
|
|||||||
call. I'm not completely sure this is necessary now that we
|
call. I'm not completely sure this is necessary now that we
|
||||||
have the above checks with stop_func_start (and now that
|
have the above checks with stop_func_start (and now that
|
||||||
find_pc_partial_function is pickier). */
|
find_pc_partial_function is pickier). */
|
||||||
|| IN_SOLIB_TRAMPOLINE (stop_pc, stop_func_name)
|
|| IN_SOLIB_CALL_TRAMPOLINE (stop_pc, stop_func_name)
|
||||||
|
|
||||||
/* If none of the above apply, it is a jump within a function,
|
/* If none of the above apply, it is a jump within a function,
|
||||||
or a return from a subroutine. The other case is longjmp,
|
or a return from a subroutine. The other case is longjmp,
|
||||||
@ -1280,6 +1293,38 @@ step_into_function:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we're in the return path from a shared library trampoline,
|
||||||
|
we want to proceed through the trampoline when stepping. */
|
||||||
|
if (IN_SOLIB_RETURN_TRAMPOLINE(stop_pc, stop_func_name))
|
||||||
|
{
|
||||||
|
CORE_ADDR tmp;
|
||||||
|
|
||||||
|
/* Determine where this trampoline returns. */
|
||||||
|
tmp = SKIP_TRAMPOLINE_CODE (stop_pc);
|
||||||
|
|
||||||
|
/* Only proceed through if we know where it's going. */
|
||||||
|
if (tmp)
|
||||||
|
{
|
||||||
|
/* And put the step-breakpoint there and go until there. */
|
||||||
|
struct symtab_and_line sr_sal;
|
||||||
|
|
||||||
|
sr_sal.pc = tmp;
|
||||||
|
sr_sal.symtab = NULL;
|
||||||
|
sr_sal.line = 0;
|
||||||
|
/* Do not specify what the fp should be when we stop
|
||||||
|
since on some machines the prologue
|
||||||
|
is where the new fp value is established. */
|
||||||
|
step_resume_breakpoint =
|
||||||
|
set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
|
||||||
|
if (breakpoints_inserted)
|
||||||
|
insert_breakpoints ();
|
||||||
|
|
||||||
|
/* Restart without fiddling with the step ranges or
|
||||||
|
other state. */
|
||||||
|
goto keep_going;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (sal.line == 0)
|
if (sal.line == 0)
|
||||||
{
|
{
|
||||||
/* We have no line number information. That means to stop
|
/* We have no line number information. That means to stop
|
||||||
@ -1885,7 +1930,7 @@ save_inferior_status (inf_status, restore_stack_info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct restore_selected_frame_args {
|
struct restore_selected_frame_args {
|
||||||
FRAME_ADDR frame_address;
|
CORE_ADDR frame_address;
|
||||||
int level;
|
int level;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1895,27 +1940,28 @@ static int restore_selected_frame PARAMS ((char *));
|
|||||||
restore_selected_frame_args * (declared as char * for catch_errors)
|
restore_selected_frame_args * (declared as char * for catch_errors)
|
||||||
telling us what frame to restore. Returns 1 for success, or 0 for
|
telling us what frame to restore. Returns 1 for success, or 0 for
|
||||||
failure. An error message will have been printed on error. */
|
failure. An error message will have been printed on error. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
restore_selected_frame (args)
|
restore_selected_frame (args)
|
||||||
char *args;
|
char *args;
|
||||||
{
|
{
|
||||||
struct restore_selected_frame_args *fr =
|
struct restore_selected_frame_args *fr =
|
||||||
(struct restore_selected_frame_args *) args;
|
(struct restore_selected_frame_args *) args;
|
||||||
FRAME fid;
|
struct frame_info *frame;
|
||||||
int level = fr->level;
|
int level = fr->level;
|
||||||
|
|
||||||
fid = find_relative_frame (get_current_frame (), &level);
|
frame = find_relative_frame (get_current_frame (), &level);
|
||||||
|
|
||||||
/* If inf_status->selected_frame_address is NULL, there was no
|
/* If inf_status->selected_frame_address is NULL, there was no
|
||||||
previously selected frame. */
|
previously selected frame. */
|
||||||
if (fid == 0 ||
|
if (frame == NULL ||
|
||||||
FRAME_FP (fid) != fr->frame_address ||
|
FRAME_FP (frame) != fr->frame_address ||
|
||||||
level != 0)
|
level != 0)
|
||||||
{
|
{
|
||||||
warning ("Unable to restore previously selected frame.\n");
|
warning ("Unable to restore previously selected frame.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
select_frame (fid, fr->level);
|
select_frame (frame, fr->level);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
238
gdb/remote.c
238
gdb/remote.c
@ -38,10 +38,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
- - if CSUM is incorrect
|
- - if CSUM is incorrect
|
||||||
|
|
||||||
<data> is as follows:
|
<data> is as follows:
|
||||||
All values are encoded in ascii hex digits.
|
Most values are encoded in ascii hex digits. Signal numbers are according
|
||||||
|
to the numbering in target.h.
|
||||||
|
|
||||||
Request Packet
|
Request Packet
|
||||||
|
|
||||||
|
set thread Hct... Set thread for subsequent operations.
|
||||||
|
c = 'c' for thread used in step and
|
||||||
|
continue; t... can be -1 for all
|
||||||
|
threads.
|
||||||
|
c = 'g' for thread used in other
|
||||||
|
operations. If zero, pick a thread,
|
||||||
|
any thread.
|
||||||
|
reply OK for success
|
||||||
|
ENN for an error.
|
||||||
|
|
||||||
read registers g
|
read registers g
|
||||||
reply XX....X Each byte of register data
|
reply XX....X Each byte of register data
|
||||||
is described by two hex digits.
|
is described by two hex digits.
|
||||||
@ -78,7 +89,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
where only part of the data was
|
where only part of the data was
|
||||||
written).
|
written).
|
||||||
|
|
||||||
cont cAA..AA AA..AA is address to resume
|
continue cAA..AA AA..AA is address to resume
|
||||||
If AA..AA is omitted,
|
If AA..AA is omitted,
|
||||||
resume at same address.
|
resume at same address.
|
||||||
|
|
||||||
@ -86,6 +97,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
If AA..AA is omitted,
|
If AA..AA is omitted,
|
||||||
resume at same address.
|
resume at same address.
|
||||||
|
|
||||||
|
continue with Csig;AA Continue with signal sig (hex signal
|
||||||
|
signal number).
|
||||||
|
|
||||||
|
step with Ssig;AA Like 'C' but step not continue.
|
||||||
|
signal
|
||||||
|
|
||||||
last signal ? Reply the current reason for stopping.
|
last signal ? Reply the current reason for stopping.
|
||||||
This is the same reply as is generated
|
This is the same reply as is generated
|
||||||
for step or cont : SAA where AA is the
|
for step or cont : SAA where AA is the
|
||||||
@ -93,16 +110,31 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
|
|
||||||
There is no immediate reply to step or cont.
|
There is no immediate reply to step or cont.
|
||||||
The reply comes when the machine stops.
|
The reply comes when the machine stops.
|
||||||
It is SAA AA is the "signal number"
|
It is SAA AA is the signal number.
|
||||||
|
|
||||||
or... TAAn...:r...;n:r...;n...:r...;
|
or... TAAn...:r...;n...:r...;n...:r...;
|
||||||
AA = signal number
|
AA = signal number
|
||||||
n... = register number
|
n... = register number (hex)
|
||||||
r... = register contents
|
r... = register contents
|
||||||
|
n... = `thread'
|
||||||
|
r... = thread process ID. This is
|
||||||
|
a hex integer.
|
||||||
|
n... = other string not starting
|
||||||
|
with valid hex digit.
|
||||||
|
gdb should ignore this n,r pair
|
||||||
|
and go on to the next. This way
|
||||||
|
we can extend the protocol.
|
||||||
or... WAA The process exited, and AA is
|
or... WAA The process exited, and AA is
|
||||||
the exit status. This is only
|
the exit status. This is only
|
||||||
applicable for certains sorts of
|
applicable for certains sorts of
|
||||||
targets.
|
targets.
|
||||||
|
or... XAA The process terminated with signal
|
||||||
|
AA.
|
||||||
|
or... Otext Send text to stdout. This can happen
|
||||||
|
at any time while the program is
|
||||||
|
running and the debugger should
|
||||||
|
continue to wait for 'W', 'T', etc.
|
||||||
|
|
||||||
kill request k
|
kill request k
|
||||||
|
|
||||||
toggle debug d toggle debug flag (see 386 & 68k stubs)
|
toggle debug d toggle debug flag (see 386 & 68k stubs)
|
||||||
@ -122,8 +154,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
general set QXXXX=yyyy Set value of XXXX to yyyy.
|
general set QXXXX=yyyy Set value of XXXX to yyyy.
|
||||||
query sect offs qOffsets Get section offsets. Reply is
|
query sect offs qOffsets Get section offsets. Reply is
|
||||||
Text=xxx;Data=yyy;Bss=zzz
|
Text=xxx;Data=yyy;Bss=zzz
|
||||||
console output Otext Send text to stdout. Only comes from
|
|
||||||
remote target.
|
|
||||||
|
|
||||||
Responses can be run-length encoded to save space. A '*' means that
|
Responses can be run-length encoded to save space. A '*' means that
|
||||||
the next character is an ASCII encoding giving a repeat count which
|
the next character is an ASCII encoding giving a repeat count which
|
||||||
@ -196,7 +226,7 @@ remote_store_registers PARAMS ((int regno));
|
|||||||
static void
|
static void
|
||||||
getpkt PARAMS ((char *buf, int forever));
|
getpkt PARAMS ((char *buf, int forever));
|
||||||
|
|
||||||
static void
|
static int
|
||||||
putpkt PARAMS ((char *buf));
|
putpkt PARAMS ((char *buf));
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -266,6 +296,39 @@ serial_t remote_desc = NULL;
|
|||||||
doesn't support 'P', the only consequence is some unnecessary traffic. */
|
doesn't support 'P', the only consequence is some unnecessary traffic. */
|
||||||
static int stub_supports_P = 1;
|
static int stub_supports_P = 1;
|
||||||
|
|
||||||
|
|
||||||
|
/* These are the threads which we last sent to the remote system. -1 for all
|
||||||
|
or -2 for not sent yet. */
|
||||||
|
int general_thread;
|
||||||
|
int cont_thread;
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_thread (th, gen)
|
||||||
|
int th;
|
||||||
|
int gen;
|
||||||
|
{
|
||||||
|
char buf[PBUFSIZ];
|
||||||
|
int state = gen ? general_thread : cont_thread;
|
||||||
|
if (state == th)
|
||||||
|
return;
|
||||||
|
buf[0] = 'H';
|
||||||
|
buf[1] = gen ? 'g' : 'c';
|
||||||
|
if (th == 42000)
|
||||||
|
{
|
||||||
|
buf[2] = '0';
|
||||||
|
buf[3] = '\0';
|
||||||
|
}
|
||||||
|
else if (th < 0)
|
||||||
|
sprintf (&buf[2], "-%x", -th);
|
||||||
|
else
|
||||||
|
sprintf (&buf[2], "%x", th);
|
||||||
|
putpkt (buf);
|
||||||
|
getpkt (buf, 0);
|
||||||
|
if (gen)
|
||||||
|
general_thread = th;
|
||||||
|
else
|
||||||
|
cont_thread = th;
|
||||||
|
}
|
||||||
|
|
||||||
/* Clean up connection to a remote debugger. */
|
/* Clean up connection to a remote debugger. */
|
||||||
|
|
||||||
@ -348,6 +411,9 @@ remote_start_remote (dummy)
|
|||||||
|
|
||||||
SERIAL_WRITE (remote_desc, "+", 1);
|
SERIAL_WRITE (remote_desc, "+", 1);
|
||||||
|
|
||||||
|
/* Let the stub know that we want it to return the thread. */
|
||||||
|
set_thread (-1, 0);
|
||||||
|
|
||||||
get_offsets (); /* Get text, data & bss offsets */
|
get_offsets (); /* Get text, data & bss offsets */
|
||||||
|
|
||||||
putpkt ("?"); /* initiate a query from remote machine */
|
putpkt ("?"); /* initiate a query from remote machine */
|
||||||
@ -411,6 +477,9 @@ device is attached to the remote system (e.g. /dev/ttya).");
|
|||||||
stub to another, we can (if the target is closed and reopened) cope. */
|
stub to another, we can (if the target is closed and reopened) cope. */
|
||||||
stub_supports_P = 1;
|
stub_supports_P = 1;
|
||||||
|
|
||||||
|
general_thread = -2;
|
||||||
|
cont_thread = -2;
|
||||||
|
|
||||||
/* Without this, some commands which require an active target (such as kill)
|
/* Without this, some commands which require an active target (such as kill)
|
||||||
won't work. This variable serves (at least) double duty as both the pid
|
won't work. This variable serves (at least) double duty as both the pid
|
||||||
of the target process (if it has such), and as a flag indicating that a
|
of the target process (if it has such), and as a flag indicating that a
|
||||||
@ -477,6 +546,9 @@ tohex (nib)
|
|||||||
|
|
||||||
/* Tell the remote machine to resume. */
|
/* Tell the remote machine to resume. */
|
||||||
|
|
||||||
|
static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
|
||||||
|
int last_sent_step;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remote_resume (pid, step, siggnal)
|
remote_resume (pid, step, siggnal)
|
||||||
int pid, step;
|
int pid, step;
|
||||||
@ -484,18 +556,25 @@ remote_resume (pid, step, siggnal)
|
|||||||
{
|
{
|
||||||
char buf[PBUFSIZ];
|
char buf[PBUFSIZ];
|
||||||
|
|
||||||
if (siggnal)
|
if (pid == -1)
|
||||||
{
|
set_thread (inferior_pid, 0);
|
||||||
target_terminal_ours_for_output ();
|
else
|
||||||
printf_filtered
|
set_thread (pid, 0);
|
||||||
("Can't send signals to a remote system. %s not sent.\n",
|
|
||||||
target_signal_to_name (siggnal));
|
|
||||||
target_terminal_inferior ();
|
|
||||||
}
|
|
||||||
|
|
||||||
dcache_flush (remote_dcache);
|
dcache_flush (remote_dcache);
|
||||||
|
|
||||||
strcpy (buf, step ? "s": "c");
|
last_sent_signal = siggnal;
|
||||||
|
last_sent_step = step;
|
||||||
|
|
||||||
|
if (siggnal != TARGET_SIGNAL_0)
|
||||||
|
{
|
||||||
|
buf[0] = step ? 'S' : 'C';
|
||||||
|
buf[1] = tohex (((int)siggnal >> 4) & 0xf);
|
||||||
|
buf[2] = tohex ((int)siggnal & 0xf);
|
||||||
|
buf[3] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strcpy (buf, step ? "s": "c");
|
||||||
|
|
||||||
putpkt (buf);
|
putpkt (buf);
|
||||||
}
|
}
|
||||||
@ -547,6 +626,9 @@ Give up (and stop debugging it)? "))
|
|||||||
target_terminal_inferior ();
|
target_terminal_inferior ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If nonzero, ignore the next kill. */
|
||||||
|
int kill_kludge;
|
||||||
|
|
||||||
/* Wait until the remote machine stops, then return,
|
/* Wait until the remote machine stops, then return,
|
||||||
storing status in STATUS just as `wait' would.
|
storing status in STATUS just as `wait' would.
|
||||||
Returns "pid" (though it's not clear what, if anything, that
|
Returns "pid" (though it's not clear what, if anything, that
|
||||||
@ -558,6 +640,7 @@ remote_wait (pid, status)
|
|||||||
struct target_waitstatus *status;
|
struct target_waitstatus *status;
|
||||||
{
|
{
|
||||||
unsigned char buf[PBUFSIZ];
|
unsigned char buf[PBUFSIZ];
|
||||||
|
int thread_num = -1;
|
||||||
|
|
||||||
status->kind = TARGET_WAITKIND_EXITED;
|
status->kind = TARGET_WAITKIND_EXITED;
|
||||||
status->value.integer = 0;
|
status->value.integer = 0;
|
||||||
@ -597,31 +680,44 @@ remote_wait (pid, status)
|
|||||||
regno = strtol (p, &p1, 16); /* Read the register number */
|
regno = strtol (p, &p1, 16); /* Read the register number */
|
||||||
|
|
||||||
if (p1 == p)
|
if (p1 == p)
|
||||||
warning ("Remote sent badly formed register number: %s\nPacket: '%s'\n",
|
|
||||||
p1, buf);
|
|
||||||
|
|
||||||
p = p1;
|
|
||||||
|
|
||||||
if (*p++ != ':')
|
|
||||||
warning ("Malformed packet (missing colon): %s\nPacket: '%s'\n",
|
|
||||||
p, buf);
|
|
||||||
|
|
||||||
if (regno >= NUM_REGS)
|
|
||||||
warning ("Remote sent bad register number %d: %s\nPacket: '%s'\n",
|
|
||||||
regno, p, buf);
|
|
||||||
|
|
||||||
for (i = 0; i < REGISTER_RAW_SIZE (regno); i++)
|
|
||||||
{
|
{
|
||||||
if (p[0] == 0 || p[1] == 0)
|
p1 = (unsigned char *) strchr (p, ':');
|
||||||
warning ("Remote reply is too short: %s", buf);
|
if (p1 == NULL)
|
||||||
regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
|
warning ("Malformed packet (missing colon): %s\n\
|
||||||
p += 2;
|
Packet: '%s'\n",
|
||||||
|
p, buf);
|
||||||
|
if (strncmp (p, "thread", p1 - p) == 0)
|
||||||
|
{
|
||||||
|
char *p2;
|
||||||
|
thread_num = strtol (++p1, &p, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p = p1;
|
||||||
|
|
||||||
|
if (*p++ != ':')
|
||||||
|
warning ("Malformed packet (missing colon): %s\n\
|
||||||
|
Packet: '%s'\n",
|
||||||
|
p, buf);
|
||||||
|
|
||||||
|
if (regno >= NUM_REGS)
|
||||||
|
warning ("Remote sent bad register number %d: %s\n\
|
||||||
|
Packet: '%s'\n",
|
||||||
|
regno, p, buf);
|
||||||
|
|
||||||
|
for (i = 0; i < REGISTER_RAW_SIZE (regno); i++)
|
||||||
|
{
|
||||||
|
if (p[0] == 0 || p[1] == 0)
|
||||||
|
warning ("Remote reply is too short: %s", buf);
|
||||||
|
regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
|
supply_register (regno, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*p++ != ';')
|
if (*p++ != ';')
|
||||||
warning ("Remote register badly formatted: %s", buf);
|
warning ("Remote register badly formatted: %s", buf);
|
||||||
|
|
||||||
supply_register (regno, regs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
@ -630,22 +726,60 @@ remote_wait (pid, status)
|
|||||||
status->value.sig = (enum target_signal)
|
status->value.sig = (enum target_signal)
|
||||||
(((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
|
(((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
|
||||||
|
|
||||||
return inferior_pid;
|
goto got_status;
|
||||||
case 'W': /* Target exited */
|
case 'W': /* Target exited */
|
||||||
{
|
{
|
||||||
/* The remote process exited. */
|
/* The remote process exited. */
|
||||||
status->kind = TARGET_WAITKIND_EXITED;
|
status->kind = TARGET_WAITKIND_EXITED;
|
||||||
status->value.integer = (fromhex (buf[1]) << 4) + fromhex (buf[2]);
|
status->value.integer = (fromhex (buf[1]) << 4) + fromhex (buf[2]);
|
||||||
return inferior_pid;
|
goto got_status;
|
||||||
}
|
}
|
||||||
|
case 'X':
|
||||||
|
status->kind = TARGET_WAITKIND_SIGNALLED;
|
||||||
|
status->value.sig = (enum target_signal)
|
||||||
|
(((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
|
||||||
|
kill_kludge = 1;
|
||||||
|
|
||||||
|
goto got_status;
|
||||||
case 'O': /* Console output */
|
case 'O': /* Console output */
|
||||||
fputs_filtered ((char *)(buf + 1), gdb_stdout);
|
fputs_filtered ((char *)(buf + 1), gdb_stdout);
|
||||||
continue;
|
continue;
|
||||||
|
case '\0':
|
||||||
|
if (last_sent_signal != TARGET_SIGNAL_0)
|
||||||
|
{
|
||||||
|
/* Zero length reply means that we tried 'S' or 'C' and
|
||||||
|
the remote system doesn't support it. */
|
||||||
|
target_terminal_ours_for_output ();
|
||||||
|
printf_filtered
|
||||||
|
("Can't send signals to this remote system. %s not sent.\n",
|
||||||
|
target_signal_to_name (last_sent_signal));
|
||||||
|
last_sent_signal = TARGET_SIGNAL_0;
|
||||||
|
target_terminal_inferior ();
|
||||||
|
|
||||||
|
strcpy (buf, last_sent_step ? 's' : 'c');
|
||||||
|
putpkt (buf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* else fallthrough */
|
||||||
default:
|
default:
|
||||||
warning ("Invalid remote reply: %s", buf);
|
warning ("Invalid remote reply: %s", buf);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
got_status:
|
||||||
|
if (thread_num != -1)
|
||||||
|
{
|
||||||
|
/* Initial thread value can only be acquired via wait, so deal with
|
||||||
|
this marker which is used before the first thread value is
|
||||||
|
acquired. */
|
||||||
|
if (inferior_pid == 42000)
|
||||||
|
{
|
||||||
|
inferior_pid = thread_num;
|
||||||
|
add_thread (inferior_pid);
|
||||||
|
}
|
||||||
|
return thread_num;
|
||||||
|
}
|
||||||
|
return inferior_pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Number of bytes of registers this stub implements. */
|
/* Number of bytes of registers this stub implements. */
|
||||||
@ -663,6 +797,8 @@ remote_fetch_registers (regno)
|
|||||||
char *p;
|
char *p;
|
||||||
char regs[REGISTER_BYTES];
|
char regs[REGISTER_BYTES];
|
||||||
|
|
||||||
|
set_thread (inferior_pid, 1);
|
||||||
|
|
||||||
sprintf (buf, "g");
|
sprintf (buf, "g");
|
||||||
remote_send (buf);
|
remote_send (buf);
|
||||||
|
|
||||||
@ -736,6 +872,8 @@ remote_store_registers (regno)
|
|||||||
int i;
|
int i;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
|
set_thread (inferior_pid, 1);
|
||||||
|
|
||||||
if (regno >= 0 && stub_supports_P)
|
if (regno >= 0 && stub_supports_P)
|
||||||
{
|
{
|
||||||
/* Try storing a single register. */
|
/* Try storing a single register. */
|
||||||
@ -944,6 +1082,8 @@ remote_xfer_memory(memaddr, myaddr, len, should_write, target)
|
|||||||
int bytes_xferred;
|
int bytes_xferred;
|
||||||
int total_xferred = 0;
|
int total_xferred = 0;
|
||||||
|
|
||||||
|
set_thread (inferior_pid, 1);
|
||||||
|
|
||||||
while (len > 0)
|
while (len > 0)
|
||||||
{
|
{
|
||||||
if (len > MAXBUFBYTES)
|
if (len > MAXBUFBYTES)
|
||||||
@ -1096,7 +1236,7 @@ remote_send (buf)
|
|||||||
/* Send a packet to the remote machine, with error checking.
|
/* Send a packet to the remote machine, with error checking.
|
||||||
The data of the packet is in BUF. */
|
The data of the packet is in BUF. */
|
||||||
|
|
||||||
static void
|
static int
|
||||||
putpkt (buf)
|
putpkt (buf)
|
||||||
char *buf;
|
char *buf;
|
||||||
{
|
{
|
||||||
@ -1165,7 +1305,7 @@ putpkt (buf)
|
|||||||
case '+':
|
case '+':
|
||||||
if (remote_debug)
|
if (remote_debug)
|
||||||
printf_unfiltered("Ack\n");
|
printf_unfiltered("Ack\n");
|
||||||
return;
|
return 1;
|
||||||
case SERIAL_TIMEOUT:
|
case SERIAL_TIMEOUT:
|
||||||
break; /* Retransmit buffer */
|
break; /* Retransmit buffer */
|
||||||
case '$':
|
case '$':
|
||||||
@ -1367,7 +1507,19 @@ retry:
|
|||||||
static void
|
static void
|
||||||
remote_kill ()
|
remote_kill ()
|
||||||
{
|
{
|
||||||
putpkt ("k");
|
/* For some mysterious reason, wait_for_inferior calls kill instead of
|
||||||
|
mourn after it gets TARGET_WAITKIND_SIGNALLED. Work around it. */
|
||||||
|
if (kill_kludge)
|
||||||
|
{
|
||||||
|
kill_kludge = 0;
|
||||||
|
target_mourn_inferior ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use catch_errors so the user can quit from gdb even when we aren't on
|
||||||
|
speaking terms with the remote system. */
|
||||||
|
catch_errors (putpkt, "k", "", RETURN_MASK_ERROR);
|
||||||
|
|
||||||
/* Don't wait for it to die. I'm not really sure it matters whether
|
/* Don't wait for it to die. I'm not really sure it matters whether
|
||||||
we do or not. For the existing stubs, kill is a noop. */
|
we do or not. For the existing stubs, kill is a noop. */
|
||||||
target_mourn_inferior ();
|
target_mourn_inferior ();
|
||||||
|
10
gdb/thread.c
10
gdb/thread.c
@ -170,9 +170,17 @@ info_threads_command (arg, from_tty)
|
|||||||
struct thread_info *tp;
|
struct thread_info *tp;
|
||||||
int current_pid = inferior_pid;
|
int current_pid = inferior_pid;
|
||||||
|
|
||||||
|
/* Avoid coredumps which would happen if we tried to access a NULL
|
||||||
|
selected_frame. */
|
||||||
|
if (!target_has_stack) error ("No stack.");
|
||||||
|
|
||||||
for (tp = thread_list; tp; tp = tp->next)
|
for (tp = thread_list; tp; tp = tp->next)
|
||||||
{
|
{
|
||||||
if (target_has_execution
|
/* FIXME: need to figure out a way to do this for remote too,
|
||||||
|
or else the print_stack_frame below will fail with a bogus
|
||||||
|
thread ID. */
|
||||||
|
if (!STREQ (current_target.to_shortname, "remote")
|
||||||
|
&& target_has_execution
|
||||||
&& kill (tp->pid, 0) == -1)
|
&& kill (tp->pid, 0) == -1)
|
||||||
{
|
{
|
||||||
tp->pid = -1; /* Mark it as dead */
|
tp->pid = -1; /* Mark it as dead */
|
||||||
|
Loading…
Reference in New Issue
Block a user