GDB (xrefs)
linux-ptrace.c
Go to the documentation of this file.
1 /* Linux-specific ptrace manipulation routines.
2  Copyright (C) 2012-2015 Free Software Foundation, Inc.
3 
4  This file is part of GDB.
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 
19 #include "common-defs.h"
20 #include "linux-ptrace.h"
21 #include "linux-procfs.h"
22 #include "linux-waitpid.h"
23 #include "buffer.h"
24 #include "gdb_wait.h"
25 
26 /* Stores the ptrace options supported by the running kernel.
27  A value of -1 means we did not check for features yet. A value
28  of 0 means there are no supported features. */
29 static int supported_ptrace_options = -1;
30 
31 /* Find all possible reasons we could fail to attach PID and append
32  these as strings to the already initialized BUFFER. '\0'
33  termination of BUFFER must be done by the caller. */
34 
35 void
37 {
38  pid_t tracerpid;
39 
40  tracerpid = linux_proc_get_tracerpid_nowarn (pid);
41  if (tracerpid > 0)
42  buffer_xml_printf (buffer, _("process %d is already traced "
43  "by process %d"),
44  (int) pid, (int) tracerpid);
45 
47  buffer_xml_printf (buffer, _("process %d is a zombie "
48  "- the process has already terminated"),
49  (int) pid);
50 }
51 
52 /* See linux-ptrace.h. */
53 
54 char *
56 {
57  static char *reason_string;
58  struct buffer buffer;
59  char *warnings;
60  long lwpid = ptid_get_lwp (ptid);
61 
62  xfree (reason_string);
63 
64  buffer_init (&buffer);
65  linux_ptrace_attach_fail_reason (lwpid, &buffer);
66  buffer_grow_str0 (&buffer, "");
67  warnings = buffer_finish (&buffer);
68  if (warnings[0] != '\0')
69  reason_string = xstrprintf ("%s (%d), %s",
70  safe_strerror (err), err, warnings);
71  else
72  reason_string = xstrprintf ("%s (%d)",
73  safe_strerror (err), err);
74  xfree (warnings);
75  return reason_string;
76 }
77 
78 #if defined __i386__ || defined __x86_64__
79 
80 /* Address of the 'ret' instruction in asm code block below. */
81 EXTERN_C void linux_ptrace_test_ret_to_nx_instr (void);
82 
83 #include <sys/reg.h>
84 #include <sys/mman.h>
85 #include <signal.h>
86 
87 #endif /* defined __i386__ || defined __x86_64__ */
88 
89 /* Test broken off-trunk Linux kernel patchset for NX support on i386. It was
90  removed in Fedora kernel 88fa1f0332d188795ed73d7ac2b1564e11a0b4cd.
91 
92  Test also x86_64 arch for PaX support. */
93 
94 static void
96 {
97 #if defined __i386__ || defined __x86_64__
98  pid_t child, got_pid;
99  gdb_byte *return_address, *pc;
100  long l;
101  int status, kill_status;
102 
103  return_address = mmap (NULL, 2, PROT_READ | PROT_WRITE,
104  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
105  if (return_address == MAP_FAILED)
106  {
107  warning (_("linux_ptrace_test_ret_to_nx: Cannot mmap: %s"),
108  safe_strerror (errno));
109  return;
110  }
111 
112  /* Put there 'int3'. */
113  *return_address = 0xcc;
114 
115  child = fork ();
116  switch (child)
117  {
118  case -1:
119  warning (_("linux_ptrace_test_ret_to_nx: Cannot fork: %s"),
120  safe_strerror (errno));
121  return;
122 
123  case 0:
124  l = ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) NULL,
125  (PTRACE_TYPE_ARG4) NULL);
126  if (l != 0)
127  warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_TRACEME: %s"),
128  safe_strerror (errno));
129  else
130  {
131 #if defined __i386__
132  asm volatile ("pushl %0;"
133  ".globl linux_ptrace_test_ret_to_nx_instr;"
134  "linux_ptrace_test_ret_to_nx_instr:"
135  "ret"
136  : : "r" (return_address) : "%esp", "memory");
137 #elif defined __x86_64__
138  asm volatile ("pushq %0;"
139  ".globl linux_ptrace_test_ret_to_nx_instr;"
140  "linux_ptrace_test_ret_to_nx_instr:"
141  "ret"
142  : : "r" ((uint64_t) (uintptr_t) return_address)
143  : "%rsp", "memory");
144 #else
145 # error "!__i386__ && !__x86_64__"
146 #endif
147  gdb_assert_not_reached ("asm block did not terminate");
148  }
149 
150  _exit (1);
151  }
152 
153  errno = 0;
154  got_pid = waitpid (child, &status, 0);
155  if (got_pid != child)
156  {
157  warning (_("linux_ptrace_test_ret_to_nx: waitpid returned %ld: %s"),
158  (long) got_pid, safe_strerror (errno));
159  return;
160  }
161 
162  if (WIFSIGNALED (status))
163  {
164  if (WTERMSIG (status) != SIGKILL)
165  warning (_("linux_ptrace_test_ret_to_nx: WTERMSIG %d is not SIGKILL!"),
166  (int) WTERMSIG (status));
167  else
168  warning (_("Cannot call inferior functions, Linux kernel PaX "
169  "protection forbids return to non-executable pages!"));
170  return;
171  }
172 
173  if (!WIFSTOPPED (status))
174  {
175  warning (_("linux_ptrace_test_ret_to_nx: status %d is not WIFSTOPPED!"),
176  status);
177  return;
178  }
179 
180  /* We may get SIGSEGV due to missing PROT_EXEC of the return_address. */
181  if (WSTOPSIG (status) != SIGTRAP && WSTOPSIG (status) != SIGSEGV)
182  {
183  warning (_("linux_ptrace_test_ret_to_nx: "
184  "WSTOPSIG %d is neither SIGTRAP nor SIGSEGV!"),
185  (int) WSTOPSIG (status));
186  return;
187  }
188 
189  errno = 0;
190 #if defined __i386__
191  l = ptrace (PTRACE_PEEKUSER, child, (PTRACE_TYPE_ARG3) (uintptr_t) (EIP * 4),
192  (PTRACE_TYPE_ARG4) NULL);
193 #elif defined __x86_64__
194  l = ptrace (PTRACE_PEEKUSER, child, (PTRACE_TYPE_ARG3) (uintptr_t) (RIP * 8),
195  (PTRACE_TYPE_ARG4) NULL);
196 #else
197 # error "!__i386__ && !__x86_64__"
198 #endif
199  if (errno != 0)
200  {
201  warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_PEEKUSER: %s"),
202  safe_strerror (errno));
203  return;
204  }
205  pc = (void *) (uintptr_t) l;
206 
207  kill (child, SIGKILL);
208  ptrace (PTRACE_KILL, child, (PTRACE_TYPE_ARG3) NULL,
209  (PTRACE_TYPE_ARG4) NULL);
210 
211  errno = 0;
212  got_pid = waitpid (child, &kill_status, 0);
213  if (got_pid != child)
214  {
215  warning (_("linux_ptrace_test_ret_to_nx: "
216  "PTRACE_KILL waitpid returned %ld: %s"),
217  (long) got_pid, safe_strerror (errno));
218  return;
219  }
220  if (!WIFSIGNALED (kill_status))
221  {
222  warning (_("linux_ptrace_test_ret_to_nx: "
223  "PTRACE_KILL status %d is not WIFSIGNALED!"),
224  status);
225  return;
226  }
227 
228  /* + 1 is there as x86* stops after the 'int3' instruction. */
229  if (WSTOPSIG (status) == SIGTRAP && pc == return_address + 1)
230  {
231  /* PASS */
232  return;
233  }
234 
235  /* We may get SIGSEGV due to missing PROT_EXEC of the RETURN_ADDRESS page. */
236  if (WSTOPSIG (status) == SIGSEGV && pc == return_address)
237  {
238  /* PASS */
239  return;
240  }
241 
242  if ((void (*) (void)) pc != &linux_ptrace_test_ret_to_nx_instr)
243  warning (_("linux_ptrace_test_ret_to_nx: PC %p is neither near return "
244  "address %p nor is the return instruction %p!"),
245  pc, return_address, &linux_ptrace_test_ret_to_nx_instr);
246  else
247  warning (_("Cannot call inferior functions on this system - "
248  "Linux kernel with broken i386 NX (non-executable pages) "
249  "support detected!"));
250 #endif /* defined __i386__ || defined __x86_64__ */
251 }
252 
253 /* Helper function to fork a process and make the child process call
254  the function FUNCTION, passing CHILD_STACK as parameter.
255 
256  For MMU-less targets, clone is used instead of fork, and
257  CHILD_STACK is used as stack space for the cloned child. If NULL,
258  stack space is allocated via malloc (and subsequently passed to
259  FUNCTION). For MMU targets, CHILD_STACK is ignored. */
260 
261 static int
262 linux_fork_to_function (gdb_byte *child_stack, void (*function) (gdb_byte *))
263 {
264  int child_pid;
265 
266  /* Sanity check the function pointer. */
267  gdb_assert (function != NULL);
268 
269 #if defined(__UCLIBC__) && defined(HAS_NOMMU)
270 #define STACK_SIZE 4096
271 
272  if (child_stack == NULL)
273  child_stack = xmalloc (STACK_SIZE * 4);
274 
275  /* Use CLONE_VM instead of fork, to support uClinux (no MMU). */
276 #ifdef __ia64__
277  child_pid = __clone2 (function, child_stack, STACK_SIZE,
278  CLONE_VM | SIGCHLD, child_stack + STACK_SIZE * 2);
279 #else /* !__ia64__ */
280  child_pid = clone (function, child_stack + STACK_SIZE,
281  CLONE_VM | SIGCHLD, child_stack + STACK_SIZE * 2);
282 #endif /* !__ia64__ */
283 #else /* !defined(__UCLIBC) && defined(HAS_NOMMU) */
284  child_pid = fork ();
285 
286  if (child_pid == 0)
287  function (NULL);
288 #endif /* defined(__UCLIBC) && defined(HAS_NOMMU) */
289 
290  if (child_pid == -1)
291  perror_with_name (("fork"));
292 
293  return child_pid;
294 }
295 
296 /* A helper function for linux_check_ptrace_features, called after
297  the child forks a grandchild. */
298 
299 static void
301 {
302  /* Free any allocated stack. */
303  xfree (child_stack);
304 
305  /* This code is only reacheable by the grandchild (child's child)
306  process. */
307  _exit (0);
308 }
309 
310 /* A helper function for linux_check_ptrace_features, called after
311  the parent process forks a child. The child allows itself to
312  be traced by its parent. */
313 
314 static void
316 {
317  ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0);
318  kill (getpid (), SIGSTOP);
319 
320  /* Fork a grandchild. */
322 
323  /* This code is only reacheable by the child (grandchild's parent)
324  process. */
325  _exit (0);
326 }
327 
328 static void linux_test_for_tracesysgood (int child_pid);
329 static void linux_test_for_tracefork (int child_pid);
330 static void linux_test_for_exitkill (int child_pid);
331 
332 /* Determine ptrace features available on this target. */
333 
334 void
336 {
337  int child_pid, ret, status;
338 
339  /* Initialize the options. */
340  supported_ptrace_options = 0;
341 
342  /* Fork a child so we can do some testing. The child will call
343  linux_child_function and will get traced. The child will
344  eventually fork a grandchild so we can test fork event
345  reporting. */
346  child_pid = linux_fork_to_function (NULL, linux_child_function);
347 
348  ret = my_waitpid (child_pid, &status, 0);
349  if (ret == -1)
350  perror_with_name (("waitpid"));
351  else if (ret != child_pid)
352  error (_("linux_check_ptrace_features: waitpid: unexpected result %d."),
353  ret);
354  if (! WIFSTOPPED (status))
355  error (_("linux_check_ptrace_features: waitpid: unexpected status %d."),
356  status);
357 
358  linux_test_for_tracesysgood (child_pid);
359 
360  linux_test_for_tracefork (child_pid);
361 
362  linux_test_for_exitkill (child_pid);
363 
364  /* Clean things up and kill any pending children. */
365  do
366  {
367  ret = ptrace (PTRACE_KILL, child_pid, (PTRACE_TYPE_ARG3) 0,
368  (PTRACE_TYPE_ARG4) 0);
369  if (ret != 0)
370  warning (_("linux_check_ptrace_features: failed to kill child"));
371  my_waitpid (child_pid, &status, 0);
372  }
373  while (WIFSTOPPED (status));
374 }
375 
376 /* Determine if PTRACE_O_TRACESYSGOOD can be used to catch
377  syscalls. */
378 
379 static void
381 {
382  int ret;
383 
384  ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,
386 
387  if (ret == 0)
388  supported_ptrace_options |= PTRACE_O_TRACESYSGOOD;
389 }
390 
391 /* Determine if PTRACE_O_TRACEFORK can be used to follow fork
392  events. */
393 
394 static void
396 {
397  int ret, status;
398  long second_pid;
399 
400  /* First, set the PTRACE_O_TRACEFORK option. If this fails, we
401  know for sure that it is not supported. */
402  ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,
404 
405  if (ret != 0)
406  return;
407 
408  /* Check if the target supports PTRACE_O_TRACEVFORKDONE. */
409  ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,
410  (PTRACE_TYPE_ARG4) (PTRACE_O_TRACEFORK
412  if (ret == 0)
413  supported_ptrace_options |= PTRACE_O_TRACEVFORKDONE;
414 
415  /* Setting PTRACE_O_TRACEFORK did not cause an error, however we
416  don't know for sure that the feature is available; old
417  versions of PTRACE_SETOPTIONS ignored unknown options.
418  Therefore, we attach to the child process, use PTRACE_SETOPTIONS
419  to enable fork tracing, and let it fork. If the process exits,
420  we assume that we can't use PTRACE_O_TRACEFORK; if we get the
421  fork notification, and we can extract the new child's PID, then
422  we assume that we can.
423 
424  We do not explicitly check for vfork tracing here. It is
425  assumed that vfork tracing is available whenever fork tracing
426  is available. */
427  ret = ptrace (PTRACE_CONT, child_pid, (PTRACE_TYPE_ARG3) 0,
428  (PTRACE_TYPE_ARG4) 0);
429  if (ret != 0)
430  warning (_("linux_test_for_tracefork: failed to resume child"));
431 
432  ret = my_waitpid (child_pid, &status, 0);
433 
434  /* Check if we received a fork event notification. */
435  if (ret == child_pid && WIFSTOPPED (status)
437  {
438  /* We did receive a fork event notification. Make sure its PID
439  is reported. */
440  second_pid = 0;
441  ret = ptrace (PTRACE_GETEVENTMSG, child_pid, (PTRACE_TYPE_ARG3) 0,
442  (PTRACE_TYPE_ARG4) &second_pid);
443  if (ret == 0 && second_pid != 0)
444  {
445  int second_status;
446 
447  /* We got the PID from the grandchild, which means fork
448  tracing is supported. */
449  supported_ptrace_options |= PTRACE_O_TRACECLONE;
450  supported_ptrace_options |= (PTRACE_O_TRACEFORK
453 
454  /* Do some cleanup and kill the grandchild. */
455  my_waitpid (second_pid, &second_status, 0);
456  ret = ptrace (PTRACE_KILL, second_pid, (PTRACE_TYPE_ARG3) 0,
457  (PTRACE_TYPE_ARG4) 0);
458  if (ret != 0)
459  warning (_("linux_test_for_tracefork: "
460  "failed to kill second child"));
461  my_waitpid (second_pid, &status, 0);
462  }
463  }
464  else
465  warning (_("linux_test_for_tracefork: unexpected result from waitpid "
466  "(%d, status 0x%x)"), ret, status);
467 }
468 
469 /* Determine if PTRACE_O_EXITKILL can be used. */
470 
471 static void
472 linux_test_for_exitkill (int child_pid)
473 {
474  int ret;
475 
476  ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,
478 
479  if (ret == 0)
480  supported_ptrace_options |= PTRACE_O_EXITKILL;
481 }
482 
483 /* Enable reporting of all currently supported ptrace events.
484  OPTIONS is a bit mask of extended features we want enabled,
485  if supported by the kernel. PTRACE_O_TRACECLONE is always
486  enabled, if supported. */
487 
488 void
489 linux_enable_event_reporting (pid_t pid, int options)
490 {
491  /* Check if we have initialized the ptrace features for this
492  target. If not, do it now. */
493  if (supported_ptrace_options == -1)
495 
496  /* We always want clone events. */
497  options |= PTRACE_O_TRACECLONE;
498 
499  /* Filter out unsupported options. */
500  options &= supported_ptrace_options;
501 
502  /* Set the options. */
504  (PTRACE_TYPE_ARG4) (uintptr_t) options);
505 }
506 
507 /* Disable reporting of all currently supported ptrace events. */
508 
509 void
511 {
512  /* Set the options. */
514 }
515 
516 /* Returns non-zero if PTRACE_OPTIONS is contained within
517  SUPPORTED_PTRACE_OPTIONS, therefore supported. Returns 0
518  otherwise. */
519 
520 static int
521 ptrace_supports_feature (int ptrace_options)
522 {
523  if (supported_ptrace_options == -1)
525 
526  return ((supported_ptrace_options & ptrace_options) == ptrace_options);
527 }
528 
529 /* Returns non-zero if PTRACE_EVENT_FORK is supported by ptrace,
530  0 otherwise. Note that if PTRACE_EVENT_FORK is supported so is
531  PTRACE_EVENT_CLONE, PTRACE_EVENT_EXEC and PTRACE_EVENT_VFORK,
532  since they were all added to the kernel at the same time. */
533 
534 int
536 {
538 }
539 
540 /* Returns non-zero if PTRACE_EVENT_CLONE is supported by ptrace,
541  0 otherwise. Note that if PTRACE_EVENT_CLONE is supported so is
542  PTRACE_EVENT_FORK, PTRACE_EVENT_EXEC and PTRACE_EVENT_VFORK,
543  since they were all added to the kernel at the same time. */
544 
545 int
547 {
549 }
550 
551 /* Returns non-zero if PTRACE_O_TRACEVFORKDONE is supported by
552  ptrace, 0 otherwise. */
553 
554 int
556 {
558 }
559 
560 /* Returns non-zero if PTRACE_O_TRACESYSGOOD is supported by ptrace,
561  0 otherwise. */
562 
563 int
565 {
567 }
568 
569 /* Display possible problems on this system. Display them only once per GDB
570  execution. */
571 
572 void
574 {
575  static int warned = 0;
576 
577  if (warned)
578  return;
579  warned = 1;
580 
582 }
583 
584 /* Extract extended ptrace event from wait status. */
585 
586 int
588 {
589  return (wstat >> 16);
590 }
591 
592 /* Determine whether wait status denotes an extended event. */
593 
594 int
596 {
597  return (linux_ptrace_get_extended_event (wstat) != 0);
598 }
599 
600 /* Return true if the event in LP may be caused by breakpoint. */
601 
602 int
604 {
605  return (WIFSTOPPED (wstat)
606  && (WSTOPSIG (wstat) == SIGTRAP
607  /* SIGILL and SIGSEGV are also treated as traps in case a
608  breakpoint is inserted at the current PC. */
609  || WSTOPSIG (wstat) == SIGILL
610  || WSTOPSIG (wstat) == SIGSEGV));
611 }
#define PTRACE_GETEVENTMSG
Definition: linux-ptrace.h:59
void xfree(void *)
Definition: common-utils.c:97
void warning(const char *fmt,...)
Definition: errors.c:26
int linux_wstatus_maybe_breakpoint(int wstat)
Definition: linux-ptrace.c:603
static void linux_test_for_tracefork(int child_pid)
Definition: linux-ptrace.c:395
int linux_is_extended_waitstatus(int wstat)
Definition: linux-ptrace.c:595
void linux_check_ptrace_features(void)
Definition: linux-ptrace.c:335
#define _(String)
Definition: gdb_locale.h:40
static int ptrace_supports_feature(int ptrace_options)
Definition: linux-ptrace.c:521
PTRACE_TYPE_RET ptrace()
static int supported_ptrace_options
Definition: linux-ptrace.c:29
Definition: ptid.h:35
int linux_proc_pid_is_zombie_nowarn(pid_t pid)
Definition: linux-procfs.c:175
static void linux_child_function(gdb_byte *child_stack)
Definition: linux-ptrace.c:315
void linux_ptrace_attach_fail_reason(pid_t pid, struct buffer *buffer)
Definition: linux-ptrace.c:36
#define PTRACE_EVENT_FORK
Definition: linux-ptrace.h:71
#define WSTOPSIG
Definition: gdb_wait.h:75
void linux_ptrace_init_warnings(void)
Definition: linux-ptrace.c:573
char * linux_ptrace_attach_fail_reason_string(ptid_t ptid, int err)
Definition: linux-ptrace.c:55
#define WTERMSIG(w)
Definition: gdb_wait.h:71
int linux_supports_traceclone(void)
Definition: linux-ptrace.c:546
void buffer_xml_printf(struct buffer *buffer, const char *format,...)
Definition: buffer.c:76
mach_port_t mach_port_t name mach_port_t mach_port_t name error_t err
Definition: gnu-nat.c:1816
#define PTRACE_O_TRACEVFORKDONE
Definition: linux-ptrace.h:67
#define PTRACE_O_TRACEVFORK
Definition: linux-ptrace.h:64
mach_port_t mach_port_t name mach_port_t mach_port_t name error_t int status
Definition: gnu-nat.c:1816
int linux_ptrace_get_extended_event(int wstat)
Definition: linux-ptrace.c:587
#define gdb_assert_not_reached(message)
Definition: gdb_assert.h:56
static void linux_grandchild_function(gdb_byte *child_stack)
Definition: linux-ptrace.c:300
#define gdb_assert(expr)
Definition: gdb_assert.h:33
#define EXTERN_C
Definition: common-defs.h:58
#define PTRACE_O_TRACEFORK
Definition: linux-ptrace.h:63
char * xstrprintf(const char *format,...)
Definition: common-utils.c:107
#define PTRACE_O_TRACEEXEC
Definition: linux-ptrace.h:66
void * xmalloc(YYSIZE_T)
int linux_supports_tracefork(void)
Definition: linux-ptrace.c:535
static void linux_ptrace_test_ret_to_nx(void)
Definition: linux-ptrace.c:95
#define PTRACE_O_TRACECLONE
Definition: linux-ptrace.h:65
#define WIFSTOPPED(w)
Definition: gdb_wait.h:62
#define buffer_grow_str0(BUFFER, STRING)
Definition: buffer.h:56
static void linux_test_for_tracesysgood(int child_pid)
Definition: linux-ptrace.c:380
bfd_byte gdb_byte
Definition: common-types.h:38
#define MAP_FAILED
Definition: gdb_bfd.c:30
void void void void void void void void void perror_with_name(const char *string) ATTRIBUTE_NORETURN
Definition: utils.c:979
void buffer_init(struct buffer *buffer)
Definition: buffer.c:60
void linux_enable_event_reporting(pid_t pid, int options)
Definition: linux-ptrace.c:489
pid_t linux_proc_get_tracerpid_nowarn(pid_t lwpid)
Definition: linux-procfs.c:68
char * safe_strerror(int)
void linux_disable_event_reporting(pid_t pid)
Definition: linux-ptrace.c:510
#define PTRACE_SETOPTIONS
Definition: linux-ptrace.h:58
int linux_supports_tracevforkdone(void)
Definition: linux-ptrace.c:555
static void linux_test_for_exitkill(int child_pid)
Definition: linux-ptrace.c:472
Definition: buffer.h:23
int my_waitpid(int pid, int *status, int flags)
Definition: linux-waitpid.c:81
#define PTRACE_O_TRACESYSGOOD
Definition: linux-ptrace.h:62
#define WIFSIGNALED(w)
Definition: gdb_wait.h:48
long ptid_get_lwp(ptid_t ptid)
Definition: ptid.c:60
#define PTRACE_TYPE_ARG3
Definition: config.h:658
static int linux_fork_to_function(gdb_byte *child_stack, void(*function)(gdb_byte *))
Definition: linux-ptrace.c:262
#define PTRACE_TYPE_ARG4
Definition: config.h:661
char * buffer_finish(struct buffer *buffer)
Definition: buffer.c:66
#define PTRACE_O_EXITKILL
Definition: linux-ptrace.h:82
void error(const char *fmt,...)
Definition: errors.c:38
int linux_supports_tracesysgood(void)
Definition: linux-ptrace.c:564
mach_port_t mach_port_t name mach_port_t mach_port_t name error_t int int rusage_t pid_t pid
Definition: gnu-nat.c:1818