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