| 1 | /* GNU/Linux native-dependent code common to multiple platforms. |
| 2 | Copyright (C) 2003 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 2 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, write to the Free Software |
| 18 | Foundation, Inc., 59 Temple Place - Suite 330, |
| 19 | Boston, MA 02111-1307, USA. */ |
| 20 | |
| 21 | #include "defs.h" |
| 22 | #include "inferior.h" |
| 23 | #include "target.h" |
| 24 | |
| 25 | #include "gdb_wait.h" |
| 26 | #include <sys/ptrace.h> |
| 27 | |
| 28 | #include "linux-nat.h" |
| 29 | |
| 30 | /* If the system headers did not provide the constants, hard-code the normal |
| 31 | values. */ |
| 32 | #ifndef PTRACE_EVENT_FORK |
| 33 | |
| 34 | #define PTRACE_SETOPTIONS 0x4200 |
| 35 | #define PTRACE_GETEVENTMSG 0x4201 |
| 36 | |
| 37 | /* options set using PTRACE_SETOPTIONS */ |
| 38 | #define PTRACE_O_TRACESYSGOOD 0x00000001 |
| 39 | #define PTRACE_O_TRACEFORK 0x00000002 |
| 40 | #define PTRACE_O_TRACEVFORK 0x00000004 |
| 41 | #define PTRACE_O_TRACECLONE 0x00000008 |
| 42 | #define PTRACE_O_TRACEEXEC 0x00000010 |
| 43 | #define PTRACE_O_TRACEVFORKDONE 0x00000020 |
| 44 | #define PTRACE_O_TRACEEXIT 0x00000040 |
| 45 | |
| 46 | /* Wait extended result codes for the above trace options. */ |
| 47 | #define PTRACE_EVENT_FORK 1 |
| 48 | #define PTRACE_EVENT_VFORK 2 |
| 49 | #define PTRACE_EVENT_CLONE 3 |
| 50 | #define PTRACE_EVENT_EXEC 4 |
| 51 | #define PTRACE_EVENT_VFORKDONE 5 |
| 52 | #define PTRACE_EVENT_EXIT 6 |
| 53 | |
| 54 | #endif /* PTRACE_EVENT_FORK */ |
| 55 | |
| 56 | /* We can't always assume that this flag is available, but all systems |
| 57 | with the ptrace event handlers also have __WALL, so it's safe to use |
| 58 | here. */ |
| 59 | #ifndef __WALL |
| 60 | #define __WALL 0x40000000 /* Wait for any child. */ |
| 61 | #endif |
| 62 | |
| 63 | extern struct target_ops child_ops; |
| 64 | |
| 65 | static int linux_parent_pid; |
| 66 | |
| 67 | struct simple_pid_list |
| 68 | { |
| 69 | int pid; |
| 70 | struct simple_pid_list *next; |
| 71 | }; |
| 72 | struct simple_pid_list *stopped_pids; |
| 73 | |
| 74 | /* This variable is a tri-state flag: -1 for unknown, 0 if PTRACE_O_TRACEFORK |
| 75 | can not be used, 1 if it can. */ |
| 76 | |
| 77 | static int linux_supports_tracefork_flag = -1; |
| 78 | |
| 79 | /* If we have PTRACE_O_TRACEFORK, this flag indicates whether we also have |
| 80 | PTRACE_O_TRACEVFORKDONE. */ |
| 81 | |
| 82 | static int linux_supports_tracevforkdone_flag = -1; |
| 83 | |
| 84 | \f |
| 85 | /* Trivial list manipulation functions to keep track of a list of |
| 86 | new stopped processes. */ |
| 87 | static void |
| 88 | add_to_pid_list (struct simple_pid_list **listp, int pid) |
| 89 | { |
| 90 | struct simple_pid_list *new_pid = xmalloc (sizeof (struct simple_pid_list)); |
| 91 | new_pid->pid = pid; |
| 92 | new_pid->next = *listp; |
| 93 | *listp = new_pid; |
| 94 | } |
| 95 | |
| 96 | static int |
| 97 | pull_pid_from_list (struct simple_pid_list **listp, int pid) |
| 98 | { |
| 99 | struct simple_pid_list **p; |
| 100 | |
| 101 | for (p = listp; *p != NULL; p = &(*p)->next) |
| 102 | if ((*p)->pid == pid) |
| 103 | { |
| 104 | struct simple_pid_list *next = (*p)->next; |
| 105 | xfree (*p); |
| 106 | *p = next; |
| 107 | return 1; |
| 108 | } |
| 109 | return 0; |
| 110 | } |
| 111 | |
| 112 | void |
| 113 | linux_record_stopped_pid (int pid) |
| 114 | { |
| 115 | add_to_pid_list (&stopped_pids, pid); |
| 116 | } |
| 117 | |
| 118 | \f |
| 119 | /* A helper function for linux_test_for_tracefork, called after fork (). */ |
| 120 | |
| 121 | static void |
| 122 | linux_tracefork_child (void) |
| 123 | { |
| 124 | int ret; |
| 125 | |
| 126 | ptrace (PTRACE_TRACEME, 0, 0, 0); |
| 127 | kill (getpid (), SIGSTOP); |
| 128 | fork (); |
| 129 | exit (0); |
| 130 | } |
| 131 | |
| 132 | /* Determine if PTRACE_O_TRACEFORK can be used to follow fork events. We |
| 133 | create a child process, attach to it, use PTRACE_SETOPTIONS to enable |
| 134 | fork tracing, and let it fork. If the process exits, we assume that |
| 135 | we can't use TRACEFORK; if we get the fork notification, and we can |
| 136 | extract the new child's PID, then we assume that we can. */ |
| 137 | |
| 138 | static void |
| 139 | linux_test_for_tracefork (void) |
| 140 | { |
| 141 | int child_pid, ret, status; |
| 142 | long second_pid; |
| 143 | |
| 144 | child_pid = fork (); |
| 145 | if (child_pid == -1) |
| 146 | perror_with_name ("linux_test_for_tracefork: fork"); |
| 147 | |
| 148 | if (child_pid == 0) |
| 149 | linux_tracefork_child (); |
| 150 | |
| 151 | ret = waitpid (child_pid, &status, 0); |
| 152 | if (ret == -1) |
| 153 | perror_with_name ("linux_test_for_tracefork: waitpid"); |
| 154 | else if (ret != child_pid) |
| 155 | error ("linux_test_for_tracefork: waitpid: unexpected result %d.", ret); |
| 156 | if (! WIFSTOPPED (status)) |
| 157 | error ("linux_test_for_tracefork: waitpid: unexpected status %d.", status); |
| 158 | |
| 159 | linux_supports_tracefork_flag = 0; |
| 160 | |
| 161 | ret = ptrace (PTRACE_SETOPTIONS, child_pid, 0, PTRACE_O_TRACEFORK); |
| 162 | if (ret != 0) |
| 163 | { |
| 164 | ptrace (PTRACE_KILL, child_pid, 0, 0); |
| 165 | waitpid (child_pid, &status, 0); |
| 166 | return; |
| 167 | } |
| 168 | |
| 169 | /* Check whether PTRACE_O_TRACEVFORKDONE is available. */ |
| 170 | ret = ptrace (PTRACE_SETOPTIONS, child_pid, 0, |
| 171 | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORKDONE); |
| 172 | linux_supports_tracevforkdone_flag = (ret == 0); |
| 173 | |
| 174 | ptrace (PTRACE_CONT, child_pid, 0, 0); |
| 175 | ret = waitpid (child_pid, &status, 0); |
| 176 | if (ret == child_pid && WIFSTOPPED (status) |
| 177 | && status >> 16 == PTRACE_EVENT_FORK) |
| 178 | { |
| 179 | second_pid = 0; |
| 180 | ret = ptrace (PTRACE_GETEVENTMSG, child_pid, 0, &second_pid); |
| 181 | if (ret == 0 && second_pid != 0) |
| 182 | { |
| 183 | int second_status; |
| 184 | |
| 185 | linux_supports_tracefork_flag = 1; |
| 186 | waitpid (second_pid, &second_status, 0); |
| 187 | ptrace (PTRACE_DETACH, second_pid, 0, 0); |
| 188 | } |
| 189 | } |
| 190 | |
| 191 | if (WIFSTOPPED (status)) |
| 192 | { |
| 193 | ptrace (PTRACE_DETACH, child_pid, 0, 0); |
| 194 | waitpid (child_pid, &status, 0); |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | /* Return non-zero iff we have tracefork functionality available. |
| 199 | This function also sets linux_supports_tracefork_flag. */ |
| 200 | |
| 201 | static int |
| 202 | linux_supports_tracefork (void) |
| 203 | { |
| 204 | if (linux_supports_tracefork_flag == -1) |
| 205 | linux_test_for_tracefork (); |
| 206 | return linux_supports_tracefork_flag; |
| 207 | } |
| 208 | |
| 209 | static int |
| 210 | linux_supports_tracevforkdone (void) |
| 211 | { |
| 212 | if (linux_supports_tracefork_flag == -1) |
| 213 | linux_test_for_tracefork (); |
| 214 | return linux_supports_tracevforkdone_flag; |
| 215 | } |
| 216 | |
| 217 | \f |
| 218 | void |
| 219 | linux_enable_event_reporting (ptid_t ptid) |
| 220 | { |
| 221 | int pid = ptid_get_pid (ptid); |
| 222 | int options; |
| 223 | |
| 224 | if (! linux_supports_tracefork ()) |
| 225 | return; |
| 226 | |
| 227 | options = PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACEEXEC; |
| 228 | if (linux_supports_tracevforkdone ()) |
| 229 | options |= PTRACE_O_TRACEVFORKDONE; |
| 230 | |
| 231 | /* Do not enable PTRACE_O_TRACEEXIT until GDB is more prepared to support |
| 232 | read-only process state. */ |
| 233 | |
| 234 | ptrace (PTRACE_SETOPTIONS, pid, 0, options); |
| 235 | } |
| 236 | |
| 237 | void |
| 238 | child_post_attach (int pid) |
| 239 | { |
| 240 | linux_enable_event_reporting (pid_to_ptid (pid)); |
| 241 | } |
| 242 | |
| 243 | void |
| 244 | linux_child_post_startup_inferior (ptid_t ptid) |
| 245 | { |
| 246 | linux_enable_event_reporting (ptid); |
| 247 | } |
| 248 | |
| 249 | #ifndef LINUX_CHILD_POST_STARTUP_INFERIOR |
| 250 | void |
| 251 | child_post_startup_inferior (ptid_t ptid) |
| 252 | { |
| 253 | linux_child_post_startup_inferior (ptid); |
| 254 | } |
| 255 | #endif |
| 256 | |
| 257 | int |
| 258 | child_follow_fork (int follow_child) |
| 259 | { |
| 260 | ptid_t last_ptid; |
| 261 | struct target_waitstatus last_status; |
| 262 | int has_vforked; |
| 263 | int parent_pid, child_pid; |
| 264 | |
| 265 | get_last_target_status (&last_ptid, &last_status); |
| 266 | has_vforked = (last_status.kind == TARGET_WAITKIND_VFORKED); |
| 267 | parent_pid = ptid_get_pid (last_ptid); |
| 268 | child_pid = last_status.value.related_pid; |
| 269 | |
| 270 | if (! follow_child) |
| 271 | { |
| 272 | /* We're already attached to the parent, by default. */ |
| 273 | |
| 274 | /* Before detaching from the child, remove all breakpoints from |
| 275 | it. (This won't actually modify the breakpoint list, but will |
| 276 | physically remove the breakpoints from the child.) */ |
| 277 | /* If we vforked this will remove the breakpoints from the parent |
| 278 | also, but they'll be reinserted below. */ |
| 279 | detach_breakpoints (child_pid); |
| 280 | |
| 281 | fprintf_filtered (gdb_stdout, |
| 282 | "Detaching after fork from child process %d.\n", |
| 283 | child_pid); |
| 284 | |
| 285 | ptrace (PTRACE_DETACH, child_pid, 0, 0); |
| 286 | |
| 287 | if (has_vforked) |
| 288 | { |
| 289 | if (linux_supports_tracevforkdone ()) |
| 290 | { |
| 291 | int status; |
| 292 | |
| 293 | ptrace (PTRACE_CONT, parent_pid, 0, 0); |
| 294 | waitpid (parent_pid, &status, __WALL); |
| 295 | if ((status >> 16) != PTRACE_EVENT_VFORKDONE) |
| 296 | warning ("Unexpected waitpid result %06x when waiting for " |
| 297 | "vfork-done", status); |
| 298 | } |
| 299 | else |
| 300 | { |
| 301 | /* We can't insert breakpoints until the child has |
| 302 | finished with the shared memory region. We need to |
| 303 | wait until that happens. Ideal would be to just |
| 304 | call: |
| 305 | - ptrace (PTRACE_SYSCALL, parent_pid, 0, 0); |
| 306 | - waitpid (parent_pid, &status, __WALL); |
| 307 | However, most architectures can't handle a syscall |
| 308 | being traced on the way out if it wasn't traced on |
| 309 | the way in. |
| 310 | |
| 311 | We might also think to loop, continuing the child |
| 312 | until it exits or gets a SIGTRAP. One problem is |
| 313 | that the child might call ptrace with PTRACE_TRACEME. |
| 314 | |
| 315 | There's no simple and reliable way to figure out when |
| 316 | the vforked child will be done with its copy of the |
| 317 | shared memory. We could step it out of the syscall, |
| 318 | two instructions, let it go, and then single-step the |
| 319 | parent once. When we have hardware single-step, this |
| 320 | would work; with software single-step it could still |
| 321 | be made to work but we'd have to be able to insert |
| 322 | single-step breakpoints in the child, and we'd have |
| 323 | to insert -just- the single-step breakpoint in the |
| 324 | parent. Very awkward. |
| 325 | |
| 326 | In the end, the best we can do is to make sure it |
| 327 | runs for a little while. Hopefully it will be out of |
| 328 | range of any breakpoints we reinsert. Usually this |
| 329 | is only the single-step breakpoint at vfork's return |
| 330 | point. */ |
| 331 | |
| 332 | usleep (10000); |
| 333 | } |
| 334 | |
| 335 | /* Since we vforked, breakpoints were removed in the parent |
| 336 | too. Put them back. */ |
| 337 | reattach_breakpoints (parent_pid); |
| 338 | } |
| 339 | } |
| 340 | else |
| 341 | { |
| 342 | char child_pid_spelling[40]; |
| 343 | |
| 344 | /* Needed to keep the breakpoint lists in sync. */ |
| 345 | if (! has_vforked) |
| 346 | detach_breakpoints (child_pid); |
| 347 | |
| 348 | /* Before detaching from the parent, remove all breakpoints from it. */ |
| 349 | remove_breakpoints (); |
| 350 | |
| 351 | fprintf_filtered (gdb_stdout, |
| 352 | "Attaching after fork to child process %d.\n", |
| 353 | child_pid); |
| 354 | |
| 355 | /* If we're vforking, we may want to hold on to the parent until |
| 356 | the child exits or execs. At exec time we can remove the old |
| 357 | breakpoints from the parent and detach it; at exit time we |
| 358 | could do the same (or even, sneakily, resume debugging it - the |
| 359 | child's exec has failed, or something similar). |
| 360 | |
| 361 | This doesn't clean up "properly", because we can't call |
| 362 | target_detach, but that's OK; if the current target is "child", |
| 363 | then it doesn't need any further cleanups, and lin_lwp will |
| 364 | generally not encounter vfork (vfork is defined to fork |
| 365 | in libpthread.so). |
| 366 | |
| 367 | The holding part is very easy if we have VFORKDONE events; |
| 368 | but keeping track of both processes is beyond GDB at the |
| 369 | moment. So we don't expose the parent to the rest of GDB. |
| 370 | Instead we quietly hold onto it until such time as we can |
| 371 | safely resume it. */ |
| 372 | |
| 373 | if (has_vforked) |
| 374 | linux_parent_pid = parent_pid; |
| 375 | else |
| 376 | target_detach (NULL, 0); |
| 377 | |
| 378 | inferior_ptid = pid_to_ptid (child_pid); |
| 379 | push_target (&child_ops); |
| 380 | |
| 381 | /* Reset breakpoints in the child as appropriate. */ |
| 382 | follow_inferior_reset_breakpoints (); |
| 383 | } |
| 384 | |
| 385 | return 0; |
| 386 | } |
| 387 | |
| 388 | ptid_t |
| 389 | linux_handle_extended_wait (int pid, int status, |
| 390 | struct target_waitstatus *ourstatus) |
| 391 | { |
| 392 | int event = status >> 16; |
| 393 | |
| 394 | if (event == PTRACE_EVENT_CLONE) |
| 395 | internal_error (__FILE__, __LINE__, |
| 396 | "unexpected clone event"); |
| 397 | |
| 398 | if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_VFORK) |
| 399 | { |
| 400 | unsigned long new_pid; |
| 401 | int ret; |
| 402 | |
| 403 | ptrace (PTRACE_GETEVENTMSG, pid, 0, &new_pid); |
| 404 | |
| 405 | /* If we haven't already seen the new PID stop, wait for it now. */ |
| 406 | if (! pull_pid_from_list (&stopped_pids, new_pid)) |
| 407 | { |
| 408 | /* The new child has a pending SIGSTOP. We can't affect it until it |
| 409 | hits the SIGSTOP, but we're already attached. |
| 410 | |
| 411 | It won't be a clone (we didn't ask for clones in the event mask) |
| 412 | so we can just call waitpid and wait for the SIGSTOP. */ |
| 413 | do { |
| 414 | ret = waitpid (new_pid, &status, 0); |
| 415 | } while (ret == -1 && errno == EINTR); |
| 416 | if (ret == -1) |
| 417 | perror_with_name ("waiting for new child"); |
| 418 | else if (ret != new_pid) |
| 419 | internal_error (__FILE__, __LINE__, |
| 420 | "wait returned unexpected PID %d", ret); |
| 421 | else if (!WIFSTOPPED (status) || WSTOPSIG (status) != SIGSTOP) |
| 422 | internal_error (__FILE__, __LINE__, |
| 423 | "wait returned unexpected status 0x%x", status); |
| 424 | } |
| 425 | |
| 426 | ourstatus->kind = (event == PTRACE_EVENT_FORK) |
| 427 | ? TARGET_WAITKIND_FORKED : TARGET_WAITKIND_VFORKED; |
| 428 | ourstatus->value.related_pid = new_pid; |
| 429 | return inferior_ptid; |
| 430 | } |
| 431 | |
| 432 | if (event == PTRACE_EVENT_EXEC) |
| 433 | { |
| 434 | ourstatus->kind = TARGET_WAITKIND_EXECD; |
| 435 | ourstatus->value.execd_pathname |
| 436 | = xstrdup (child_pid_to_exec_file (pid)); |
| 437 | |
| 438 | if (linux_parent_pid) |
| 439 | { |
| 440 | detach_breakpoints (linux_parent_pid); |
| 441 | ptrace (PTRACE_DETACH, linux_parent_pid, 0, 0); |
| 442 | |
| 443 | linux_parent_pid = 0; |
| 444 | } |
| 445 | |
| 446 | return inferior_ptid; |
| 447 | } |
| 448 | |
| 449 | internal_error (__FILE__, __LINE__, |
| 450 | "unknown ptrace event %d", event); |
| 451 | } |
| 452 | |
| 453 | \f |
| 454 | int |
| 455 | child_insert_fork_catchpoint (int pid) |
| 456 | { |
| 457 | if (! linux_supports_tracefork ()) |
| 458 | error ("Your system does not support fork catchpoints."); |
| 459 | |
| 460 | return 0; |
| 461 | } |
| 462 | |
| 463 | int |
| 464 | child_insert_vfork_catchpoint (int pid) |
| 465 | { |
| 466 | if (!linux_supports_tracefork ()) |
| 467 | error ("Your system does not support vfork catchpoints."); |
| 468 | |
| 469 | return 0; |
| 470 | } |
| 471 | |
| 472 | int |
| 473 | child_insert_exec_catchpoint (int pid) |
| 474 | { |
| 475 | if (!linux_supports_tracefork ()) |
| 476 | error ("Your system does not support exec catchpoints."); |
| 477 | |
| 478 | return 0; |
| 479 | } |
| 480 | |
| 481 | void |
| 482 | kill_inferior (void) |
| 483 | { |
| 484 | int status; |
| 485 | int pid = PIDGET (inferior_ptid); |
| 486 | struct target_waitstatus last; |
| 487 | ptid_t last_ptid; |
| 488 | int ret; |
| 489 | |
| 490 | if (pid == 0) |
| 491 | return; |
| 492 | |
| 493 | /* If we're stopped while forking and we haven't followed yet, kill the |
| 494 | other task. We need to do this first because the parent will be |
| 495 | sleeping if this is a vfork. */ |
| 496 | |
| 497 | get_last_target_status (&last_ptid, &last); |
| 498 | |
| 499 | if (last.kind == TARGET_WAITKIND_FORKED |
| 500 | || last.kind == TARGET_WAITKIND_VFORKED) |
| 501 | { |
| 502 | ptrace (PT_KILL, last.value.related_pid); |
| 503 | ptrace_wait (null_ptid, &status); |
| 504 | } |
| 505 | |
| 506 | /* Kill the current process. */ |
| 507 | ptrace (PT_KILL, pid, (PTRACE_ARG3_TYPE) 0, 0); |
| 508 | ret = ptrace_wait (null_ptid, &status); |
| 509 | |
| 510 | /* We might get a SIGCHLD instead of an exit status. This is |
| 511 | aggravated by the first kill above - a child has just died. */ |
| 512 | |
| 513 | while (ret == pid && WIFSTOPPED (status)) |
| 514 | { |
| 515 | ptrace (PT_KILL, pid, (PTRACE_ARG3_TYPE) 0, 0); |
| 516 | ret = ptrace_wait (null_ptid, &status); |
| 517 | } |
| 518 | |
| 519 | target_mourn_inferior (); |
| 520 | } |