Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1273)

Unified Diff: gdb/gdbserver/lynx-low.c

Issue 124383005: GDB 7.6.50 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@upstream
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gdb/gdbserver/lynx-low.h ('k') | gdb/gdbserver/lynx-ppc-low.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gdb/gdbserver/lynx-low.c
diff --git a/gdb/gdbserver/lynx-low.c b/gdb/gdbserver/lynx-low.c
index 2c7ab6e3dfa193fe433bf2eece609d3c419fcbd1..3c061b8f0779e3e4966d1c45f71ea3a8162c0799 100644
--- a/gdb/gdbserver/lynx-low.c
+++ b/gdb/gdbserver/lynx-low.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009-2012 Free Software Foundation, Inc.
+/* Copyright (C) 2009-2013 Free Software Foundation, Inc.
This file is part of GDB.
@@ -25,11 +25,23 @@
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
-#include <sys/wait.h>
+#include "gdb_wait.h"
#include <signal.h>
+#include "filestuff.h"
int using_threads = 1;
+const struct target_desc *lynx_tdesc;
+
+/* Per-process private data. */
+
+struct process_info_private
+{
+ /* The PTID obtained from the last wait performed on this process.
+ Initialized to null_ptid until the first wait is performed. */
+ ptid_t last_wait_event_ptid;
+};
+
/* Print a debug trace on standard output if debug_threads is set. */
static void
@@ -96,169 +108,79 @@ lynx_ptrace_pid_from_ptid (ptid_t ptid)
static char *
ptrace_request_to_str (int request)
{
+#define CASE(X) case X: return #X
switch (request)
{
- case PTRACE_TRACEME:
- return "PTRACE_TRACEME";
- break;
- case PTRACE_PEEKTEXT:
- return "PTRACE_PEEKTEXT";
- break;
- case PTRACE_PEEKDATA:
- return "PTRACE_PEEKDATA";
- break;
- case PTRACE_PEEKUSER:
- return "PTRACE_PEEKUSER";
- break;
- case PTRACE_POKETEXT:
- return "PTRACE_POKETEXT";
- break;
- case PTRACE_POKEDATA:
- return "PTRACE_POKEDATA";
- break;
- case PTRACE_POKEUSER:
- return "PTRACE_POKEUSER";
- break;
- case PTRACE_CONT:
- return "PTRACE_CONT";
- break;
- case PTRACE_KILL:
- return "PTRACE_KILL";
- break;
- case PTRACE_SINGLESTEP:
- return "PTRACE_SINGLESTEP";
- break;
- case PTRACE_ATTACH:
- return "PTRACE_ATTACH";
- break;
- case PTRACE_DETACH:
- return "PTRACE_DETACH";
- break;
- case PTRACE_GETREGS:
- return "PTRACE_GETREGS";
- break;
- case PTRACE_SETREGS:
- return "PTRACE_SETREGS";
- break;
- case PTRACE_GETFPREGS:
- return "PTRACE_GETFPREGS";
- break;
- case PTRACE_SETFPREGS:
- return "PTRACE_SETFPREGS";
- break;
- case PTRACE_READDATA:
- return "PTRACE_READDATA";
- break;
- case PTRACE_WRITEDATA:
- return "PTRACE_WRITEDATA";
- break;
- case PTRACE_READTEXT:
- return "PTRACE_READTEXT";
- break;
- case PTRACE_WRITETEXT:
- return "PTRACE_WRITETEXT";
- break;
- case PTRACE_GETFPAREGS:
- return "PTRACE_GETFPAREGS";
- break;
- case PTRACE_SETFPAREGS:
- return "PTRACE_SETFPAREGS";
- break;
- case PTRACE_GETWINDOW:
- return "PTRACE_GETWINDOW";
- break;
- case PTRACE_SETWINDOW:
- return "PTRACE_SETWINDOW";
- break;
- case PTRACE_SYSCALL:
- return "PTRACE_SYSCALL";
- break;
- case PTRACE_DUMPCORE:
- return "PTRACE_DUMPCORE";
- break;
- case PTRACE_SETWRBKPT:
- return "PTRACE_SETWRBKPT";
- break;
- case PTRACE_SETACBKPT:
- return "PTRACE_SETACBKPT";
- break;
- case PTRACE_CLRBKPT:
- return "PTRACE_CLRBKPT";
- break;
- case PTRACE_GET_UCODE:
- return "PTRACE_GET_UCODE";
- break;
+ CASE(PTRACE_TRACEME);
+ CASE(PTRACE_PEEKTEXT);
+ CASE(PTRACE_PEEKDATA);
+ CASE(PTRACE_PEEKUSER);
+ CASE(PTRACE_POKETEXT);
+ CASE(PTRACE_POKEDATA);
+ CASE(PTRACE_POKEUSER);
+ CASE(PTRACE_CONT);
+ CASE(PTRACE_KILL);
+ CASE(PTRACE_SINGLESTEP);
+ CASE(PTRACE_ATTACH);
+ CASE(PTRACE_DETACH);
+ CASE(PTRACE_GETREGS);
+ CASE(PTRACE_SETREGS);
+ CASE(PTRACE_GETFPREGS);
+ CASE(PTRACE_SETFPREGS);
+ CASE(PTRACE_READDATA);
+ CASE(PTRACE_WRITEDATA);
+ CASE(PTRACE_READTEXT);
+ CASE(PTRACE_WRITETEXT);
+ CASE(PTRACE_GETFPAREGS);
+ CASE(PTRACE_SETFPAREGS);
+ CASE(PTRACE_GETWINDOW);
+ CASE(PTRACE_SETWINDOW);
+ CASE(PTRACE_SYSCALL);
+ CASE(PTRACE_DUMPCORE);
+ CASE(PTRACE_SETWRBKPT);
+ CASE(PTRACE_SETACBKPT);
+ CASE(PTRACE_CLRBKPT);
+ CASE(PTRACE_GET_UCODE);
#ifdef PT_READ_GPR
- case PT_READ_GPR:
- return "PT_READ_GPR";
- break;
+ CASE(PT_READ_GPR);
#endif
#ifdef PT_WRITE_GPR
- case PT_WRITE_GPR:
- return "PT_WRITE_GPR";
- break;
+ CASE(PT_WRITE_GPR);
#endif
#ifdef PT_READ_FPR
- case PT_READ_FPR:
- return "PT_READ_FPR";
- break;
+ CASE(PT_READ_FPR);
#endif
#ifdef PT_WRITE_FPR
- case PT_WRITE_FPR:
- return "PT_WRITE_FPR";
- break;
+ CASE(PT_WRITE_FPR);
#endif
#ifdef PT_READ_VPR
- case PT_READ_VPR:
- return "PT_READ_VPR";
- break;
+ CASE(PT_READ_VPR);
#endif
#ifdef PT_WRITE_VPR
- case PT_WRITE_VPR:
- return "PT_WRITE_VPR";
- break;
+ CASE(PT_WRITE_VPR);
#endif
#ifdef PTRACE_PEEKUSP
- case PTRACE_PEEKUSP:
- return "PTRACE_PEEKUSP";
- break;
+ CASE(PTRACE_PEEKUSP);
#endif
#ifdef PTRACE_POKEUSP
- case PTRACE_POKEUSP:
- return "PTRACE_POKEUSP";
- break;
+ CASE(PTRACE_POKEUSP);
+#endif
+ CASE(PTRACE_PEEKTHREAD);
+ CASE(PTRACE_THREADUSER);
+ CASE(PTRACE_FPREAD);
+ CASE(PTRACE_FPWRITE);
+ CASE(PTRACE_SETSIG);
+ CASE(PTRACE_CONT_ONE);
+ CASE(PTRACE_KILL_ONE);
+ CASE(PTRACE_SINGLESTEP_ONE);
+ CASE(PTRACE_GETLOADINFO);
+ CASE(PTRACE_GETTRACESIG);
+#ifdef PTRACE_GETTHREADLIST
+ CASE(PTRACE_GETTHREADLIST);
#endif
- case PTRACE_PEEKTHREAD:
- return "PTRACE_PEEKTHREAD";
- break;
- case PTRACE_THREADUSER:
- return "PTRACE_THREADUSER";
- break;
- case PTRACE_FPREAD:
- return "PTRACE_FPREAD";
- break;
- case PTRACE_FPWRITE:
- return "PTRACE_FPWRITE";
- break;
- case PTRACE_SETSIG:
- return "PTRACE_SETSIG";
- break;
- case PTRACE_CONT_ONE:
- return "PTRACE_CONT_ONE";
- break;
- case PTRACE_KILL_ONE:
- return "PTRACE_KILL_ONE";
- break;
- case PTRACE_SINGLESTEP_ONE:
- return "PTRACE_SINGLESTEP_ONE";
- break;
- case PTRACE_GETLOADINFO:
- return "PTRACE_GETLOADINFO";
- break;
- case PTRACE_GETTHREADLIST:
- return "PTRACE_GETTHREADLIST";
- break;
}
+#undef CASE
+
return "<unknown-request>";
}
@@ -286,12 +208,27 @@ lynx_ptrace (int request, ptid_t ptid, int addr, int data, int addr2)
return result;
}
+/* Call add_process with the given parameters, and initializes
+ the process' private data. */
+
+static struct process_info *
+lynx_add_process (int pid, int attached)
+{
+ struct process_info *proc;
+
+ proc = add_process (pid, attached);
+ proc->tdesc = lynx_tdesc;
+ proc->private = xcalloc (1, sizeof (*proc->private));
+ proc->private->last_wait_event_ptid = null_ptid;
+
+ return proc;
+}
+
/* Implement the create_inferior method of the target_ops vector. */
static int
lynx_create_inferior (char *program, char **allargs)
{
- struct process_info *new_process;
int pid;
lynx_debug ("lynx_create_inferior ()");
@@ -304,6 +241,8 @@ lynx_create_inferior (char *program, char **allargs)
{
int pgrp;
+ close_most_fds ();
+
/* Switch child to its own process group so that signals won't
directly affect gdbserver. */
pgrp = getpid();
@@ -316,27 +255,62 @@ lynx_create_inferior (char *program, char **allargs)
_exit (0177);
}
- new_process = add_process (pid, 0);
+ lynx_add_process (pid, 0);
/* Do not add the process thread just yet, as we do not know its tid.
We will add it later, during the wait for the STOP event corresponding
to the lynx_ptrace (PTRACE_TRACEME) call above. */
return pid;
}
+/* Assuming we've just attached to a running inferior whose pid is PID,
+ add all threads running in that process. */
+
+static void
+lynx_add_threads_after_attach (int pid)
+{
+ /* Ugh! There appears to be no way to get the list of threads
+ in the program we just attached to. So get the list by calling
+ the "ps" command. This is only needed now, as we will then
+ keep the thread list up to date thanks to thread creation and
+ exit notifications. */
+ FILE *f;
+ char buf[256];
+ int thread_pid, thread_tid;
+
+ f = popen ("ps atx", "r");
+ if (f == NULL)
+ perror_with_name ("Cannot get thread list");
+
+ while (fgets (buf, sizeof (buf), f) != NULL)
+ if ((sscanf (buf, "%d %d", &thread_pid, &thread_tid) == 2
+ && thread_pid == pid))
+ {
+ ptid_t thread_ptid = lynx_ptid_build (pid, thread_tid);
+
+ if (!find_thread_ptid (thread_ptid))
+ {
+ lynx_debug ("New thread: (pid = %d, tid = %d)",
+ pid, thread_tid);
+ add_thread (thread_ptid, NULL);
+ }
+ }
+
+ pclose (f);
+}
+
/* Implement the attach target_ops method. */
static int
lynx_attach (unsigned long pid)
{
- struct process_info *new_process;
ptid_t ptid = lynx_ptid_build (pid, 0);
if (lynx_ptrace (PTRACE_ATTACH, ptid, 0, 0, 0) != 0)
error ("Cannot attach to process %lu: %s (%d)\n", pid,
strerror (errno), errno);
- new_process = add_process (pid, 1);
- add_thread (ptid, NULL);
+ lynx_add_process (pid, 1);
+ lynx_add_threads_after_attach (pid);
return 0;
}
@@ -346,15 +320,34 @@ lynx_attach (unsigned long pid)
static void
lynx_resume (struct thread_resume *resume_info, size_t n)
{
- ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
/* FIXME: Assume for now that n == 1. */
+ ptid_t ptid = resume_info[0].thread;
const int request = (resume_info[0].kind == resume_step
? PTRACE_SINGLESTEP : PTRACE_CONT);
const int signal = resume_info[0].sig;
- int ret;
+
+ /* If given a minus_one_ptid, then try using the current_process'
+ private->last_wait_event_ptid. On most LynxOS versions,
+ using any of the process' thread works well enough, but
+ LynxOS 178 is a little more sensitive, and triggers some
+ unexpected signals (Eg SIG61) when we resume the inferior
+ using a different thread. */
+ if (ptid_equal (ptid, minus_one_ptid))
+ ptid = current_process()->private->last_wait_event_ptid;
+
+ /* The ptid might still be minus_one_ptid; this can happen between
+ the moment we create the inferior or attach to a process, and
+ the moment we resume its execution for the first time. It is
+ fine to use the current_inferior's ptid in those cases. */
+ if (ptid_equal (ptid, minus_one_ptid))
+ ptid = thread_to_gdb_id (current_inferior);
regcache_invalidate ();
- ret = lynx_ptrace (request, inferior_ptid, 1, signal, 0);
+
+ errno = 0;
+ lynx_ptrace (request, ptid, 1, signal, 0);
+ if (errno)
+ perror_with_name ("ptrace");
}
/* Resume the execution of the given PTID. */
@@ -371,16 +364,6 @@ lynx_continue (ptid_t ptid)
lynx_resume (&resume_info, 1);
}
-/* Remove all inferiors and associated threads. */
-
-static void
-lynx_clear_inferiors (void)
-{
- /* We do not use private data, so nothing much to do except calling
- clear_inferiors. */
- clear_inferiors ();
-}
-
/* A wrapper around waitpid that handles the various idiosyncrasies
of LynxOS' waitpid. */
@@ -438,6 +421,7 @@ retry:
ret = lynx_waitpid (pid, &wstat);
new_ptid = lynx_ptid_build (ret, ((union wait *) &wstat)->w_tid);
+ find_process_pid (ret)->private->last_wait_event_ptid = new_ptid;
/* If this is a new thread, then add it now. The reason why we do
this here instead of when handling new-thread events is because
@@ -445,7 +429,11 @@ retry:
for non-threaded applications where the new-thread events are not
generated. */
if (!find_thread_ptid (new_ptid))
- add_thread (new_ptid, NULL);
+ {
+ lynx_debug ("New thread: (pid = %d, tid = %d)",
+ lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid));
+ add_thread (new_ptid, NULL);
+ }
if (WIFSTOPPED (wstat))
{
@@ -491,12 +479,12 @@ retry:
case SIGNEWTHREAD:
/* We just added the new thread above. No need to do anything
further. Just resume the execution again. */
- lynx_continue (ptid);
+ lynx_continue (new_ptid);
goto retry;
case SIGTHREADEXIT:
remove_thread (find_thread_ptid (new_ptid));
- lynx_continue (ptid);
+ lynx_continue (new_ptid);
goto retry;
}
}
@@ -562,7 +550,11 @@ lynx_detach (int pid)
static void
lynx_mourn (struct process_info *proc)
{
- lynx_clear_inferiors ();
+ /* Free our private data. */
+ free (proc->private);
+ proc->private = NULL;
+
+ clear_inferiors ();
}
/* Implement the join target_ops method. */
« no previous file with comments | « gdb/gdbserver/lynx-low.h ('k') | gdb/gdbserver/lynx-ppc-low.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698