| OLD | NEW | 
|    1 /* Copyright (C) 2009-2012 Free Software Foundation, Inc. |    1 /* Copyright (C) 2009-2013 Free Software Foundation, Inc. | 
|    2  |    2  | 
|    3    This file is part of GDB. |    3    This file is part of GDB. | 
|    4  |    4  | 
|    5    This program is free software; you can redistribute it and/or modify |    5    This program is free software; you can redistribute it and/or modify | 
|    6    it under the terms of the GNU General Public License as published by |    6    it under the terms of the GNU General Public License as published by | 
|    7    the Free Software Foundation; either version 3 of the License, or |    7    the Free Software Foundation; either version 3 of the License, or | 
|    8    (at your option) any later version. |    8    (at your option) any later version. | 
|    9  |    9  | 
|   10    This program is distributed in the hope that it will be useful, |   10    This program is distributed in the hope that it will be useful, | 
|   11    but WITHOUT ANY WARRANTY; without even the implied warranty of |   11    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|   12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |   12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|   13    GNU General Public License for more details. |   13    GNU General Public License for more details. | 
|   14  |   14  | 
|   15    You should have received a copy of the GNU General Public License |   15    You should have received a copy of the GNU General Public License | 
|   16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ |   16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | 
|   17  |   17  | 
|   18 #include "server.h" |   18 #include "server.h" | 
|   19 #include "target.h" |   19 #include "target.h" | 
|   20 #include "lynx-low.h" |   20 #include "lynx-low.h" | 
|   21  |   21  | 
|   22 #include <limits.h> |   22 #include <limits.h> | 
|   23 #include <sys/ptrace.h> |   23 #include <sys/ptrace.h> | 
|   24 #include <sys/piddef.h> /* Provides PIDGET, TIDGET, BUILDPID, etc.  */ |   24 #include <sys/piddef.h> /* Provides PIDGET, TIDGET, BUILDPID, etc.  */ | 
|   25 #include <unistd.h> |   25 #include <unistd.h> | 
|   26 #include <sys/ioctl.h> |   26 #include <sys/ioctl.h> | 
|   27 #include <sys/types.h> |   27 #include <sys/types.h> | 
|   28 #include <sys/wait.h> |   28 #include "gdb_wait.h" | 
|   29 #include <signal.h> |   29 #include <signal.h> | 
 |   30 #include "filestuff.h" | 
|   30  |   31  | 
|   31 int using_threads = 1; |   32 int using_threads = 1; | 
|   32  |   33  | 
 |   34 const struct target_desc *lynx_tdesc; | 
 |   35  | 
 |   36 /* Per-process private data.  */ | 
 |   37  | 
 |   38 struct process_info_private | 
 |   39 { | 
 |   40   /* The PTID obtained from the last wait performed on this process. | 
 |   41      Initialized to null_ptid until the first wait is performed.  */ | 
 |   42   ptid_t last_wait_event_ptid; | 
 |   43 }; | 
 |   44  | 
