1 /* Linux-specific ptrace manipulation routines.
2 Copyright (C) 2012-2022 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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/>. */
19 #include "gdbsupport/common-defs.h"
20 #include "linux-ptrace.h"
21 #include "linux-procfs.h"
22 #include "linux-waitpid.h"
23 #include "gdbsupport/buffer.h"
24 #ifdef HAVE_SYS_PROCFS_H
25 #include <sys/procfs.h>
28 /* Stores the ptrace options supported by the running kernel.
29 A value of -1 means we did not check for features yet. A value
30 of 0 means there are no supported features. */
31 static int supported_ptrace_options
= -1;
33 /* Find all possible reasons we could fail to attach PID and return these
34 as a string. An empty string is returned if we didn't find any reason. */
37 linux_ptrace_attach_fail_reason (pid_t pid
)
39 pid_t tracerpid
= linux_proc_get_tracerpid_nowarn (pid
);
43 string_appendf (result
,
44 _("process %d is already traced by process %d"),
45 (int) pid
, (int) tracerpid
);
47 if (linux_proc_pid_is_zombie_nowarn (pid
))
48 string_appendf (result
,
49 _("process %d is a zombie - the process has already "
56 /* See linux-ptrace.h. */
59 linux_ptrace_attach_fail_reason_string (ptid_t ptid
, int err
)
61 long lwpid
= ptid
.lwp ();
62 std::string reason
= linux_ptrace_attach_fail_reason (lwpid
);
65 return string_printf ("%s (%d), %s", safe_strerror (err
), err
,
68 return string_printf ("%s (%d)", safe_strerror (err
), err
);
71 #if defined __i386__ || defined __x86_64__
73 /* Address of the 'ret' instruction in asm code block below. */
74 EXTERN_C
void linux_ptrace_test_ret_to_nx_instr (void);
80 #endif /* defined __i386__ || defined __x86_64__ */
82 /* Kill CHILD. WHO is used to report warnings. */
85 kill_child (pid_t child
, const char *who
)
90 if (kill (child
, SIGKILL
) != 0)
92 warning (_("%s: failed to kill child pid %ld %s"),
93 who
, (long) child
, safe_strerror (errno
));
98 got_pid
= my_waitpid (child
, &kill_status
, 0);
102 "kill waitpid returned %ld: %s"),
103 who
, (long) got_pid
, safe_strerror (errno
));
106 if (!WIFSIGNALED (kill_status
))
109 "kill status %d is not WIFSIGNALED!"),
115 /* Test broken off-trunk Linux kernel patchset for NX support on i386. It was
116 removed in Fedora kernel 88fa1f0332d188795ed73d7ac2b1564e11a0b4cd.
118 Test also x86_64 arch for PaX support. */
121 linux_ptrace_test_ret_to_nx (void)
123 #if defined __i386__ || defined __x86_64__
124 pid_t child
, got_pid
;
125 gdb_byte
*return_address
, *pc
;
131 = (gdb_byte
*) mmap (NULL
, 2, PROT_READ
| PROT_WRITE
,
132 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
133 if (return_address
== MAP_FAILED
)
135 warning (_("linux_ptrace_test_ret_to_nx: Cannot mmap: %s"),
136 safe_strerror (errno
));
140 /* Put there 'int3'. */
141 *return_address
= 0xcc;
147 warning (_("linux_ptrace_test_ret_to_nx: Cannot fork: %s"),
148 safe_strerror (errno
));
152 l
= ptrace (PTRACE_TRACEME
, 0, (PTRACE_TYPE_ARG3
) NULL
,
153 (PTRACE_TYPE_ARG4
) NULL
);
155 warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_TRACEME: %s"),
156 safe_strerror (errno
));
160 asm volatile ("pushl %0;"
161 ".globl linux_ptrace_test_ret_to_nx_instr;"
162 "linux_ptrace_test_ret_to_nx_instr:"
164 : : "r" (return_address
) : "memory");
165 #elif defined __x86_64__
166 asm volatile ("pushq %0;"
167 ".globl linux_ptrace_test_ret_to_nx_instr;"
168 "linux_ptrace_test_ret_to_nx_instr:"
170 : : "r" ((uint64_t) (uintptr_t) return_address
)
173 # error "!__i386__ && !__x86_64__"
175 gdb_assert_not_reached ("asm block did not terminate");
182 got_pid
= waitpid (child
, &status
, 0);
183 if (got_pid
!= child
)
185 warning (_("linux_ptrace_test_ret_to_nx: waitpid returned %ld: %s"),
186 (long) got_pid
, safe_strerror (errno
));
190 if (WIFSIGNALED (status
))
192 if (WTERMSIG (status
) != SIGKILL
)
193 warning (_("linux_ptrace_test_ret_to_nx: WTERMSIG %d is not SIGKILL!"),
194 (int) WTERMSIG (status
));
196 warning (_("Cannot call inferior functions, Linux kernel PaX "
197 "protection forbids return to non-executable pages!"));
201 if (!WIFSTOPPED (status
))
203 warning (_("linux_ptrace_test_ret_to_nx: status %d is not WIFSTOPPED!"),
205 kill_child (child
, "linux_ptrace_test_ret_to_nx");
209 /* We may get SIGSEGV due to missing PROT_EXEC of the return_address. */
210 if (WSTOPSIG (status
) != SIGTRAP
&& WSTOPSIG (status
) != SIGSEGV
)
212 warning (_("linux_ptrace_test_ret_to_nx: "
213 "WSTOPSIG %d is neither SIGTRAP nor SIGSEGV!"),
214 (int) WSTOPSIG (status
));
215 kill_child (child
, "linux_ptrace_test_ret_to_nx");
219 if (ptrace (PTRACE_GETREGS
, child
, (PTRACE_TYPE_ARG3
) 0,
220 (PTRACE_TYPE_ARG4
) ®s
) < 0)
222 warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_GETREGS: %s"),
223 safe_strerror (errno
));
226 pc
= (gdb_byte
*) (uintptr_t) regs
[EIP
];
227 #elif defined __x86_64__
228 pc
= (gdb_byte
*) (uintptr_t) regs
[RIP
];
230 # error "!__i386__ && !__x86_64__"
233 kill_child (child
, "linux_ptrace_test_ret_to_nx");
235 /* + 1 is there as x86* stops after the 'int3' instruction. */
236 if (WSTOPSIG (status
) == SIGTRAP
&& pc
== return_address
+ 1)
242 /* We may get SIGSEGV due to missing PROT_EXEC of the RETURN_ADDRESS page. */
243 if (WSTOPSIG (status
) == SIGSEGV
&& pc
== return_address
)
249 if ((void (*) (void)) pc
!= &linux_ptrace_test_ret_to_nx_instr
)
250 warning (_("linux_ptrace_test_ret_to_nx: PC %p is neither near return "
251 "address %p nor is the return instruction %p!"),
252 pc
, return_address
, &linux_ptrace_test_ret_to_nx_instr
);
254 warning (_("Cannot call inferior functions on this system - "
255 "Linux kernel with broken i386 NX (non-executable pages) "
256 "support detected!"));
257 #endif /* defined __i386__ || defined __x86_64__ */
260 /* Helper function to fork a process and make the child process call
261 the function FUNCTION, passing CHILD_STACK as parameter.
263 For MMU-less targets, clone is used instead of fork, and
264 CHILD_STACK is used as stack space for the cloned child. If NULL,
265 stack space is allocated via malloc (and subsequently passed to
266 FUNCTION). For MMU targets, CHILD_STACK is ignored. */
269 linux_fork_to_function (gdb_byte
*child_stack
, int (*function
) (void *))
273 /* Sanity check the function pointer. */
274 gdb_assert (function
!= NULL
);
276 #if defined(__UCLIBC__) && defined(HAS_NOMMU)
277 #define STACK_SIZE 4096
279 if (child_stack
== NULL
)
280 child_stack
= (gdb_byte
*) xmalloc (STACK_SIZE
* 4);
282 /* Use CLONE_VM instead of fork, to support uClinux (no MMU). */
284 child_pid
= __clone2 (function
, child_stack
, STACK_SIZE
,
285 CLONE_VM
| SIGCHLD
, child_stack
+ STACK_SIZE
* 2);
286 #else /* !__ia64__ */
287 child_pid
= clone (function
, child_stack
+ STACK_SIZE
,
288 CLONE_VM
| SIGCHLD
, child_stack
+ STACK_SIZE
* 2);
289 #endif /* !__ia64__ */
290 #else /* !defined(__UCLIBC) && defined(HAS_NOMMU) */
295 #endif /* defined(__UCLIBC) && defined(HAS_NOMMU) */
298 perror_with_name (("fork"));
303 /* A helper function for linux_check_ptrace_features, called after
304 the child forks a grandchild. */
307 linux_grandchild_function (void *child_stack
)
309 /* Free any allocated stack. */
312 /* This code is only reacheable by the grandchild (child's child)
317 /* A helper function for linux_check_ptrace_features, called after
318 the parent process forks a child. The child allows itself to
319 be traced by its parent. */
322 linux_child_function (void *child_stack
)
324 ptrace (PTRACE_TRACEME
, 0, (PTRACE_TYPE_ARG3
) 0, (PTRACE_TYPE_ARG4
) 0);
325 kill (getpid (), SIGSTOP
);
327 /* Fork a grandchild. */
328 linux_fork_to_function ((gdb_byte
*) child_stack
, linux_grandchild_function
);
330 /* This code is only reacheable by the child (grandchild's parent)
335 static void linux_test_for_tracesysgood (int child_pid
);
336 static void linux_test_for_tracefork (int child_pid
);
337 static void linux_test_for_exitkill (int child_pid
);
339 /* Determine ptrace features available on this target. */
342 linux_check_ptrace_features (void)
344 int child_pid
, ret
, status
;
346 /* Initialize the options. */
347 supported_ptrace_options
= 0;
349 /* Fork a child so we can do some testing. The child will call
350 linux_child_function and will get traced. The child will
351 eventually fork a grandchild so we can test fork event
353 child_pid
= linux_fork_to_function (NULL
, linux_child_function
);
355 ret
= my_waitpid (child_pid
, &status
, 0);
357 perror_with_name (("waitpid"));
358 else if (ret
!= child_pid
)
359 error (_("linux_check_ptrace_features: waitpid: unexpected result %d."),
361 if (! WIFSTOPPED (status
))
362 error (_("linux_check_ptrace_features: waitpid: unexpected status %d."),
365 linux_test_for_tracesysgood (child_pid
);
367 linux_test_for_tracefork (child_pid
);
369 linux_test_for_exitkill (child_pid
);
371 /* Kill child_pid. */
372 kill_child (child_pid
, "linux_check_ptrace_features");
375 /* Determine if PTRACE_O_TRACESYSGOOD can be used to catch
379 linux_test_for_tracesysgood (int child_pid
)
383 ret
= ptrace (PTRACE_SETOPTIONS
, child_pid
, (PTRACE_TYPE_ARG3
) 0,
384 (PTRACE_TYPE_ARG4
) PTRACE_O_TRACESYSGOOD
);
387 supported_ptrace_options
|= PTRACE_O_TRACESYSGOOD
;
390 /* Determine if PTRACE_O_TRACEFORK can be used to follow fork
394 linux_test_for_tracefork (int child_pid
)
399 /* First, set the PTRACE_O_TRACEFORK option. If this fails, we
400 know for sure that it is not supported. */
401 ret
= ptrace (PTRACE_SETOPTIONS
, child_pid
, (PTRACE_TYPE_ARG3
) 0,
402 (PTRACE_TYPE_ARG4
) PTRACE_O_TRACEFORK
);
407 /* Check if the target supports PTRACE_O_TRACEVFORKDONE. */
408 ret
= ptrace (PTRACE_SETOPTIONS
, child_pid
, (PTRACE_TYPE_ARG3
) 0,
409 (PTRACE_TYPE_ARG4
) (PTRACE_O_TRACEFORK
410 | PTRACE_O_TRACEVFORKDONE
));
412 supported_ptrace_options
|= PTRACE_O_TRACEVFORKDONE
;
414 /* Setting PTRACE_O_TRACEFORK did not cause an error, however we
415 don't know for sure that the feature is available; old
416 versions of PTRACE_SETOPTIONS ignored unknown options.
417 Therefore, we attach to the child process, use PTRACE_SETOPTIONS
418 to enable fork tracing, and let it fork. If the process exits,
419 we assume that we can't use PTRACE_O_TRACEFORK; if we get the
420 fork notification, and we can extract the new child's PID, then
421 we assume that we can.
423 We do not explicitly check for vfork tracing here. It is
424 assumed that vfork tracing is available whenever fork tracing
426 ret
= ptrace (PTRACE_CONT
, child_pid
, (PTRACE_TYPE_ARG3
) 0,
427 (PTRACE_TYPE_ARG4
) 0);
429 warning (_("linux_test_for_tracefork: failed to resume child"));
431 ret
= my_waitpid (child_pid
, &status
, 0);
433 /* Check if we received a fork event notification. */
434 if (ret
== child_pid
&& WIFSTOPPED (status
)
435 && linux_ptrace_get_extended_event (status
) == PTRACE_EVENT_FORK
)
437 /* We did receive a fork event notification. Make sure its PID
440 ret
= ptrace (PTRACE_GETEVENTMSG
, child_pid
, (PTRACE_TYPE_ARG3
) 0,
441 (PTRACE_TYPE_ARG4
) &second_pid
);
442 if (ret
== 0 && second_pid
!= 0)
446 /* We got the PID from the grandchild, which means fork
447 tracing is supported. */
448 supported_ptrace_options
|= PTRACE_O_TRACECLONE
;
449 supported_ptrace_options
|= (PTRACE_O_TRACEFORK
450 | PTRACE_O_TRACEVFORK
451 | PTRACE_O_TRACEEXEC
);
453 /* Do some cleanup and kill the grandchild. */
454 my_waitpid (second_pid
, &second_status
, 0);
455 kill_child (second_pid
, "linux_test_for_tracefork");
459 warning (_("linux_test_for_tracefork: unexpected result from waitpid "
460 "(%d, status 0x%x)"), ret
, status
);
463 /* Determine if PTRACE_O_EXITKILL can be used. */
466 linux_test_for_exitkill (int child_pid
)
470 ret
= ptrace (PTRACE_SETOPTIONS
, child_pid
, (PTRACE_TYPE_ARG3
) 0,
471 (PTRACE_TYPE_ARG4
) PTRACE_O_EXITKILL
);
474 supported_ptrace_options
|= PTRACE_O_EXITKILL
;
477 /* Enable reporting of all currently supported ptrace events.
478 OPTIONS is a bit mask of extended features we want enabled,
479 if supported by the kernel. PTRACE_O_TRACECLONE is always
480 enabled, if supported. */
483 linux_enable_event_reporting (pid_t pid
, int options
)
485 /* Check if we have initialized the ptrace features for this
486 target. If not, do it now. */
487 if (supported_ptrace_options
== -1)
488 linux_check_ptrace_features ();
490 /* We always want clone events. */
491 options
|= PTRACE_O_TRACECLONE
;
493 /* Filter out unsupported options. */
494 options
&= supported_ptrace_options
;
496 /* Set the options. */
497 ptrace (PTRACE_SETOPTIONS
, pid
, (PTRACE_TYPE_ARG3
) 0,
498 (PTRACE_TYPE_ARG4
) (uintptr_t) options
);
501 /* Disable reporting of all currently supported ptrace events. */
504 linux_disable_event_reporting (pid_t pid
)
506 /* Set the options. */
507 ptrace (PTRACE_SETOPTIONS
, pid
, (PTRACE_TYPE_ARG3
) 0, 0);
510 /* Returns non-zero if PTRACE_OPTIONS is contained within
511 SUPPORTED_PTRACE_OPTIONS, therefore supported. Returns 0
515 ptrace_supports_feature (int ptrace_options
)
517 if (supported_ptrace_options
== -1)
518 linux_check_ptrace_features ();
520 return ((supported_ptrace_options
& ptrace_options
) == ptrace_options
);
523 /* Returns non-zero if PTRACE_EVENT_FORK is supported by ptrace,
524 0 otherwise. Note that if PTRACE_EVENT_FORK is supported so is
525 PTRACE_EVENT_CLONE, PTRACE_EVENT_EXEC and PTRACE_EVENT_VFORK,
526 since they were all added to the kernel at the same time. */
529 linux_supports_tracefork (void)
531 return ptrace_supports_feature (PTRACE_O_TRACEFORK
);
534 /* Returns non-zero if PTRACE_EVENT_EXEC is supported by ptrace,
535 0 otherwise. Note that if PTRACE_EVENT_FORK is supported so is
536 PTRACE_EVENT_CLONE, PTRACE_EVENT_FORK and PTRACE_EVENT_VFORK,
537 since they were all added to the kernel at the same time. */
540 linux_supports_traceexec (void)
542 return ptrace_supports_feature (PTRACE_O_TRACEEXEC
);
545 /* Returns non-zero if PTRACE_EVENT_CLONE is supported by ptrace,
546 0 otherwise. Note that if PTRACE_EVENT_CLONE is supported so is
547 PTRACE_EVENT_FORK, PTRACE_EVENT_EXEC and PTRACE_EVENT_VFORK,
548 since they were all added to the kernel at the same time. */
551 linux_supports_traceclone (void)
553 return ptrace_supports_feature (PTRACE_O_TRACECLONE
);
556 /* Returns non-zero if PTRACE_O_TRACEVFORKDONE is supported by
557 ptrace, 0 otherwise. */
560 linux_supports_tracevforkdone (void)
562 return ptrace_supports_feature (PTRACE_O_TRACEVFORKDONE
);
565 /* Returns non-zero if PTRACE_O_TRACESYSGOOD is supported by ptrace,
569 linux_supports_tracesysgood (void)
571 return ptrace_supports_feature (PTRACE_O_TRACESYSGOOD
);
574 /* Display possible problems on this system. Display them only once per GDB
578 linux_ptrace_init_warnings (void)
580 static int warned
= 0;
586 linux_ptrace_test_ret_to_nx ();
589 /* Extract extended ptrace event from wait status. */
592 linux_ptrace_get_extended_event (int wstat
)
594 return (wstat
>> 16);
597 /* Determine whether wait status denotes an extended event. */
600 linux_is_extended_waitstatus (int wstat
)
602 return (linux_ptrace_get_extended_event (wstat
) != 0);
605 /* Return true if the event in LP may be caused by breakpoint. */
608 linux_wstatus_maybe_breakpoint (int wstat
)
610 return (WIFSTOPPED (wstat
)
611 && (WSTOPSIG (wstat
) == SIGTRAP
612 /* SIGILL and SIGSEGV are also treated as traps in case a
613 breakpoint is inserted at the current PC. */
614 || WSTOPSIG (wstat
) == SIGILL
615 || WSTOPSIG (wstat
) == SIGSEGV
));