1 /* Copyright 2007, Red Hat Inc. */
4 #define ps_prochandle attach_state_struct
12 #include <sys/ptrace.h>
13 #include <sys/types.h>
19 #include <linux/ptrace.h>
20 #include <asm/prctl.h>
21 #include <elfutils/libdwfl.h>
22 #include <thread_db.h>
28 /* Insert constant delay for before each critical check? */
30 #define USLEEP (1000000 / 2)
33 #if 1 /* Standard run. */
34 #define TIMEOUT_SECS 4
35 #define LOOPS_MIN 100000
37 /* LOOPS_MIN is a safety as QEMU clock time sucks.
38 100000 is 4s natively and 53s in QEMU. */
39 #define TIMEOUT_SECS 20
40 #define LOOPS_MIN 500000
44 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
56 static __attribute__((__noreturn__)) void crash (void)
64 fputs (">>> CRASH START\n", stderr);
66 count = backtrace (array, ARRAY_SIZE (array));
67 backtrace_symbols_fd (array, count, STDERR_FILENO);
69 snprintf (command, sizeof (command), "echo -e \"bt\\nquit\""
70 " >/tmp/debugger.%d; gdb --batch -nx --command=/tmp/debugger.%d"
71 " /proc/%d/exe %d </dev/null;rm -f /tmp/debugger.%d",
72 (int) getpid(), (int) getpid(), (int) getpid(), (int) getpid(),
75 fputs (">>> CRASH FINISH\n", stderr);
81 /* Separate the valid `1 << enum state' and `enum state' ranges. */
95 static const char *state_to_name (enum state state)
99 case STATE_INSTABLE: return "STATE_INSTABLE";
100 case STATE_ENOENT: return "STATE_ENOENT";
101 case STATE_SLEEPING: return "STATE_SLEEPING";
102 case STATE_RUNNING: return "STATE_RUNNING";
103 case STATE_STOPPED: return "STATE_STOPPED";
104 case STATE_PTRACED: return "STATE_PTRACED";
105 case STATE_ZOMBIE: return "STATE_ZOMBIE";
106 case STATE_DEAD: return "STATE_DEAD";
107 case STATE_DISK_SLEEP: return "STATE_DISK_SLEEP";
114 static enum state state_get (pid_t pid)
116 char status_name[32];
123 snprintf (status_name, sizeof (status_name), "/proc/%d/status", (int) pid);
124 f = fopen (status_name, "r");
125 if (f == NULL && errno == ENOENT)
126 found = STATE_ENOENT;
129 fprintf (stderr, "errno = %d\n", errno);
136 found = STATE_INSTABLE;
137 while (errno = 0, fgets (line, sizeof (line), f) != NULL)
139 const char *const string = "State:\t";
140 const size_t length = sizeof "State:\t" - 1;
142 if (strncmp (line, string, length) != 0)
144 if (strcmp (line + length, "S (sleeping)\n") == 0)
145 found = STATE_SLEEPING;
146 else if (strcmp (line + length, "R (running)\n") == 0)
147 found = STATE_RUNNING;
148 else if (strcmp (line + length, "T (stopped)\n") == 0)
149 found = STATE_STOPPED;
150 else if (strcmp (line + length, "T (tracing stop)\n") == 0)
151 found = STATE_PTRACED;
152 else if (strcmp (line + length, "Z (zombie)\n") == 0)
153 found = STATE_ZOMBIE;
154 /* FIXME: What does it mean? */
155 else if (strcmp (line + length, "X (dead)\n") == 0)
157 else if (strcmp (line + length, "D (disk sleep)\n") == 0)
158 found = STATE_DISK_SLEEP;
161 fprintf (stderr, "Found an unknown state: %s", line + length);
165 assert (found != STATE_INSTABLE || errno == ESRCH);
172 #define STATE(pid, expect_mask) state ((pid), (expect_mask), #expect_mask )
174 static enum state state (pid_t pid, unsigned expect_mask, const char *expect_mask_string)
177 time_t timeout = time (NULL) + TIMEOUT_SECS;
180 /* Sanity check `1 << enum state' was not misplaced with `enum state'. */
181 assert (1 << (STATE_FIRST + 1) >= STATE_LAST);
182 assert (expect_mask != 0);
183 #define MASK_UNDER_EXCLUSIVE(bit) ((1 << (bit)) - 1)
184 #define MASK_ABOVE_INCLUSIVE(bit) (~MASK_UNDER_EXCLUSIVE (bit))
185 assert ((expect_mask & MASK_UNDER_EXCLUSIVE (STATE_FIRST + 1)) == 0);
186 assert ((expect_mask & MASK_ABOVE_INCLUSIVE (STATE_LAST)) == 0);
187 #undef MASK_ABOVE_INCLUSIVE
188 #undef MASK_UNDER_EXCLUSIVE
192 found = state_get (pid);
194 if (((1 << found) & expect_mask) != 0)
197 while (loops++ < LOOPS_MIN || time (NULL) < timeout);
199 fprintf (stderr, "Found for PID %d state %s but expecting (%s)\n",
200 (int) pid, state_to_name (found), expect_mask_string);
204 struct attach_state_struct
209 td_thragent_t *thread_agent;
210 /* Debugging only: Number of signal needing redelivery on PTRACE_ATTACH. */
215 int attach_state_redelivered_get (struct attach_state_struct *attach_state)
217 assert (attach_state != NULL);
219 return attach_state->redelivered;
222 int attach_state_threads_count_get (struct attach_state_struct *attach_state)
224 assert (attach_state != NULL);
226 return attach_state->threads_count;
229 int attach_state_stopped_get (struct attach_state_struct *attach_state)
231 assert (attach_state != NULL);
233 return attach_state->stopped;
236 pid_t attach_state_pid_get (struct attach_state_struct *attach_state)
238 assert (attach_state != NULL);
240 return attach_state->pid;
243 struct attach_state_struct *attach_single (pid_t pid)
247 struct attach_state_struct *attach_state;
249 attach_state = malloc (sizeof (*attach_state));
250 assert (attach_state != NULL);
251 attach_state->pid = pid;
252 attach_state->dwfl = NULL;
253 attach_state->redelivered = 0;
254 attach_state->threads_count = -1;
258 attach_state->stopped = (STATE (pid, (1 << STATE_SLEEPING)
259 | (1 << STATE_RUNNING)
260 | (1 << STATE_STOPPED))
263 i = ptrace (PTRACE_ATTACH, pid, NULL, NULL);
266 /* FIXME: Why it does not work?
267 Disable also the STATE () call above. */
271 i = ptrace (PTRACE_CONT, pid, (void *) 1, (void *) SIGSTOP);
272 /* `STOPPED == 1' may be false, even if the process was not stopped. */
274 attach_state->stopped = 1;
275 else if (errno == ESRCH)
276 attach_state->stopped = 0;
285 i = waitpid (pid, &status, 0);
287 if (!WIFSTOPPED (status))
289 /* Process may have exited. */
290 fprintf (stderr, "PID %d waitpid(2) status %d\n", (int) pid,
294 if (WSTOPSIG (status) == SIGSTOP)
297 if (attach_state->redelivered == 0)
298 attach_state->redelivered = WSTOPSIG (status);
300 attach_state->redelivered = -1;
304 /* Re-deliver the signal received before SIGSTOP.
305 It happens with about only 1:200000 probability. */
306 i = ptrace (PTRACE_CONT, pid, (void *) 1,
307 (void *) (unsigned long) WSTOPSIG (status));
314 void detach_single (struct attach_state_struct *attach_state)
320 i = ptrace (PTRACE_DETACH, attach_state->pid, NULL,
321 (void *) (unsigned long) (attach_state->stopped ? SIGSTOP : 0));
327 static Dwfl *get_dwfl (struct ps_prochandle *proc_handle)
329 static char *debuginfo_path;
331 static const Dwfl_Callbacks proc_callbacks =
333 .find_debuginfo = dwfl_standard_find_debuginfo,
334 .debuginfo_path = &debuginfo_path,
336 .find_elf = dwfl_linux_proc_find_elf,
339 if (proc_handle->dwfl == NULL)
341 proc_handle->dwfl = dwfl_begin (&proc_callbacks);
342 assert (proc_handle->dwfl != NULL);
345 if (dwfl_linux_proc_report (proc_handle->dwfl, proc_handle->pid) != 0
346 || dwfl_report_end (proc_handle->dwfl, NULL, NULL) != 0)
348 fprintf (stderr, "dwfl reporting: %m\n");
352 return proc_handle->dwfl;
355 /* Functions in this interface return one of these status codes. */
358 PS_OK, /* Generic "call succeeded". */
359 PS_ERR, /* Generic error. */
360 PS_BADPID, /* Bad process handle. */
361 PS_BADLID, /* Bad LWP identifier. */
362 PS_BADADDR, /* Bad address. */
363 PS_NOSYM, /* Could not find given symbol. */
364 PS_NOFREGS /* FPU register set not available for given LWP. */
367 ps_err_e ps_pdread (struct ps_prochandle *proc_handle, psaddr_t addr,
368 void *buffer, size_t length)
370 pid_t pid = proc_handle->pid;
374 if (pid == getpid ())
376 memcpy (buffer, addr, length);
380 /* Already under PTRACE_ATTACH. */
382 if (ptrace (PTRACE_ATTACH, pid, NULL, NULL) != 0)
384 if (waitpid (pid, NULL, 0) != pid)
388 snprintf (filename, sizeof (filename), "/proc/%ld/mem", (long) pid);
389 fd = open (filename, O_RDONLY);
391 if (lseek64 (fd, (off64_t) addr, SEEK_SET) != (off64_t) addr)
393 if (read (fd, buffer, length) != length)
395 /* It occurs for singlethreaded processes. */
396 if ((off64_t) addr == 0)
398 fprintf (stderr, "read() error @0x%lx length %lu: %m\n",
399 (unsigned long) addr, (unsigned long) length);
405 /* Already under PTRACE_ATTACH. */
407 if (ptrace (PTRACE_DETACH, pid, NULL, NULL) != 0)
414 ps_err_e ps_pdwrite (struct ps_prochandle *proc_handle, psaddr_t addr,
415 const void *buffer, size_t length)
420 ps_err_e ps_lgetregs (struct ps_prochandle *proc_handle, lwpid_t lwp,
426 ps_err_e ps_lsetregs (struct ps_prochandle *proc_handle, lwpid_t lwp,
427 const prgregset_t regs)
432 ps_err_e ps_lgetfpregs (struct ps_prochandle *proc_handle, lwpid_t lwp,
433 prfpregset_t *fpregs)
438 ps_err_e ps_lsetfpregs (struct ps_prochandle *proc_handle, lwpid_t lwp,
439 const prfpregset_t *fpregs)
444 /* Return the PID of the process. */
445 pid_t ps_getpid (struct ps_prochandle *proc_handle)
447 return proc_handle->pid;
450 struct getmodules_callback_arg
452 const char *sym_name;
457 static int getmodules_callback (Dwfl_Module *module,
458 void **module_userdata_pointer,
459 const char *module_name,
460 Dwarf_Addr module_low_addr, void *arg)
462 struct getmodules_callback_arg *getmodules_callback_arg = arg;
466 sym_count = dwfl_module_getsymtab (module);
469 assert (sym_count >= 0);
471 for (ndx = 0; ndx < sym_count; ndx++)
473 const char *name_got;
475 name_got = dwfl_module_getsym (module, ndx, &sym,
477 assert (name_got != NULL);
478 if (strcmp (name_got, getmodules_callback_arg->sym_name) == 0)
481 if (ndx == sym_count)
484 *getmodules_callback_arg->sym_addr = (psaddr_t) sym.st_value;
485 getmodules_callback_arg->retval = PS_OK;
490 /* Look up the named symbol in the named DSO in the symbol tables
491 associated with the process being debugged, filling in *SYM_ADDR
492 with the corresponding run-time address. */
493 ps_err_e ps_pglobal_lookup (struct ps_prochandle *proc_handle,
494 const char *object_name, const char *sym_name,
497 Dwfl *dwfl = get_dwfl (proc_handle);
498 struct getmodules_callback_arg getmodules_callback_arg;
499 ptrdiff_t err_ptrdiff;
501 /* FIXME: `object_name' ignored due to missing unresolving of shared
502 libraries symbolic links. */
503 getmodules_callback_arg.sym_name = sym_name;
504 getmodules_callback_arg.sym_addr = sym_addr;
505 getmodules_callback_arg.retval = PS_NOSYM;
506 err_ptrdiff = dwfl_getmodules (dwfl, getmodules_callback,
507 &getmodules_callback_arg, 0);
508 assert (err_ptrdiff == 0);
509 return getmodules_callback_arg.retval;
513 ps_err_e ps_get_thread_area (const struct ps_prochandle *ph, lwpid_t lwpid,
514 int idx, void **base)
518 assert (idx == FS || idx == GS);
520 if (ptrace (PTRACE_ATTACH, lwpid, NULL, NULL) != 0)
522 if (waitpid (lwpid, NULL, 0) != lwpid)
525 val = ptrace (PTRACE_ARCH_PRCTL, lwpid, base, (idx == FS ? ARCH_GET_FS
528 if (ptrace (PTRACE_DETACH, lwpid, NULL, NULL) != 0)
533 fprintf (stderr, "PTRACE_ARCH_PRCTL (%s): %m\n", (idx == FS ? "FS"
541 #error "Unsupported ps_get_thread_area ()!"
544 static int find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
548 struct attach_state_struct *attach_state = data;
550 err = td_thr_get_info (th_p, &info);
551 assert (err == TD_OK);
552 /* printf ("LWP = %ld TID = 0x%lx\n", (long) info.ti_lid, info.ti_tid); */
554 attach_state->threads_count++;
559 static void attach_multi (struct attach_state_struct *attach_state)
564 assert (err == TD_OK);
566 err = td_ta_new (attach_state, &attach_state->thread_agent);
567 assert (err == TD_OK || err == TD_NOLIBTHREAD);
568 attach_state->threads_count = 0;
569 if (err == TD_NOLIBTHREAD)
571 attach_state->thread_agent = NULL;
574 assert (attach_state->thread_agent != NULL);
575 /* Multithreading test: */
576 err = td_ta_thr_iter (attach_state->thread_agent, find_new_threads_callback,
577 attach_state, TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
578 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
581 fprintf (stderr, "err = %d\n", err);
584 /* Do not: assert (attach_state->threads_count > 0);
585 as during early initialization we really may get 0. */
588 struct attach_state_struct *attach (pid_t pid)
590 struct attach_state_struct *attach_state;
592 attach_state = attach_single (pid);
593 attach_multi (attach_state);
598 void detach (struct attach_state_struct *attach_state)
600 if (attach_state->thread_agent != NULL)
604 err = td_ta_delete (attach_state->thread_agent);
605 assert (err == TD_OK);
607 if (attach_state->dwfl != NULL);
608 dwfl_end (attach_state->dwfl);
610 detach_single (attach_state);
615 int main (int argc, char **argv)
618 struct attach_state_struct *attach_state;
622 fprintf (stderr, "Usage: %s <PID>\n", argv[0]);
626 pid = atoi (argv[1]);
628 attach_state = attach (pid);
629 detach (attach_state);
634 #endif /* !LIBRARY */