|   33 /* Print a debug trace on standard output if debug_threads is set.  */ |   45 /* Print a debug trace on standard output if debug_threads is set.  */ | 
|   34  |   46  | 
|   35 static void |   47 static void | 
|   36 lynx_debug (char *string, ...) |   48 lynx_debug (char *string, ...) | 
|   37 { |   49 { | 
|   38   va_list args; |   50   va_list args; | 
|   39  |   51  | 
|   40   if (!debug_threads) |   52   if (!debug_threads) | 
|   41     return; |   53     return; | 
|   42  |   54  | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   89 lynx_ptrace_pid_from_ptid (ptid_t ptid) |  101 lynx_ptrace_pid_from_ptid (ptid_t ptid) | 
|   90 { |  102 { | 
|   91   return BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid)); |  103   return BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid)); | 
|   92 } |  104 } | 
|   93  |  105  | 
|   94 /* Return a string image of the ptrace REQUEST number.  */ |  106 /* Return a string image of the ptrace REQUEST number.  */ | 
|   95  |  107  | 
|   96 static char * |  108 static char * | 
|   97 ptrace_request_to_str (int request) |  109 ptrace_request_to_str (int request) | 
|   98 { |  110 { | 
 |  111 #define CASE(X) case X: return #X | 
|   99   switch (request) |  112   switch (request) | 
|  100     { |  113     { | 
|  101       case PTRACE_TRACEME: |  114       CASE(PTRACE_TRACEME); | 
|  102         return "PTRACE_TRACEME"; |  115       CASE(PTRACE_PEEKTEXT); | 
|  103         break; |  116       CASE(PTRACE_PEEKDATA); | 
|  104       case PTRACE_PEEKTEXT: |  117       CASE(PTRACE_PEEKUSER); | 
|  105         return "PTRACE_PEEKTEXT"; |  118       CASE(PTRACE_POKETEXT); | 
|  106         break; |  119       CASE(PTRACE_POKEDATA); | 
|  107       case PTRACE_PEEKDATA: |  120       CASE(PTRACE_POKEUSER); | 
|  108         return "PTRACE_PEEKDATA"; |  121       CASE(PTRACE_CONT); | 
|  109         break; |  122       CASE(PTRACE_KILL); | 
|  110       case PTRACE_PEEKUSER: |  123       CASE(PTRACE_SINGLESTEP); | 
|  111         return "PTRACE_PEEKUSER"; |  124       CASE(PTRACE_ATTACH); | 
|  112         break; |  125       CASE(PTRACE_DETACH); | 
|  113       case PTRACE_POKETEXT: |  126       CASE(PTRACE_GETREGS); | 
|  114         return "PTRACE_POKETEXT"; |  127       CASE(PTRACE_SETREGS); | 
|  115         break; |  128       CASE(PTRACE_GETFPREGS); | 
|  116       case PTRACE_POKEDATA: |  129       CASE(PTRACE_SETFPREGS); | 
|  117         return "PTRACE_POKEDATA"; |  130       CASE(PTRACE_READDATA); | 
|  118         break; |  131       CASE(PTRACE_WRITEDATA); | 
|  119       case PTRACE_POKEUSER: |  132       CASE(PTRACE_READTEXT); | 
|  120         return "PTRACE_POKEUSER"; |  133       CASE(PTRACE_WRITETEXT); | 
|  121         break; |  134       CASE(PTRACE_GETFPAREGS); | 
|  122       case PTRACE_CONT: |  135       CASE(PTRACE_SETFPAREGS); | 
|  123         return "PTRACE_CONT"; |  136       CASE(PTRACE_GETWINDOW); | 
|  124         break; |  137       CASE(PTRACE_SETWINDOW); | 
|  125       case PTRACE_KILL: |  138       CASE(PTRACE_SYSCALL); | 
|  126         return "PTRACE_KILL"; |  139       CASE(PTRACE_DUMPCORE); | 
|  127         break; |  140       CASE(PTRACE_SETWRBKPT); | 
|  128       case PTRACE_SINGLESTEP: |  141       CASE(PTRACE_SETACBKPT); | 
|  129         return "PTRACE_SINGLESTEP"; |  142       CASE(PTRACE_CLRBKPT); | 
|  130         break; |  143       CASE(PTRACE_GET_UCODE); | 
|  131       case PTRACE_ATTACH: |  | 
|  132         return "PTRACE_ATTACH"; |  | 
|  133         break; |  | 
|  134       case PTRACE_DETACH: |  | 
|  135         return "PTRACE_DETACH"; |  | 
|  136         break; |  | 
|  137       case PTRACE_GETREGS: |  | 
|  138         return "PTRACE_GETREGS"; |  | 
|  139         break; |  | 
|  140       case PTRACE_SETREGS: |  | 
|  141         return "PTRACE_SETREGS"; |  | 
|  142         break; |  | 
|  143       case PTRACE_GETFPREGS: |  | 
|  144         return "PTRACE_GETFPREGS"; |  | 
|  145         break; |  | 
|  146       case PTRACE_SETFPREGS: |  | 
|  147         return "PTRACE_SETFPREGS"; |  | 
|  148         break; |  | 
|  149       case PTRACE_READDATA: |  | 
|  150         return "PTRACE_READDATA"; |  | 
|  151         break; |  | 
|  152       case PTRACE_WRITEDATA: |  | 
|  153         return "PTRACE_WRITEDATA"; |  | 
|  154         break; |  | 
|  155       case PTRACE_READTEXT: |  | 
|  156         return "PTRACE_READTEXT"; |  | 
|  157         break; |  | 
|  158       case PTRACE_WRITETEXT: |  | 
|  159         return "PTRACE_WRITETEXT"; |  | 
|  160         break; |  | 
|  161       case PTRACE_GETFPAREGS: |  | 
|  162         return "PTRACE_GETFPAREGS"; |  | 
|  163         break; |  | 
|  164       case PTRACE_SETFPAREGS: |  | 
|  165         return "PTRACE_SETFPAREGS"; |  | 
|  166         break; |  | 
|  167       case PTRACE_GETWINDOW: |  | 
|  168         return "PTRACE_GETWINDOW"; |  | 
|  169         break; |  | 
|  170       case PTRACE_SETWINDOW: |  | 
|  171         return "PTRACE_SETWINDOW"; |  | 
|  172         break; |  | 
|  173       case PTRACE_SYSCALL: |  | 
|  174         return "PTRACE_SYSCALL"; |  | 
|  175         break; |  | 
|  176       case PTRACE_DUMPCORE: |  | 
|  177         return "PTRACE_DUMPCORE"; |  | 
|  178         break; |  | 
|  179       case PTRACE_SETWRBKPT: |  | 
|  180         return "PTRACE_SETWRBKPT"; |  | 
|  181         break; |  | 
|  182       case PTRACE_SETACBKPT: |  | 
|  183         return "PTRACE_SETACBKPT"; |  | 
|  184         break; |  | 
|  185       case PTRACE_CLRBKPT: |  | 
|  186         return "PTRACE_CLRBKPT"; |  | 
|  187         break; |  | 
|  188       case PTRACE_GET_UCODE: |  | 
|  189         return "PTRACE_GET_UCODE"; |  | 
|  190         break; |  | 
|  191 #ifdef PT_READ_GPR |  144 #ifdef PT_READ_GPR | 
|  192       case PT_READ_GPR: |  145       CASE(PT_READ_GPR); | 
|  193         return "PT_READ_GPR"; |  | 
|  194         break; |  | 
|  195 #endif |  146 #endif | 
|  196 #ifdef PT_WRITE_GPR |  147 #ifdef PT_WRITE_GPR | 
|  197       case PT_WRITE_GPR: |  148       CASE(PT_WRITE_GPR); | 
|  198         return "PT_WRITE_GPR"; |  | 
|  199         break; |  | 
|  200 #endif |  149 #endif | 
|  201 #ifdef PT_READ_FPR |  150 #ifdef PT_READ_FPR | 
|  202       case PT_READ_FPR: |  151       CASE(PT_READ_FPR); | 
|  203         return "PT_READ_FPR"; |  | 
|  204         break; |  | 
|  205 #endif |  152 #endif | 
|  206 #ifdef PT_WRITE_FPR |  153 #ifdef PT_WRITE_FPR | 
|  207       case PT_WRITE_FPR: |  154       CASE(PT_WRITE_FPR); | 
|  208         return "PT_WRITE_FPR"; |  | 
|  209         break; |  | 
|  210 #endif |  155 #endif | 
|  211 #ifdef PT_READ_VPR |  156 #ifdef PT_READ_VPR | 
|  212       case PT_READ_VPR: |  157       CASE(PT_READ_VPR); | 
|  213         return "PT_READ_VPR"; |  | 
|  214         break; |  | 
|  215 #endif |  158 #endif | 
|  216 #ifdef PT_WRITE_VPR |  159 #ifdef PT_WRITE_VPR | 
|  217       case PT_WRITE_VPR: |  160       CASE(PT_WRITE_VPR); | 
|  218         return "PT_WRITE_VPR"; |  | 
|  219         break; |  | 
|  220 #endif |  161 #endif | 
|  221 #ifdef PTRACE_PEEKUSP |  162 #ifdef PTRACE_PEEKUSP | 
|  222       case PTRACE_PEEKUSP: |  163       CASE(PTRACE_PEEKUSP); | 
|  223         return "PTRACE_PEEKUSP"; |  | 
|  224         break; |  | 
|  225 #endif |  164 #endif | 
|  226 #ifdef PTRACE_POKEUSP |  165 #ifdef PTRACE_POKEUSP | 
|  227       case PTRACE_POKEUSP: |  166       CASE(PTRACE_POKEUSP); | 
|  228         return "PTRACE_POKEUSP"; |  | 
|  229         break; |  | 
|  230 #endif |  167 #endif | 
|  231       case PTRACE_PEEKTHREAD: |  168       CASE(PTRACE_PEEKTHREAD); | 
|  232         return "PTRACE_PEEKTHREAD"; |  169       CASE(PTRACE_THREADUSER); | 
|  233         break; |  170       CASE(PTRACE_FPREAD); | 
|  234       case PTRACE_THREADUSER: |  171       CASE(PTRACE_FPWRITE); | 
|  235         return "PTRACE_THREADUSER"; |  172       CASE(PTRACE_SETSIG); | 
|  236         break; |  173       CASE(PTRACE_CONT_ONE); | 
|  237       case PTRACE_FPREAD: |  174       CASE(PTRACE_KILL_ONE); | 
|  238         return "PTRACE_FPREAD"; |  175       CASE(PTRACE_SINGLESTEP_ONE); | 
|  239         break; |  176       CASE(PTRACE_GETLOADINFO); | 
|  240       case PTRACE_FPWRITE: |  177       CASE(PTRACE_GETTRACESIG); | 
|  241         return "PTRACE_FPWRITE"; |  178 #ifdef PTRACE_GETTHREADLIST | 
|  242         break; |  179       CASE(PTRACE_GETTHREADLIST); | 
|  243       case PTRACE_SETSIG: |  180 #endif | 
|  244         return "PTRACE_SETSIG"; |  | 
|  245         break; |  | 
|  246       case PTRACE_CONT_ONE: |  | 
|  247         return "PTRACE_CONT_ONE"; |  | 
|  248         break; |  | 
|  249       case PTRACE_KILL_ONE: |  | 
|  250         return "PTRACE_KILL_ONE"; |  | 
|  251         break; |  | 
|  252       case PTRACE_SINGLESTEP_ONE: |  | 
|  253         return "PTRACE_SINGLESTEP_ONE"; |  | 
|  254         break; |  | 
|  255       case PTRACE_GETLOADINFO: |  | 
|  256         return "PTRACE_GETLOADINFO"; |  | 
|  257         break; |  | 
|  258       case PTRACE_GETTHREADLIST: |  | 
|  259         return "PTRACE_GETTHREADLIST"; |  | 
|  260         break; |  | 
|  261     } |  181     } | 
 |  182 #undef CASE | 
 |  183  | 
|  262   return "<unknown-request>"; |  184   return "<unknown-request>"; | 
|  263 } |  185 } | 
|  264  |  186  | 
|  265 /* A wrapper around ptrace that allows us to print debug traces of |  187 /* A wrapper around ptrace that allows us to print debug traces of | 
|  266    ptrace calls if debug traces are activated.  */ |  188    ptrace calls if debug traces are activated.  */ | 
|  267  |  189  | 
|  268 static int |  190 static int | 
|  269 lynx_ptrace (int request, ptid_t ptid, int addr, int data, int addr2) |  191 lynx_ptrace (int request, ptid_t ptid, int addr, int data, int addr2) | 
|  270 { |  192 { | 
|  271   int result; |  193   int result; | 
|  272   const int pid = lynx_ptrace_pid_from_ptid (ptid); |  194   const int pid = lynx_ptrace_pid_from_ptid (ptid); | 
|  273   int saved_errno; |  195   int saved_errno; | 
|  274  |  196  | 
|  275   if (debug_threads) |  197   if (debug_threads) | 
|  276     fprintf (stderr, "PTRACE (%s, pid=%d(pid=%d, tid=%d), addr=0x%x, " |  198     fprintf (stderr, "PTRACE (%s, pid=%d(pid=%d, tid=%d), addr=0x%x, " | 
|  277              "data=0x%x, addr2=0x%x)", |  199              "data=0x%x, addr2=0x%x)", | 
|  278              ptrace_request_to_str (request), pid, PIDGET (pid), TIDGET (pid), |  200              ptrace_request_to_str (request), pid, PIDGET (pid), TIDGET (pid), | 
|  279              addr, data, addr2); |  201              addr, data, addr2); | 
|  280   result = ptrace (request, pid, addr, data, addr2); |  202   result = ptrace (request, pid, addr, data, addr2); | 
|  281   saved_errno = errno; |  203   saved_errno = errno; | 
|  282   if (debug_threads) |  204   if (debug_threads) | 
|  283     fprintf (stderr, " -> %d (=0x%x)\n", result, result); |  205     fprintf (stderr, " -> %d (=0x%x)\n", result, result); | 
|  284  |  206  | 
|  285   errno = saved_errno; |  207   errno = saved_errno; | 
|  286   return result; |  208   return result; | 
|  287 } |  209 } | 
|  288  |  210  | 
 |  211 /* Call add_process with the given parameters, and initializes | 
 |  212    the process' private data.  */ | 
 |  213  | 
 |  214 static struct process_info * | 
 |  215 lynx_add_process (int pid, int attached) | 
 |  216 { | 
 |  217   struct process_info *proc; | 
 |  218  | 
 |  219   proc = add_process (pid, attached); | 
 |  220   proc->tdesc = lynx_tdesc; | 
 |  221   proc->private = xcalloc (1, sizeof (*proc->private)); | 
 |  222   proc->private->last_wait_event_ptid = null_ptid; | 
 |  223  | 
 |  224   return proc; | 
 |  225 } | 
 |  226  | 
