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 */
35 /* Function: child_pid_to_exec_file
37 * Accepts an integer pid
38 * Returns a string representing a file that can be opened
39 * to get the symbols for the child process.
43 child_pid_to_exec_file (int pid
)
47 name1
= xmalloc (MAXPATHLEN
);
48 name2
= xmalloc (MAXPATHLEN
);
49 make_cleanup (xfree
, name1
);
50 make_cleanup (xfree
, name2
);
51 memset (name2
, 0, MAXPATHLEN
);
53 sprintf (name1
, "/proc/%d/exe", pid
);
54 if (readlink (name1
, name2
, MAXPATHLEN
) > 0)
60 /* Function: read_mappings
62 * Service function for corefiles and info proc.
66 read_mapping (FILE *mapfile
,
75 int ret
= fscanf (mapfile
, "%llx-%llx %s %llx %s %llx",
76 addr
, endaddr
, permissions
, offset
, device
, inode
);
78 if (ret
> 0 && ret
!= EOF
&& *inode
!= 0)
80 /* Eat everything up to EOL for the filename. This will prevent
81 weird filenames (such as one with embedded whitespace) from
82 confusing this code. It also makes this code more robust
83 in respect to annotations the kernel may add after the
86 Note the filename is used for informational purposes only. */
87 ret
+= fscanf (mapfile
, "%[^\n]\n", filename
);
91 filename
[0] = '\0'; /* no filename */
92 fscanf (mapfile
, "\n");
94 return (ret
!= 0 && ret
!= EOF
);
97 /* Function: linux_find_memory_regions
99 * Fills the "to_find_memory_regions" target vector.
100 * Lists the memory regions in the inferior for a corefile.
104 linux_find_memory_regions (int (*func
) (CORE_ADDR
,
110 long long pid
= PIDGET (inferior_ptid
);
111 char mapsfilename
[MAXPATHLEN
];
113 long long addr
, endaddr
, size
, offset
, inode
;
114 char permissions
[8], device
[8], filename
[MAXPATHLEN
];
115 int read
, write
, exec
;
118 /* Compose the filename for the /proc memory map, and open it. */
119 sprintf (mapsfilename
, "/proc/%lld/maps", pid
);
120 if ((mapsfile
= fopen (mapsfilename
, "r")) == NULL
)
121 error ("Could not open %s\n", mapsfilename
);
124 fprintf_filtered (gdb_stdout
,
125 "Reading memory regions from %s\n", mapsfilename
);
127 /* Now iterate until end-of-file. */
128 while (read_mapping (mapsfile
, &addr
, &endaddr
, &permissions
[0],
129 &offset
, &device
[0], &inode
, &filename
[0]))
131 size
= endaddr
- addr
;
133 /* Get the segment's permissions. */
134 read
= (strchr (permissions
, 'r') != 0);
135 write
= (strchr (permissions
, 'w') != 0);
136 exec
= (strchr (permissions
, 'x') != 0);
140 fprintf_filtered (gdb_stdout
,
141 "Save segment, %lld bytes at 0x%s (%c%c%c)",
142 size
, paddr_nz (addr
),
146 if (filename
&& filename
[0])
147 fprintf_filtered (gdb_stdout
,
148 " for %s", filename
);
149 fprintf_filtered (gdb_stdout
, "\n");
152 /* Invoke the callback function to create the corefile segment. */
153 func (addr
, size
, read
, write
, exec
, obfd
);
159 /* Function: linux_do_thread_registers
161 * Records the thread's register state for the corefile note section.
165 linux_do_thread_registers (bfd
*obfd
, ptid_t ptid
,
166 char *note_data
, int *note_size
)
169 gdb_fpregset_t fpregs
;
170 #ifdef FILL_FPXREGSET
171 gdb_fpxregset_t fpxregs
;
173 unsigned long merged_pid
= ptid_get_tid (ptid
) << 16 | ptid_get_pid (ptid
);
175 fill_gregset (&gregs
, -1);
176 note_data
= (char *) elfcore_write_prstatus (obfd
,
183 fill_fpregset (&fpregs
, -1);
184 note_data
= (char *) elfcore_write_prfpreg (obfd
,
189 #ifdef FILL_FPXREGSET
190 fill_fpxregset (&fpxregs
, -1);
191 note_data
= (char *) elfcore_write_prxfpreg (obfd
,
200 struct linux_corefile_thread_data
{
206 /* Function: linux_corefile_thread_callback
208 * Called by gdbthread.c once per thread.
209 * Records the thread's register state for the corefile note section.
213 linux_corefile_thread_callback (struct thread_info
*ti
, void *data
)
215 struct linux_corefile_thread_data
*args
= data
;
216 ptid_t saved_ptid
= inferior_ptid
;
218 inferior_ptid
= ti
->ptid
;
219 registers_changed ();
220 target_fetch_registers (-1); /* FIXME should not be necessary;
221 fill_gregset should do it automatically. */
222 args
->note_data
= linux_do_thread_registers (args
->obfd
,
226 inferior_ptid
= saved_ptid
;
227 registers_changed ();
228 target_fetch_registers (-1); /* FIXME should not be necessary;
229 fill_gregset should do it automatically. */
233 /* Function: linux_make_note_section
235 * Fills the "to_make_corefile_note" target vector.
236 * Builds the note section for a corefile, and returns it
237 * in a malloc buffer.
241 linux_make_note_section (bfd
*obfd
, int *note_size
)
243 struct linux_corefile_thread_data thread_args
;
244 struct cleanup
*old_chain
;
245 char fname
[16] = {'\0'};
246 char psargs
[80] = {'\0'};
247 char *note_data
= NULL
;
248 ptid_t current_ptid
= inferior_ptid
;
250 if (get_exec_file (0))
252 strncpy (fname
, strrchr (get_exec_file (0), '/') + 1, sizeof (fname
));
253 strncpy (psargs
, get_exec_file (0),
255 if (get_inferior_args ())
257 strncat (psargs
, " ",
258 sizeof (psargs
) - strlen (psargs
));
259 strncat (psargs
, get_inferior_args (),
260 sizeof (psargs
) - strlen (psargs
));
262 note_data
= (char *) elfcore_write_prpsinfo (obfd
,
269 /* Dump information for threads. */
270 thread_args
.obfd
= obfd
;
271 thread_args
.note_data
= note_data
;
272 thread_args
.note_size
= note_size
;
273 iterate_over_threads (linux_corefile_thread_callback
, &thread_args
);
274 if (thread_args
.note_data
== note_data
)
276 /* iterate_over_threads didn't come up with any threads;
277 just use inferior_ptid. */
278 note_data
= linux_do_thread_registers (obfd
, inferior_ptid
,
279 note_data
, note_size
);
283 note_data
= thread_args
.note_data
;
286 make_cleanup (xfree
, note_data
);
291 * Function: linux_info_proc_cmd
293 * Implement the "info proc" command.
297 linux_info_proc_cmd (char *args
, int from_tty
)
299 long long pid
= PIDGET (inferior_ptid
);
302 char buffer
[MAXPATHLEN
];
303 char fname1
[MAXPATHLEN
], fname2
[MAXPATHLEN
];
316 /* Break up 'args' into an argv array. */
317 if ((argv
= buildargv (args
)) == NULL
)
320 make_cleanup_freeargv (argv
);
322 while (argv
!= NULL
&& *argv
!= NULL
)
324 if (isdigit (argv
[0][0]))
326 pid
= strtoul (argv
[0], NULL
, 10);
328 else if (strncmp (argv
[0], "mappings", strlen (argv
[0])) == 0)
332 else if (strcmp (argv
[0], "status") == 0)
336 else if (strcmp (argv
[0], "stat") == 0)
340 else if (strcmp (argv
[0], "cmd") == 0)
344 else if (strncmp (argv
[0], "exe", strlen (argv
[0])) == 0)
348 else if (strcmp (argv
[0], "cwd") == 0)
352 else if (strncmp (argv
[0], "all", strlen (argv
[0])) == 0)
358 /* [...] (future options here) */
363 error ("No current process: you must name one.");
365 sprintf (fname1
, "/proc/%lld", pid
);
366 if (stat (fname1
, &dummy
) != 0)
367 error ("No /proc directory: '%s'", fname1
);
369 printf_filtered ("process %lld\n", pid
);
370 if (cmdline_f
|| all
)
372 sprintf (fname1
, "/proc/%lld/cmdline", pid
);
373 if ((procfile
= fopen (fname1
, "r")) > 0)
375 fgets (buffer
, sizeof (buffer
), procfile
);
376 printf_filtered ("cmdline = '%s'\n", buffer
);
380 warning ("unable to open /proc file '%s'", fname1
);
384 sprintf (fname1
, "/proc/%lld/cwd", pid
);
385 memset (fname2
, 0, sizeof (fname2
));
386 if (readlink (fname1
, fname2
, sizeof (fname2
)) > 0)
387 printf_filtered ("cwd = '%s'\n", fname2
);
389 warning ("unable to read link '%s'", fname1
);
393 sprintf (fname1
, "/proc/%lld/exe", pid
);
394 memset (fname2
, 0, sizeof (fname2
));
395 if (readlink (fname1
, fname2
, sizeof (fname2
)) > 0)
396 printf_filtered ("exe = '%s'\n", fname2
);
398 warning ("unable to read link '%s'", fname1
);
400 if (mappings_f
|| all
)
402 sprintf (fname1
, "/proc/%lld/maps", pid
);
403 if ((procfile
= fopen (fname1
, "r")) > 0)
405 long long addr
, endaddr
, size
, offset
, inode
;
406 char permissions
[8], device
[8], filename
[MAXPATHLEN
];
407 char *header_fmt_string
, *data_fmt_string
;
409 if (TARGET_ADDR_BIT
== 32)
411 header_fmt_string
= "\t%10s %10s %10s %10s %7s\n";
412 data_fmt_string
= "\t%#10lx %#10lx %#10x %#10x %7s\n";
416 header_fmt_string
= " %18s %18s %10s %10s %7s\n";
417 data_fmt_string
= " %#18lx %#18lx %#10x %#10x %7s\n";
420 printf_filtered ("Mapped address spaces:\n\n");
421 printf_filtered (header_fmt_string
,
428 while (read_mapping (procfile
, &addr
, &endaddr
, &permissions
[0],
429 &offset
, &device
[0], &inode
, &filename
[0]))
431 size
= endaddr
- addr
;
432 printf_filtered (data_fmt_string
,
433 (unsigned long) addr
, /* FIXME: pr_addr */
434 (unsigned long) endaddr
,
436 (unsigned int) offset
,
437 filename
[0] ? filename
: "");
444 warning ("unable to open /proc file '%s'", fname1
);
448 sprintf (fname1
, "/proc/%lld/status", pid
);
449 if ((procfile
= fopen (fname1
, "r")) > 0)
451 while (fgets (buffer
, sizeof (buffer
), procfile
) != NULL
)
452 printf_filtered (buffer
);
456 warning ("unable to open /proc file '%s'", fname1
);
460 sprintf (fname1
, "/proc/%lld/stat", pid
);
461 if ((procfile
= fopen (fname1
, "r")) > 0)
466 if (fscanf (procfile
, "%d ", &itmp
) > 0)
467 printf_filtered ("Process: %d\n", itmp
);
468 if (fscanf (procfile
, "%s ", &buffer
[0]) > 0)
469 printf_filtered ("Exec file: %s\n", buffer
);
470 if (fscanf (procfile
, "%c ", &ctmp
) > 0)
471 printf_filtered ("State: %c\n", ctmp
);
472 if (fscanf (procfile
, "%d ", &itmp
) > 0)
473 printf_filtered ("Parent process: %d\n", itmp
);
474 if (fscanf (procfile
, "%d ", &itmp
) > 0)
475 printf_filtered ("Process group: %d\n", itmp
);
476 if (fscanf (procfile
, "%d ", &itmp
) > 0)
477 printf_filtered ("Session id: %d\n", itmp
);
478 if (fscanf (procfile
, "%d ", &itmp
) > 0)
479 printf_filtered ("TTY: %d\n", itmp
);
480 if (fscanf (procfile
, "%d ", &itmp
) > 0)
481 printf_filtered ("TTY owner process group: %d\n", itmp
);
482 if (fscanf (procfile
, "%u ", &itmp
) > 0)
483 printf_filtered ("Flags: 0x%x\n", itmp
);
484 if (fscanf (procfile
, "%u ", &itmp
) > 0)
485 printf_filtered ("Minor faults (no memory page): %u\n",
486 (unsigned int) itmp
);
487 if (fscanf (procfile
, "%u ", &itmp
) > 0)
488 printf_filtered ("Minor faults, children: %u\n",
489 (unsigned int) itmp
);
490 if (fscanf (procfile
, "%u ", &itmp
) > 0)
491 printf_filtered ("Major faults (memory page faults): %u\n",
492 (unsigned int) itmp
);
493 if (fscanf (procfile
, "%u ", &itmp
) > 0)
494 printf_filtered ("Major faults, children: %u\n",
495 (unsigned int) itmp
);
496 if (fscanf (procfile
, "%d ", &itmp
) > 0)
497 printf_filtered ("utime: %d\n", itmp
);
498 if (fscanf (procfile
, "%d ", &itmp
) > 0)
499 printf_filtered ("stime: %d\n", itmp
);
500 if (fscanf (procfile
, "%d ", &itmp
) > 0)
501 printf_filtered ("utime, children: %d\n", itmp
);
502 if (fscanf (procfile
, "%d ", &itmp
) > 0)
503 printf_filtered ("stime, children: %d\n", itmp
);
504 if (fscanf (procfile
, "%d ", &itmp
) > 0)
505 printf_filtered ("jiffies remaining in current time slice: %d\n",
507 if (fscanf (procfile
, "%d ", &itmp
) > 0)
508 printf_filtered ("'nice' value: %d\n", itmp
);
509 if (fscanf (procfile
, "%u ", &itmp
) > 0)
510 printf_filtered ("jiffies until next timeout: %u\n",
511 (unsigned int) itmp
);
512 if (fscanf (procfile
, "%u ", &itmp
) > 0)
513 printf_filtered ("jiffies until next SIGALRM: %u\n",
514 (unsigned int) itmp
);
515 if (fscanf (procfile
, "%d ", &itmp
) > 0)
516 printf_filtered ("start time (jiffies since system boot): %d\n",
518 if (fscanf (procfile
, "%u ", &itmp
) > 0)
519 printf_filtered ("Virtual memory size: %u\n",
520 (unsigned int) itmp
);
521 if (fscanf (procfile
, "%u ", &itmp
) > 0)
522 printf_filtered ("Resident set size: %u\n",
523 (unsigned int) itmp
);
524 if (fscanf (procfile
, "%u ", &itmp
) > 0)
525 printf_filtered ("rlim: %u\n",
526 (unsigned int) itmp
);
527 if (fscanf (procfile
, "%u ", &itmp
) > 0)
528 printf_filtered ("Start of text: 0x%x\n", itmp
);
529 if (fscanf (procfile
, "%u ", &itmp
) > 0)
530 printf_filtered ("End of text: 0x%x\n", itmp
);
531 if (fscanf (procfile
, "%u ", &itmp
) > 0)
532 printf_filtered ("Start of stack: 0x%x\n", itmp
);
533 #if 0 /* Don't know how architecture-dependent the rest is...
534 Anyway the signal bitmap info is available from "status". */
535 if (fscanf (procfile
, "%u ", &itmp
) > 0) /* FIXME arch? */
536 printf_filtered ("Kernel stack pointer: 0x%x\n", itmp
);
537 if (fscanf (procfile
, "%u ", &itmp
) > 0) /* FIXME arch? */
538 printf_filtered ("Kernel instr pointer: 0x%x\n", itmp
);
539 if (fscanf (procfile
, "%d ", &itmp
) > 0)
540 printf_filtered ("Pending signals bitmap: 0x%x\n", itmp
);
541 if (fscanf (procfile
, "%d ", &itmp
) > 0)
542 printf_filtered ("Blocked signals bitmap: 0x%x\n", itmp
);
543 if (fscanf (procfile
, "%d ", &itmp
) > 0)
544 printf_filtered ("Ignored signals bitmap: 0x%x\n", itmp
);
545 if (fscanf (procfile
, "%d ", &itmp
) > 0)
546 printf_filtered ("Catched signals bitmap: 0x%x\n", itmp
);
547 if (fscanf (procfile
, "%u ", &itmp
) > 0) /* FIXME arch? */
548 printf_filtered ("wchan (system call): 0x%x\n", itmp
);
553 warning ("unable to open /proc file '%s'", fname1
);
558 _initialize_linux_proc (void)
560 extern void inftarg_set_find_memory_regions ();
561 extern void inftarg_set_make_corefile_notes ();
563 inftarg_set_find_memory_regions (linux_find_memory_regions
);
564 inftarg_set_make_corefile_notes (linux_make_note_section
);
566 add_info ("proc", linux_info_proc_cmd
,
567 "Show /proc process information about any running process.\n\
568 Specify any process id, or use the program being debugged by default.\n\
569 Specify any of the following keywords for detailed info:\n\
570 mappings -- list of mapped memory regions.\n\
571 stat -- list a bunch of random process info.\n\
572 status -- list a different bunch of random process info.\n\
573 all -- list all available /proc info.");