1 /* Linux-specific ptrace manipulation routines.
2 Copyright (C) 2012-2014 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/>. */
25 #include "linux-ptrace.h"
26 #include "linux-procfs.h"
27 #include "linux-waitpid.h"
33 /* Stores the currently supported ptrace options. A value of
34 -1 means we did not check for features yet. A value of 0 means
35 there are no supported features. */
36 static int current_ptrace_options
= -1;
38 /* Additional flags to test. */
40 static int additional_flags
;
42 /* Find all possible reasons we could fail to attach PID and append
43 these as strings to the already initialized BUFFER. '\0'
44 termination of BUFFER must be done by the caller. */
47 linux_ptrace_attach_fail_reason (pid_t pid
, struct buffer
*buffer
)
51 tracerpid
= linux_proc_get_tracerpid (pid
);
53 buffer_xml_printf (buffer
, _("process %d is already traced "
55 (int) pid
, (int) tracerpid
);
57 if (linux_proc_pid_is_zombie (pid
))
58 buffer_xml_printf (buffer
, _("process %d is a zombie "
59 "- the process has already terminated"),
63 #if defined __i386__ || defined __x86_64__
65 /* Address of the 'ret' instruction in asm code block below. */
66 extern void (linux_ptrace_test_ret_to_nx_instr
) (void);
72 #endif /* defined __i386__ || defined __x86_64__ */
74 /* Test broken off-trunk Linux kernel patchset for NX support on i386. It was
75 removed in Fedora kernel 88fa1f0332d188795ed73d7ac2b1564e11a0b4cd.
77 Test also x86_64 arch for PaX support. */
80 linux_ptrace_test_ret_to_nx (void)
82 #if defined __i386__ || defined __x86_64__
84 gdb_byte
*return_address
, *pc
;
86 int status
, kill_status
;
88 return_address
= mmap (NULL
, 2, PROT_READ
| PROT_WRITE
,
89 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
90 if (return_address
== MAP_FAILED
)
92 warning (_("linux_ptrace_test_ret_to_nx: Cannot mmap: %s"),
97 /* Put there 'int3'. */
98 *return_address
= 0xcc;
104 warning (_("linux_ptrace_test_ret_to_nx: Cannot fork: %s"),
109 l
= ptrace (PTRACE_TRACEME
, 0, (PTRACE_TYPE_ARG3
) NULL
,
110 (PTRACE_TYPE_ARG4
) NULL
);
112 warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_TRACEME: %s"),
117 asm volatile ("pushl %0;"
118 ".globl linux_ptrace_test_ret_to_nx_instr;"
119 "linux_ptrace_test_ret_to_nx_instr:"
121 : : "r" (return_address
) : "%esp", "memory");
122 #elif defined __x86_64__
123 asm volatile ("pushq %0;"
124 ".globl linux_ptrace_test_ret_to_nx_instr;"
125 "linux_ptrace_test_ret_to_nx_instr:"
127 : : "r" ((uint64_t) (uintptr_t) return_address
)
130 # error "!__i386__ && !__x86_64__"
132 gdb_assert_not_reached ("asm block did not terminate");
139 got_pid
= waitpid (child
, &status
, 0);
140 if (got_pid
!= child
)
142 warning (_("linux_ptrace_test_ret_to_nx: waitpid returned %ld: %s"),
143 (long) got_pid
, strerror (errno
));
147 if (WIFSIGNALED (status
))
149 if (WTERMSIG (status
) != SIGKILL
)
150 warning (_("linux_ptrace_test_ret_to_nx: WTERMSIG %d is not SIGKILL!"),
151 (int) WTERMSIG (status
));
153 warning (_("Cannot call inferior functions, Linux kernel PaX "
154 "protection forbids return to non-executable pages!"));
158 if (!WIFSTOPPED (status
))
160 warning (_("linux_ptrace_test_ret_to_nx: status %d is not WIFSTOPPED!"),
165 /* We may get SIGSEGV due to missing PROT_EXEC of the return_address. */
166 if (WSTOPSIG (status
) != SIGTRAP
&& WSTOPSIG (status
) != SIGSEGV
)
168 warning (_("linux_ptrace_test_ret_to_nx: "
169 "WSTOPSIG %d is neither SIGTRAP nor SIGSEGV!"),
170 (int) WSTOPSIG (status
));
176 l
= ptrace (PTRACE_PEEKUSER
, child
, (PTRACE_TYPE_ARG3
) (uintptr_t) (EIP
* 4),
177 (PTRACE_TYPE_ARG4
) NULL
);
178 #elif defined __x86_64__
179 l
= ptrace (PTRACE_PEEKUSER
, child
, (PTRACE_TYPE_ARG3
) (uintptr_t) (RIP
* 8),
180 (PTRACE_TYPE_ARG4
) NULL
);
182 # error "!__i386__ && !__x86_64__"
186 warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_PEEKUSER: %s"),
190 pc
= (void *) (uintptr_t) l
;
192 kill (child
, SIGKILL
);
193 ptrace (PTRACE_KILL
, child
, (PTRACE_TYPE_ARG3
) NULL
,
194 (PTRACE_TYPE_ARG4
) NULL
);
197 got_pid
= waitpid (child
, &kill_status
, 0);
198 if (got_pid
!= child
)
200 warning (_("linux_ptrace_test_ret_to_nx: "
201 "PTRACE_KILL waitpid returned %ld: %s"),
202 (long) got_pid
, strerror (errno
));
205 if (!WIFSIGNALED (kill_status
))
207 warning (_("linux_ptrace_test_ret_to_nx: "
208 "PTRACE_KILL status %d is not WIFSIGNALED!"),
213 /* + 1 is there as x86* stops after the 'int3' instruction. */
214 if (WSTOPSIG (status
) == SIGTRAP
&& pc
== return_address
+ 1)
220 /* We may get SIGSEGV due to missing PROT_EXEC of the RETURN_ADDRESS page. */
221 if (WSTOPSIG (status
) == SIGSEGV
&& pc
== return_address
)
227 if ((void (*) (void)) pc
!= &linux_ptrace_test_ret_to_nx_instr
)
228 warning (_("linux_ptrace_test_ret_to_nx: PC %p is neither near return "
229 "address %p nor is the return instruction %p!"),
230 pc
, return_address
, &linux_ptrace_test_ret_to_nx_instr
);
232 warning (_("Cannot call inferior functions on this system - "
233 "Linux kernel with broken i386 NX (non-executable pages) "
234 "support detected!"));
235 #endif /* defined __i386__ || defined __x86_64__ */
238 /* Helper function to fork a process and make the child process call
239 the function FUNCTION, passing CHILD_STACK as parameter.
241 For MMU-less targets, clone is used instead of fork, and
242 CHILD_STACK is used as stack space for the cloned child. If NULL,
243 stack space is allocated via malloc (and subsequently passed to
244 FUNCTION). For MMU targets, CHILD_STACK is ignored. */
247 linux_fork_to_function (gdb_byte
*child_stack
, void (*function
) (gdb_byte
*))
251 /* Sanity check the function pointer. */
252 gdb_assert (function
!= NULL
);
254 #if defined(__UCLIBC__) && defined(HAS_NOMMU)
255 #define STACK_SIZE 4096
257 if (child_stack
== NULL
)
258 child_stack
= xmalloc (STACK_SIZE
* 4);
260 /* Use CLONE_VM instead of fork, to support uClinux (no MMU). */
262 child_pid
= __clone2 (function
, child_stack
, STACK_SIZE
,
263 CLONE_VM
| SIGCHLD
, child_stack
+ STACK_SIZE
* 2);
264 #else /* !__ia64__ */
265 child_pid
= clone (function
, child_stack
+ STACK_SIZE
,
266 CLONE_VM
| SIGCHLD
, child_stack
+ STACK_SIZE
* 2);
267 #endif /* !__ia64__ */
268 #else /* !defined(__UCLIBC) && defined(HAS_NOMMU) */
273 #endif /* defined(__UCLIBC) && defined(HAS_NOMMU) */
276 perror_with_name (("fork"));
281 /* A helper function for linux_check_ptrace_features, called after
282 the child forks a grandchild. */
285 linux_grandchild_function (gdb_byte
*child_stack
)
287 /* Free any allocated stack. */
290 /* This code is only reacheable by the grandchild (child's child)
295 /* A helper function for linux_check_ptrace_features, called after
296 the parent process forks a child. The child allows itself to
297 be traced by its parent. */
300 linux_child_function (gdb_byte
*child_stack
)
302 ptrace (PTRACE_TRACEME
, 0, (PTRACE_TYPE_ARG3
) 0, (PTRACE_TYPE_ARG4
) 0);
303 kill (getpid (), SIGSTOP
);
305 /* Fork a grandchild. */
306 linux_fork_to_function (child_stack
, linux_grandchild_function
);
308 /* This code is only reacheable by the child (grandchild's parent)
313 static void linux_test_for_tracesysgood (int child_pid
);
314 static void linux_test_for_tracefork (int child_pid
);
316 /* Determine ptrace features available on this target. */
319 linux_check_ptrace_features (void)
321 int child_pid
, ret
, status
;
323 /* Initialize the options. */
324 current_ptrace_options
= 0;
326 /* Fork a child so we can do some testing. The child will call
327 linux_child_function and will get traced. The child will
328 eventually fork a grandchild so we can test fork event
330 child_pid
= linux_fork_to_function (NULL
, linux_child_function
);
332 ret
= my_waitpid (child_pid
, &status
, 0);
334 perror_with_name (("waitpid"));
335 else if (ret
!= child_pid
)
336 error (_("linux_check_ptrace_features: waitpid: unexpected result %d."),
338 if (! WIFSTOPPED (status
))
339 error (_("linux_check_ptrace_features: waitpid: unexpected status %d."),
342 linux_test_for_tracesysgood (child_pid
);
344 linux_test_for_tracefork (child_pid
);
346 /* Clean things up and kill any pending children. */
349 ret
= ptrace (PTRACE_KILL
, child_pid
, (PTRACE_TYPE_ARG3
) 0,
350 (PTRACE_TYPE_ARG4
) 0);
352 warning (_("linux_check_ptrace_features: failed to kill child"));
353 my_waitpid (child_pid
, &status
, 0);
355 while (WIFSTOPPED (status
));
358 /* Determine if PTRACE_O_TRACESYSGOOD can be used to catch
362 linux_test_for_tracesysgood (int child_pid
)
366 if ((additional_flags
& PTRACE_O_TRACESYSGOOD
) == 0)
369 ret
= ptrace (PTRACE_SETOPTIONS
, child_pid
, (PTRACE_TYPE_ARG3
) 0,
370 (PTRACE_TYPE_ARG4
) PTRACE_O_TRACESYSGOOD
);
373 current_ptrace_options
|= PTRACE_O_TRACESYSGOOD
;
376 /* Determine if PTRACE_O_TRACEFORK can be used to follow fork
380 linux_test_for_tracefork (int child_pid
)
385 /* First, set the PTRACE_O_TRACEFORK option. If this fails, we
386 know for sure that it is not supported. */
387 ret
= ptrace (PTRACE_SETOPTIONS
, child_pid
, (PTRACE_TYPE_ARG3
) 0,
388 (PTRACE_TYPE_ARG4
) PTRACE_O_TRACEFORK
);
393 if ((additional_flags
& PTRACE_O_TRACEVFORKDONE
) != 0)
395 /* Check if the target supports PTRACE_O_TRACEVFORKDONE. */
396 ret
= ptrace (PTRACE_SETOPTIONS
, child_pid
, (PTRACE_TYPE_ARG3
) 0,
397 (PTRACE_TYPE_ARG4
) (PTRACE_O_TRACEFORK
398 | PTRACE_O_TRACEVFORKDONE
));
400 current_ptrace_options
|= PTRACE_O_TRACEVFORKDONE
;
403 /* Setting PTRACE_O_TRACEFORK did not cause an error, however we
404 don't know for sure that the feature is available; old
405 versions of PTRACE_SETOPTIONS ignored unknown options.
406 Therefore, we attach to the child process, use PTRACE_SETOPTIONS
407 to enable fork tracing, and let it fork. If the process exits,
408 we assume that we can't use PTRACE_O_TRACEFORK; if we get the
409 fork notification, and we can extract the new child's PID, then
410 we assume that we can.
412 We do not explicitly check for vfork tracing here. It is
413 assumed that vfork tracing is available whenever fork tracing
415 ret
= ptrace (PTRACE_CONT
, child_pid
, (PTRACE_TYPE_ARG3
) 0,
416 (PTRACE_TYPE_ARG4
) 0);
418 warning (_("linux_test_for_tracefork: failed to resume child"));
420 ret
= my_waitpid (child_pid
, &status
, 0);
422 /* Check if we received a fork event notification. */
423 if (ret
== child_pid
&& WIFSTOPPED (status
)
424 && status
>> 16 == PTRACE_EVENT_FORK
)
426 /* We did receive a fork event notification. Make sure its PID
429 ret
= ptrace (PTRACE_GETEVENTMSG
, child_pid
, (PTRACE_TYPE_ARG3
) 0,
430 (PTRACE_TYPE_ARG4
) &second_pid
);
431 if (ret
== 0 && second_pid
!= 0)
435 /* We got the PID from the grandchild, which means fork
436 tracing is supported. */
437 current_ptrace_options
|= PTRACE_O_TRACECLONE
;
438 current_ptrace_options
|= (additional_flags
& (PTRACE_O_TRACEFORK
439 | PTRACE_O_TRACEVFORK
440 | PTRACE_O_TRACEEXEC
));
442 /* Do some cleanup and kill the grandchild. */
443 my_waitpid (second_pid
, &second_status
, 0);
444 ret
= ptrace (PTRACE_KILL
, second_pid
, (PTRACE_TYPE_ARG3
) 0,
445 (PTRACE_TYPE_ARG4
) 0);
447 warning (_("linux_test_for_tracefork: "
448 "failed to kill second child"));
449 my_waitpid (second_pid
, &status
, 0);
453 warning (_("linux_test_for_tracefork: unexpected result from waitpid "
454 "(%d, status 0x%x)"), ret
, status
);
457 /* Enable reporting of all currently supported ptrace events. */
460 linux_enable_event_reporting (pid_t pid
)
462 /* Check if we have initialized the ptrace features for this
463 target. If not, do it now. */
464 if (current_ptrace_options
== -1)
465 linux_check_ptrace_features ();
467 /* Set the options. */
468 ptrace (PTRACE_SETOPTIONS
, pid
, (PTRACE_TYPE_ARG3
) 0,
469 (PTRACE_TYPE_ARG4
) (uintptr_t) current_ptrace_options
);
472 /* Disable reporting of all currently supported ptrace events. */
475 linux_disable_event_reporting (pid_t pid
)
477 /* Set the options. */
478 ptrace (PTRACE_SETOPTIONS
, pid
, (PTRACE_TYPE_ARG3
) 0, 0);
481 /* Returns non-zero if PTRACE_OPTIONS is contained within
482 CURRENT_PTRACE_OPTIONS, therefore supported. Returns 0
486 ptrace_supports_feature (int ptrace_options
)
488 gdb_assert (current_ptrace_options
>= 0);
490 return ((current_ptrace_options
& ptrace_options
) == ptrace_options
);
493 /* Returns non-zero if PTRACE_EVENT_FORK is supported by ptrace,
494 0 otherwise. Note that if PTRACE_EVENT_FORK is supported so is
495 PTRACE_EVENT_CLONE, PTRACE_EVENT_EXEC and PTRACE_EVENT_VFORK,
496 since they were all added to the kernel at the same time. */
499 linux_supports_tracefork (void)
501 return ptrace_supports_feature (PTRACE_O_TRACEFORK
);
504 /* Returns non-zero if PTRACE_EVENT_CLONE is supported by ptrace,
505 0 otherwise. Note that if PTRACE_EVENT_CLONE is supported so is
506 PTRACE_EVENT_FORK, PTRACE_EVENT_EXEC and PTRACE_EVENT_VFORK,
507 since they were all added to the kernel at the same time. */
510 linux_supports_traceclone (void)
512 return ptrace_supports_feature (PTRACE_O_TRACECLONE
);
515 /* Returns non-zero if PTRACE_O_TRACEVFORKDONE is supported by
516 ptrace, 0 otherwise. */
519 linux_supports_tracevforkdone (void)
521 return ptrace_supports_feature (PTRACE_O_TRACEVFORKDONE
);
524 /* Returns non-zero if PTRACE_O_TRACESYSGOOD is supported by ptrace,
528 linux_supports_tracesysgood (void)
530 return ptrace_supports_feature (PTRACE_O_TRACESYSGOOD
);
533 /* Display possible problems on this system. Display them only once per GDB
537 linux_ptrace_init_warnings (void)
539 static int warned
= 0;
545 linux_ptrace_test_ret_to_nx ();
548 /* Set additional ptrace flags to use. Some such flags may be checked
549 by the implementation above. This function must be called before
550 any other function in this file; otherwise the flags may not take
551 effect appropriately. */
554 linux_ptrace_set_additional_flags (int flags
)
556 additional_flags
= flags
;