|  289 /* Implement the create_inferior method of the target_ops vector.  */ |  227 /* Implement the create_inferior method of the target_ops vector.  */ | 
|  290  |  228  | 
|  291 static int |  229 static int | 
|  292 lynx_create_inferior (char *program, char **allargs) |  230 lynx_create_inferior (char *program, char **allargs) | 
|  293 { |  231 { | 
|  294   struct process_info *new_process; |  | 
|  295   int pid; |  232   int pid; | 
|  296  |  233  | 
|  297   lynx_debug ("lynx_create_inferior ()"); |  234   lynx_debug ("lynx_create_inferior ()"); | 
|  298  |  235  | 
|  299   pid = fork (); |  236   pid = fork (); | 
|  300   if (pid < 0) |  237   if (pid < 0) | 
|  301     perror_with_name ("fork"); |  238     perror_with_name ("fork"); | 
|  302  |  239  | 
|  303   if (pid == 0) |  240   if (pid == 0) | 
|  304     { |  241     { | 
|  305       int pgrp; |  242       int pgrp; | 
|  306  |  243  | 
 |  244       close_most_fds (); | 
 |  245  | 
|  307       /* Switch child to its own process group so that signals won't |  246       /* Switch child to its own process group so that signals won't | 
|  308          directly affect gdbserver. */ |  247          directly affect gdbserver. */ | 
|  309       pgrp = getpid(); |  248       pgrp = getpid(); | 
|  310       setpgid (0, pgrp); |  249       setpgid (0, pgrp); | 
|  311       ioctl (0, TIOCSPGRP, &pgrp); |  250       ioctl (0, TIOCSPGRP, &pgrp); | 
|  312       lynx_ptrace (PTRACE_TRACEME, null_ptid, 0, 0, 0); |  251       lynx_ptrace (PTRACE_TRACEME, null_ptid, 0, 0, 0); | 
|  313       execv (program, allargs); |  252       execv (program, allargs); | 
|  314       fprintf (stderr, "Cannot exec %s: %s.\n", program, strerror (errno)); |  253       fprintf (stderr, "Cannot exec %s: %s.\n", program, strerror (errno)); | 
|  315       fflush (stderr); |  254       fflush (stderr); | 
|  316       _exit (0177); |  255       _exit (0177); | 
|  317     } |  256     } | 
|  318  |  257  | 
|  319   new_process = add_process (pid, 0); |  258   lynx_add_process (pid, 0); | 
|  320   /* Do not add the process thread just yet, as we do not know its tid. |  259   /* Do not add the process thread just yet, as we do not know its tid. | 
|  321      We will add it later, during the wait for the STOP event corresponding |  260      We will add it later, during the wait for the STOP event corresponding | 
|  322      to the lynx_ptrace (PTRACE_TRACEME) call above.  */ |  261      to the lynx_ptrace (PTRACE_TRACEME) call above.  */ | 
|  323   return pid; |  262   return pid; | 
|  324 } |  263 } | 
|  325  |  264  | 
 |  265 /* Assuming we've just attached to a running inferior whose pid is PID, | 
 |  266    add all threads running in that process.  */ | 
 |  267  | 
 |  268 static void | 
 |  269 lynx_add_threads_after_attach (int pid) | 
 |  270 { | 
 |  271   /* Ugh!  There appears to be no way to get the list of threads | 
 |  272      in the program we just attached to.  So get the list by calling | 
 |  273      the "ps" command.  This is only needed now, as we will then | 
 |  274      keep the thread list up to date thanks to thread creation and | 
 |  275      exit notifications.  */ | 
 |  276   FILE *f; | 
 |  277   char buf[256]; | 
 |  278   int thread_pid, thread_tid; | 
 |  279  | 
 |  280   f = popen ("ps atx", "r"); | 
 |  281   if (f == NULL) | 
 |  282     perror_with_name ("Cannot get thread list"); | 
 |  283  | 
 |  284   while (fgets (buf, sizeof (buf), f) != NULL) | 
 |  285     if ((sscanf (buf, "%d %d", &thread_pid, &thread_tid) == 2 | 
 |  286          && thread_pid == pid)) | 
 |  287     { | 
 |  288       ptid_t thread_ptid = lynx_ptid_build (pid, thread_tid); | 
 |  289  | 
 |  290       if (!find_thread_ptid (thread_ptid)) | 
 |  291         { | 
 |  292           lynx_debug ("New thread: (pid = %d, tid = %d)", | 
 |  293                       pid, thread_tid); | 
 |  294           add_thread (thread_ptid, NULL); | 
 |  295         } | 
 |  296     } | 
 |  297  | 
 |  298   pclose (f); | 
 |  299 } | 
 |  300  | 
