1 /* GNU/Linux specific methods for using the /proc file system.
3 Copyright 2001, 2002 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
24 #include <sys/param.h> /* for MAXPATHLEN */
25 #include <sys/procfs.h> /* for elf_gregset etc. */
26 #include <sys/stat.h> /* for struct stat */
27 #include <ctype.h> /* for isdigit */
28 #include "regcache.h" /* for registers_changed */
29 #include "gregset.h" /* for gregset */
30 #include "gdbcore.h" /* for get_exec_file */
31 #include "gdbthread.h" /* for struct thread_info etc. */
32 #include "elf-bfd.h" /* for elfcore_write_* */
33 #include "cli/cli-decode.h" /* for add_info */
34 #include "gdb_string.h"
36 /* Function: child_pid_to_exec_file
38 * Accepts an integer pid
39 * Returns a string representing a file that can be opened
40 * to get the symbols for the child process.
44 child_pid_to_exec_file (int pid)
48 name1 = xmalloc (MAXPATHLEN);
49 name2 = xmalloc (MAXPATHLEN);
50 make_cleanup (xfree, name1);
51 make_cleanup (xfree, name2);
52 memset (name2, 0, MAXPATHLEN);
54 sprintf (name1, "/proc/%d/exe", pid);
55 if (readlink (name1, name2, MAXPATHLEN) > 0)
61 /* Function: read_mappings
63 * Service function for corefiles and info proc.
67 read_mapping (FILE *mapfile,
76 int ret = fscanf (mapfile, "%llx-%llx %s %llx %s %llx",
77 addr, endaddr, permissions, offset, device, inode);
79 if (ret > 0 && ret != EOF && *inode != 0)
81 /* Eat everything up to EOL for the filename. This will prevent
82 weird filenames (such as one with embedded whitespace) from
83 confusing this code. It also makes this code more robust
84 in respect to annotations the kernel may add after the
87 Note the filename is used for informational purposes only. */
88 ret += fscanf (mapfile, "%[^\n]\n", filename);
92 filename[0] = '\0'; /* no filename */
93 fscanf (mapfile, "\n");
95 return (ret != 0 && ret != EOF);
98 /* Function: linux_find_memory_regions
100 * Fills the "to_find_memory_regions" target vector.
101 * Lists the memory regions in the inferior for a corefile.
105 linux_find_memory_regions (int (*func) (CORE_ADDR,
111 long long pid = PIDGET (inferior_ptid);
112 char mapsfilename[MAXPATHLEN];
114 long long addr, endaddr, size, offset, inode;
115 char permissions[8], device[8], filename[MAXPATHLEN];
116 int read, write, exec;
119 /* Compose the filename for the /proc memory map, and open it. */
120 sprintf (mapsfilename, "/proc/%lld/maps", pid);
121 if ((mapsfile = fopen (mapsfilename, "r")) == NULL)
122 error ("Could not open %s\n", mapsfilename);
125 fprintf_filtered (gdb_stdout,
126 "Reading memory regions from %s\n", mapsfilename);
128 /* Now iterate until end-of-file. */
129 while (read_mapping (mapsfile, &addr, &endaddr, &permissions[0],
130 &offset, &device[0], &inode, &filename[0]))
132 size = endaddr - addr;
134 /* Get the segment's permissions. */
135 read = (strchr (permissions, 'r') != 0);
136 write = (strchr (permissions, 'w') != 0);
137 exec = (strchr (permissions, 'x') != 0);
141 fprintf_filtered (gdb_stdout,
142 "Save segment, %lld bytes at 0x%s (%c%c%c)",
143 size, paddr_nz (addr),
147 if (filename && filename[0])
148 fprintf_filtered (gdb_stdout,
149 " for %s", filename);
150 fprintf_filtered (gdb_stdout, "\n");
153 /* Invoke the callback function to create the corefile segment. */
154 func (addr, size, read, write, exec, obfd);
160 /* Function: linux_do_thread_registers
162 * Records the thread's register state for the corefile note section.
166 linux_do_thread_registers (bfd *obfd, ptid_t ptid,
167 char *note_data, int *note_size)
170 gdb_fpregset_t fpregs;
171 #ifdef FILL_FPXREGSET
172 gdb_fpxregset_t fpxregs;
174 unsigned long merged_pid = ptid_get_tid (ptid) << 16 | ptid_get_pid (ptid);
176 fill_gregset (&gregs, -1);
177 note_data = (char *) elfcore_write_prstatus (obfd,
184 fill_fpregset (&fpregs, -1);
185 note_data = (char *) elfcore_write_prfpreg (obfd,
190 #ifdef FILL_FPXREGSET
191 fill_fpxregset (&fpxregs, -1);
192 note_data = (char *) elfcore_write_prxfpreg (obfd,
201 struct linux_corefile_thread_data
209 /* Function: linux_corefile_thread_callback
211 * Called by gdbthread.c once per thread.
212 * Records the thread's register state for the corefile note section.
216 linux_corefile_thread_callback (struct thread_info *ti, void *data)
218 struct linux_corefile_thread_data *args = data;
219 ptid_t saved_ptid = inferior_ptid;
221 inferior_ptid = ti->ptid;
222 registers_changed ();
223 target_fetch_registers (-1); /* FIXME should not be necessary;
224 fill_gregset should do it automatically. */
225 args->note_data = linux_do_thread_registers (args->obfd,
230 inferior_ptid = saved_ptid;
231 registers_changed ();
232 target_fetch_registers (-1); /* FIXME should not be necessary;
233 fill_gregset should do it automatically. */
237 /* Function: linux_make_note_section
239 * Fills the "to_make_corefile_note" target vector.
240 * Builds the note section for a corefile, and returns it
241 * in a malloc buffer.
245 linux_make_note_section (bfd *obfd, int *note_size)
247 struct linux_corefile_thread_data thread_args;
248 struct cleanup *old_chain;
249 char fname[16] = {'\0'};
250 char psargs[80] = {'\0'};
251 char *note_data = NULL;
252 ptid_t current_ptid = inferior_ptid;
254 if (get_exec_file (0))
256 strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname));
257 strncpy (psargs, get_exec_file (0),
259 if (get_inferior_args ())
261 strncat (psargs, " ",
262 sizeof (psargs) - strlen (psargs));
263 strncat (psargs, get_inferior_args (),
264 sizeof (psargs) - strlen (psargs));
266 note_data = (char *) elfcore_write_prpsinfo (obfd,
273 /* Dump information for threads. */
274 thread_args.obfd = obfd;
275 thread_args.note_data = note_data;
276 thread_args.note_size = note_size;
277 thread_args.num_notes = 0;
278 iterate_over_threads (linux_corefile_thread_callback, &thread_args);
279 if (thread_args.num_notes == 0)
281 /* iterate_over_threads didn't come up with any threads;
282 just use inferior_ptid. */
283 note_data = linux_do_thread_registers (obfd, inferior_ptid,
284 note_data, note_size);
288 note_data = thread_args.note_data;
291 make_cleanup (xfree, note_data);
296 * Function: linux_info_proc_cmd
298 * Implement the "info proc" command.
302 linux_info_proc_cmd (char *args, int from_tty)
304 long long pid = PIDGET (inferior_ptid);
307 char buffer[MAXPATHLEN];
308 char fname1[MAXPATHLEN], fname2[MAXPATHLEN];
321 /* Break up 'args' into an argv array. */
322 if ((argv = buildargv (args)) == NULL)
325 make_cleanup_freeargv (argv);
327 while (argv != NULL && *argv != NULL)
329 if (isdigit (argv[0][0]))
331 pid = strtoul (argv[0], NULL, 10);
333 else if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0)
337 else if (strcmp (argv[0], "status") == 0)
341 else if (strcmp (argv[0], "stat") == 0)
345 else if (strcmp (argv[0], "cmd") == 0)
349 else if (strncmp (argv[0], "exe", strlen (argv[0])) == 0)
353 else if (strcmp (argv[0], "cwd") == 0)
357 else if (strncmp (argv[0], "all", strlen (argv[0])) == 0)
363 /* [...] (future options here) */
368 error ("No current process: you must name one.");
370 sprintf (fname1, "/proc/%lld", pid);
371 if (stat (fname1, &dummy) != 0)
372 error ("No /proc directory: '%s'", fname1);
374 printf_filtered ("process %lld\n", pid);
375 if (cmdline_f || all)
377 sprintf (fname1, "/proc/%lld/cmdline", pid);
378 if ((procfile = fopen (fname1, "r")) > 0)
380 fgets (buffer, sizeof (buffer), procfile);
381 printf_filtered ("cmdline = '%s'\n", buffer);
385 warning ("unable to open /proc file '%s'", fname1);
389 sprintf (fname1, "/proc/%lld/cwd", pid);
390 memset (fname2, 0, sizeof (fname2));
391 if (readlink (fname1, fname2, sizeof (fname2)) > 0)
392 printf_filtered ("cwd = '%s'\n", fname2);
394 warning ("unable to read link '%s'", fname1);
398 sprintf (fname1, "/proc/%lld/exe", pid);
399 memset (fname2, 0, sizeof (fname2));
400 if (readlink (fname1, fname2, sizeof (fname2)) > 0)
401 printf_filtered ("exe = '%s'\n", fname2);
403 warning ("unable to read link '%s'", fname1);
405 if (mappings_f || all)
407 sprintf (fname1, "/proc/%lld/maps", pid);
408 if ((procfile = fopen (fname1, "r")) > 0)
410 long long addr, endaddr, size, offset, inode;
411 char permissions[8], device[8], filename[MAXPATHLEN];
412 char *header_fmt_string, *data_fmt_string;
414 if (TARGET_ADDR_BIT == 32)
416 header_fmt_string = "\t%10s %10s %10s %10s %7s\n";
417 data_fmt_string = "\t%#10lx %#10lx %#10x %#10x %7s\n";
421 header_fmt_string = " %18s %18s %10s %10s %7s\n";
422 data_fmt_string = " %#18lx %#18lx %#10x %#10x %7s\n";
425 printf_filtered ("Mapped address spaces:\n\n");
426 printf_filtered (header_fmt_string,
433 while (read_mapping (procfile, &addr, &endaddr, &permissions[0],
434 &offset, &device[0], &inode, &filename[0]))
436 size = endaddr - addr;
437 printf_filtered (data_fmt_string,
438 (unsigned long) addr, /* FIXME: pr_addr */
439 (unsigned long) endaddr,
441 (unsigned int) offset,
442 filename[0] ? filename : "");
449 warning ("unable to open /proc file '%s'", fname1);
453 sprintf (fname1, "/proc/%lld/status", pid);
454 if ((procfile = fopen (fname1, "r")) > 0)
456 while (fgets (buffer, sizeof (buffer), procfile) != NULL)
457 printf_filtered (buffer);
461 warning ("unable to open /proc file '%s'", fname1);
465 sprintf (fname1, "/proc/%lld/stat", pid);
466 if ((procfile = fopen (fname1, "r")) > 0)
471 if (fscanf (procfile, "%d ", &itmp) > 0)
472 printf_filtered ("Process: %d\n", itmp);
473 if (fscanf (procfile, "%s ", &buffer[0]) > 0)
474 printf_filtered ("Exec file: %s\n", buffer);
475 if (fscanf (procfile, "%c ", &ctmp) > 0)
476 printf_filtered ("State: %c\n", ctmp);
477 if (fscanf (procfile, "%d ", &itmp) > 0)
478 printf_filtered ("Parent process: %d\n", itmp);
479 if (fscanf (procfile, "%d ", &itmp) > 0)
480 printf_filtered ("Process group: %d\n", itmp);
481 if (fscanf (procfile, "%d ", &itmp) > 0)
482 printf_filtered ("Session id: %d\n", itmp);
483 if (fscanf (procfile, "%d ", &itmp) > 0)
484 printf_filtered ("TTY: %d\n", itmp);
485 if (fscanf (procfile, "%d ", &itmp) > 0)
486 printf_filtered ("TTY owner process group: %d\n", itmp);
487 if (fscanf (procfile, "%u ", &itmp) > 0)
488 printf_filtered ("Flags: 0x%x\n", itmp);
489 if (fscanf (procfile, "%u ", &itmp) > 0)
490 printf_filtered ("Minor faults (no memory page): %u\n",
491 (unsigned int) itmp);
492 if (fscanf (procfile, "%u ", &itmp) > 0)
493 printf_filtered ("Minor faults, children: %u\n",
494 (unsigned int) itmp);
495 if (fscanf (procfile, "%u ", &itmp) > 0)
496 printf_filtered ("Major faults (memory page faults): %u\n",
497 (unsigned int) itmp);
498 if (fscanf (procfile, "%u ", &itmp) > 0)
499 printf_filtered ("Major faults, children: %u\n",
500 (unsigned int) itmp);
501 if (fscanf (procfile, "%d ", &itmp) > 0)
502 printf_filtered ("utime: %d\n", itmp);
503 if (fscanf (procfile, "%d ", &itmp) > 0)
504 printf_filtered ("stime: %d\n", itmp);
505 if (fscanf (procfile, "%d ", &itmp) > 0)
506 printf_filtered ("utime, children: %d\n", itmp);
507 if (fscanf (procfile, "%d ", &itmp) > 0)
508 printf_filtered ("stime, children: %d\n", itmp);
509 if (fscanf (procfile, "%d ", &itmp) > 0)
510 printf_filtered ("jiffies remaining in current time slice: %d\n",
512 if (fscanf (procfile, "%d ", &itmp) > 0)
513 printf_filtered ("'nice' value: %d\n", itmp);
514 if (fscanf (procfile, "%u ", &itmp) > 0)
515 printf_filtered ("jiffies until next timeout: %u\n",
516 (unsigned int) itmp);
517 if (fscanf (procfile, "%u ", &itmp) > 0)
518 printf_filtered ("jiffies until next SIGALRM: %u\n",
519 (unsigned int) itmp);
520 if (fscanf (procfile, "%d ", &itmp) > 0)
521 printf_filtered ("start time (jiffies since system boot): %d\n",
523 if (fscanf (procfile, "%u ", &itmp) > 0)
524 printf_filtered ("Virtual memory size: %u\n",
525 (unsigned int) itmp);
526 if (fscanf (procfile, "%u ", &itmp) > 0)
527 printf_filtered ("Resident set size: %u\n",
528 (unsigned int) itmp);
529 if (fscanf (procfile, "%u ", &itmp) > 0)
530 printf_filtered ("rlim: %u\n",
531 (unsigned int) itmp);
532 if (fscanf (procfile, "%u ", &itmp) > 0)
533 printf_filtered ("Start of text: 0x%x\n", itmp);
534 if (fscanf (procfile, "%u ", &itmp) > 0)
535 printf_filtered ("End of text: 0x%x\n", itmp);
536 if (fscanf (procfile, "%u ", &itmp) > 0)
537 printf_filtered ("Start of stack: 0x%x\n", itmp);
538 #if 0 /* Don't know how architecture-dependent the rest is...
539 Anyway the signal bitmap info is available from "status". */
540 if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
541 printf_filtered ("Kernel stack pointer: 0x%x\n", itmp);
542 if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
543 printf_filtered ("Kernel instr pointer: 0x%x\n", itmp);
544 if (fscanf (procfile, "%d ", &itmp) > 0)
545 printf_filtered ("Pending signals bitmap: 0x%x\n", itmp);
546 if (fscanf (procfile, "%d ", &itmp) > 0)
547 printf_filtered ("Blocked signals bitmap: 0x%x\n", itmp);
548 if (fscanf (procfile, "%d ", &itmp) > 0)
549 printf_filtered ("Ignored signals bitmap: 0x%x\n", itmp);
550 if (fscanf (procfile, "%d ", &itmp) > 0)
551 printf_filtered ("Catched signals bitmap: 0x%x\n", itmp);
552 if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
553 printf_filtered ("wchan (system call): 0x%x\n", itmp);
558 warning ("unable to open /proc file '%s'", fname1);
563 _initialize_linux_proc (void)
565 extern void inftarg_set_find_memory_regions ();
566 extern void inftarg_set_make_corefile_notes ();
568 inftarg_set_find_memory_regions (linux_find_memory_regions);
569 inftarg_set_make_corefile_notes (linux_make_note_section);
571 add_info ("proc", linux_info_proc_cmd,
572 "Show /proc process information about any running process.\n\
573 Specify any process id, or use the program being debugged by default.\n\
574 Specify any of the following keywords for detailed info:\n\
575 mappings -- list of mapped memory regions.\n\
576 stat -- list a bunch of random process info.\n\
577 status -- list a different bunch of random process info.\n\
578 all -- list all available /proc info.");