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

Side by Side 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« 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