|  326 /* Implement the attach target_ops method.  */ |  301 /* Implement the attach target_ops method.  */ | 
|  327  |  302  | 
|  328 static int |  303 static int | 
|  329 lynx_attach (unsigned long pid) |  304 lynx_attach (unsigned long pid) | 
|  330 { |  305 { | 
|  331   struct process_info *new_process; |  | 
|  332   ptid_t ptid = lynx_ptid_build (pid, 0); |  306   ptid_t ptid = lynx_ptid_build (pid, 0); | 
|  333  |  307  | 
|  334   if (lynx_ptrace (PTRACE_ATTACH, ptid, 0, 0, 0) != 0) |  308   if (lynx_ptrace (PTRACE_ATTACH, ptid, 0, 0, 0) != 0) | 
|  335     error ("Cannot attach to process %lu: %s (%d)\n", pid, |  309     error ("Cannot attach to process %lu: %s (%d)\n", pid, | 
|  336            strerror (errno), errno); |  310            strerror (errno), errno); | 
|  337  |  311  | 
|  338   new_process = add_process (pid, 1); |  312   lynx_add_process (pid, 1); | 
|  339   add_thread (ptid, NULL); |  313   lynx_add_threads_after_attach (pid); | 
|  340  |  314  | 
|  341   return 0; |  315   return 0; | 
|  342 } |  316 } | 
|  343  |  317  | 
|  344 /* Implement the resume target_ops method.  */ |  318 /* Implement the resume target_ops method.  */ | 
|  345  |  319  | 
|  346 static void |  320 static void | 
|  347 lynx_resume (struct thread_resume *resume_info, size_t n) |  321 lynx_resume (struct thread_resume *resume_info, size_t n) | 
|  348 { |  322 { | 
|  349   ptid_t inferior_ptid = thread_to_gdb_id (current_inferior); |  | 
|  350   /* FIXME: Assume for now that n == 1.  */ |  323   /* FIXME: Assume for now that n == 1.  */ | 
 |  324   ptid_t ptid = resume_info[0].thread; | 
|  351   const int request = (resume_info[0].kind == resume_step |  325   const int request = (resume_info[0].kind == resume_step | 
|  352                        ? PTRACE_SINGLESTEP : PTRACE_CONT); |  326                        ? PTRACE_SINGLESTEP : PTRACE_CONT); | 
|  353   const int signal = resume_info[0].sig; |  327   const int signal = resume_info[0].sig; | 
|  354   int ret; |  328  | 
 |  329   /* If given a minus_one_ptid, then try using the current_process' | 
 |  330      private->last_wait_event_ptid.  On most LynxOS versions, | 
 |  331      using any of the process' thread works well enough, but | 
 |  332      LynxOS 178 is a little more sensitive, and triggers some | 
 |  333      unexpected signals (Eg SIG61) when we resume the inferior | 
 |  334      using a different thread.  */ | 
 |  335   if (ptid_equal (ptid, minus_one_ptid)) | 
 |  336     ptid = current_process()->private->last_wait_event_ptid; | 
 |  337  | 
 |  338   /* The ptid might still be minus_one_ptid; this can happen between | 
 |  339      the moment we create the inferior or attach to a process, and | 
 |  340      the moment we resume its execution for the first time.  It is | 
 |  341      fine to use the current_inferior's ptid in those cases.  */ | 
 |  342   if (ptid_equal (ptid, minus_one_ptid)) | 
 |  343     ptid = thread_to_gdb_id (current_inferior); | 
|  355  |  344  | 
|  356   regcache_invalidate (); |  345   regcache_invalidate (); | 
|  357   ret = lynx_ptrace (request, inferior_ptid, 1, signal, 0); |  346  | 
 |  347   errno = 0; | 
 |  348   lynx_ptrace (request, ptid, 1, signal, 0); | 
 |  349   if (errno) | 
 |  350     perror_with_name ("ptrace"); | 
|  358 } |  351 } | 
|  359  |  352  | 
|  360 /* Resume the execution of the given PTID.  */ |  353 /* Resume the execution of the given PTID.  */ | 
|  361  |  354  | 
|  362 static void |  355 static void | 
|  363 lynx_continue (ptid_t ptid) |  356 lynx_continue (ptid_t ptid) | 
|  364 { |  357 { | 
|  365   struct thread_resume resume_info; |  358   struct thread_resume resume_info; | 
|  366  |  359  | 
|  367   resume_info.thread = ptid; |  360   resume_info.thread = ptid; | 
|  368   resume_info.kind = resume_continue; |  361   resume_info.kind = resume_continue; | 
|  369   resume_info.sig = 0; |  362   resume_info.sig = 0; | 
|  370  |  363  | 
|  371   lynx_resume (&resume_info, 1); |  364   lynx_resume (&resume_info, 1); | 
|  372 } |  365 } | 
|  373  |  366  | 
|  374 /* Remove all inferiors and associated threads.  */ |  | 
|  375  |  | 
|  376 static void |  | 
|  377 lynx_clear_inferiors (void) |  | 
|  378 { |  | 
|  379   /* We do not use private data, so nothing much to do except calling |  | 
|  380      clear_inferiors.  */ |  | 
|  381   clear_inferiors (); |  | 
|  382 } |  | 
|  383  |  | 
|  384 /* A wrapper around waitpid that handles the various idiosyncrasies |  367 /* A wrapper around waitpid that handles the various idiosyncrasies | 
|  385    of LynxOS' waitpid.  */ |  368    of LynxOS' waitpid.  */ | 
|  386  |  369  | 
|  387 static int |  370 static int | 
|  388 lynx_waitpid (int pid, int *stat_loc) |  371 lynx_waitpid (int pid, int *stat_loc) | 
|  389 { |  372 { | 
|  390   int ret = 0; |  373   int ret = 0; | 
|  391  |  374  | 
|  392   while (1) |  375   while (1) | 
|  393     { |  376     { | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  431  |  414  | 
|  432   if (ptid_equal (ptid, minus_one_ptid)) |  415   if (ptid_equal (ptid, minus_one_ptid)) | 
|  433     pid = lynx_ptid_get_pid (thread_to_gdb_id (current_inferior)); |  416     pid = lynx_ptid_get_pid (thread_to_gdb_id (current_inferior)); | 
|  434   else |  417   else | 
|  435     pid = BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid)); |  418     pid = BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid)); | 
|  436  |  419  | 
|  437 retry: |  420 retry: | 
|  438  |  421  | 
|  439   ret = lynx_waitpid (pid, &wstat); |  422   ret = lynx_waitpid (pid, &wstat); | 
|  440   new_ptid = lynx_ptid_build (ret, ((union wait *) &wstat)->w_tid); |  423   new_ptid = lynx_ptid_build (ret, ((union wait *) &wstat)->w_tid); | 
 |  424   find_process_pid (ret)->private->last_wait_event_ptid = new_ptid; | 
|  441  |  425  | 
|  442   /* If this is a new thread, then add it now.  The reason why we do |  426   /* If this is a new thread, then add it now.  The reason why we do | 
|  443      this here instead of when handling new-thread events is because |  427      this here instead of when handling new-thread events is because | 
|  444      we need to add the thread associated to the "main" thread - even |  428      we need to add the thread associated to the "main" thread - even | 
|  445      for non-threaded applications where the new-thread events are not |  429      for non-threaded applications where the new-thread events are not | 
|  446      generated.  */ |  430      generated.  */ | 
|  447   if (!find_thread_ptid (new_ptid)) |  431   if (!find_thread_ptid (new_ptid)) | 
|  448     add_thread (new_ptid, NULL); |  432     { | 
 |  433       lynx_debug ("New thread: (pid = %d, tid = %d)", | 
 |  434 »       »         lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid)); | 
 |  435       add_thread (new_ptid, NULL); | 
 |  436     } | 
|  449  |  437  | 
|  450   if (WIFSTOPPED (wstat)) |  438   if (WIFSTOPPED (wstat)) | 
|  451     { |  439     { | 
|  452       status->kind = TARGET_WAITKIND_STOPPED; |  440       status->kind = TARGET_WAITKIND_STOPPED; | 
|  453       status->value.integer = gdb_signal_from_host (WSTOPSIG (wstat)); |  441       status->value.integer = gdb_signal_from_host (WSTOPSIG (wstat)); | 
|  454       lynx_debug ("process stopped with signal: %d", |  442       lynx_debug ("process stopped with signal: %d", | 
|  455                   status->value.integer); |  443                   status->value.integer); | 
|  456     } |  444     } | 
|  457   else if (WIFEXITED (wstat)) |  445   else if (WIFEXITED (wstat)) | 
|  458     { |  446     { | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|  484       && status->value.integer == GDB_SIGNAL_TRAP) |  472       && status->value.integer == GDB_SIGNAL_TRAP) | 
|  485     { |  473     { | 
|  486       const int realsig = lynx_ptrace (PTRACE_GETTRACESIG, new_ptid, 0, 0, 0); |  474       const int realsig = lynx_ptrace (PTRACE_GETTRACESIG, new_ptid, 0, 0, 0); | 
|  487  |  475  | 
|  488       lynx_debug ("(realsig = %d)", realsig); |  476       lynx_debug ("(realsig = %d)", realsig); | 
|  489       switch (realsig) |  477       switch (realsig) | 
|  490         { |  478         { | 
|  491           case SIGNEWTHREAD: |  479           case SIGNEWTHREAD: | 
|  492             /* We just added the new thread above.  No need to do anything |  480             /* We just added the new thread above.  No need to do anything | 
|  493                further.  Just resume the execution again.  */ |  481                further.  Just resume the execution again.  */ | 
|  494 »           lynx_continue (ptid); |  482 »           lynx_continue (new_ptid); | 
|  495             goto retry; |  483             goto retry; | 
|  496  |  484  | 
|  497           case SIGTHREADEXIT: |  485           case SIGTHREADEXIT: | 
|  498             remove_thread (find_thread_ptid (new_ptid)); |  486             remove_thread (find_thread_ptid (new_ptid)); | 
|  499 »           lynx_continue (ptid); |  487 »           lynx_continue (new_ptid); | 
|  500             goto retry; |  488             goto retry; | 
|  501         } |  489         } | 
|  502     } |  490     } | 
|  503  |  491  | 
|  504   return new_ptid; |  492   return new_ptid; | 
|  505 } |  493 } | 
|  506  |  494  | 
|  507 /* A wrapper around lynx_wait_1 that also prints debug traces when |  495 /* A wrapper around lynx_wait_1 that also prints debug traces when | 
|  508    such debug traces have been activated.  */ |  496    such debug traces have been activated.  */ | 
|  509  |  497  | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  555   lynx_ptrace (PTRACE_DETACH, ptid, 0, 0, 0); |  543   lynx_ptrace (PTRACE_DETACH, ptid, 0, 0, 0); | 
|  556   the_target->mourn (process); |  544   the_target->mourn (process); | 
|  557   return 0; |  545   return 0; | 
|  558 } |  546 } | 
|  559  |  547  | 
|  560 /* Implement the mourn target_ops method.  */ |  548 /* Implement the mourn target_ops method.  */ | 
|  561  |  549  | 
|  562 static void |  550 static void | 
|  563 lynx_mourn (struct process_info *proc) |  551 lynx_mourn (struct process_info *proc) | 
|  564 { |  552 { | 
|  565   lynx_clear_inferiors (); |  553   /* Free our private data.  */ | 
 |  554   free (proc->private); | 
 |  555   proc->private = NULL; | 
 |  556  | 
 |  557   clear_inferiors (); | 
|  566 } |  558 } | 
|  567  |  559  | 
|  568 /* Implement the join target_ops method.  */ |  560 /* Implement the join target_ops method.  */ | 
|  569  |  561  | 
|  570 static void |  562 static void | 
|  571 lynx_join (int pid) |  563 lynx_join (int pid) | 
|  572 { |  564 { | 
|  573   /* The PTRACE_DETACH is sufficient to detach from the process. |  565   /* The PTRACE_DETACH is sufficient to detach from the process. | 
|  574      So no need to do anything extra.  */ |  566      So no need to do anything extra.  */ | 
|  575 } |  567 } | 
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  761   NULL,  /* handle_monitor_command */ |  753   NULL,  /* handle_monitor_command */ | 
|  762 }; |  754 }; | 
|  763  |  755  | 
|  764 void |  756 void | 
|  765 initialize_low (void) |  757 initialize_low (void) | 
|  766 { |  758 { | 
|  767   set_target_ops (&lynx_target_ops); |  759   set_target_ops (&lynx_target_ops); | 
|  768   the_low_target.arch_setup (); |  760   the_low_target.arch_setup (); | 
|  769 } |  761 } | 
|  770  |  762  | 
| OLD | NEW |