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 unsigned long merged_pid
= ptid_get_tid (ptid
) << 16 | ptid_get_pid (ptid
);
172 fill_gregset (&gregs
, -1);
173 note_data
= (char *) elfcore_write_prstatus (obfd
,
180 fill_fpregset (&fpregs
, -1);
181 note_data
= (char *) elfcore_write_prfpreg (obfd
,
189 struct linux_corefile_thread_data
{
195 /* Function: linux_corefile_thread_callback
197 * Called by gdbthread.c once per thread.
198 * Records the thread's register state for the corefile note section.
202 linux_corefile_thread_callback (struct thread_info
*ti
, void *data
)
204 struct linux_corefile_thread_data
*args
= data
;
205 ptid_t saved_ptid
= inferior_ptid
;
207 inferior_ptid
= ti
->ptid
;
208 registers_changed ();
209 target_fetch_registers (-1); /* FIXME should not be necessary;
210 fill_gregset should do it automatically. */
211 args
->note_data
= linux_do_thread_registers (args
->obfd
,
215 inferior_ptid
= saved_ptid
;
216 registers_changed ();
217 target_fetch_registers (-1); /* FIXME should not be necessary;
218 fill_gregset should do it automatically. */
222 /* Function: linux_make_note_section
224 * Fills the "to_make_corefile_note" target vector.
225 * Builds the note section for a corefile, and returns it
226 * in a malloc buffer.
230 linux_make_note_section (bfd
*obfd
, int *note_size
)
232 struct linux_corefile_thread_data thread_args
;
233 struct cleanup
*old_chain
;
234 char fname
[16] = {'\0'};
235 char psargs
[80] = {'\0'};
236 char *note_data
= NULL
;
237 ptid_t current_ptid
= inferior_ptid
;
239 if (get_exec_file (0))
241 strncpy (fname
, strrchr (get_exec_file (0), '/') + 1, sizeof (fname
));
242 strncpy (psargs
, get_exec_file (0),
244 if (get_inferior_args ())
246 strncat (psargs
, " ",
247 sizeof (psargs
) - strlen (psargs
));
248 strncat (psargs
, get_inferior_args (),
249 sizeof (psargs
) - strlen (psargs
));
251 note_data
= (char *) elfcore_write_prpsinfo (obfd
,
258 /* Dump information for threads. */
259 thread_args
.obfd
= obfd
;
260 thread_args
.note_data
= note_data
;
261 thread_args
.note_size
= note_size
;
262 iterate_over_threads (linux_corefile_thread_callback
, &thread_args
);
263 if (thread_args
.note_data
== note_data
)
265 /* iterate_over_threads didn't come up with any threads;
266 just use inferior_ptid. */
267 note_data
= linux_do_thread_registers (obfd
, inferior_ptid
,
268 note_data
, note_size
);
272 note_data
= thread_args
.note_data
;
275 make_cleanup (xfree
, note_data
);
280 * Function: linux_info_proc_cmd
282 * Implement the "info proc" command.
286 linux_info_proc_cmd (char *args
, int from_tty
)
288 long long pid
= PIDGET (inferior_ptid
);
291 char buffer
[MAXPATHLEN
];
292 char fname1
[MAXPATHLEN
], fname2
[MAXPATHLEN
];
305 /* Break up 'args' into an argv array. */
306 if ((argv
= buildargv (args
)) == NULL
)
309 make_cleanup_freeargv (argv
);
311 while (argv
!= NULL
&& *argv
!= NULL
)
313 if (isdigit (argv
[0][0]))
315 pid
= strtoul (argv
[0], NULL
, 10);
317 else if (strncmp (argv
[0], "mappings", strlen (argv
[0])) == 0)
321 else if (strcmp (argv
[0], "status") == 0)
325 else if (strcmp (argv
[0], "stat") == 0)
329 else if (strcmp (argv
[0], "cmd") == 0)
333 else if (strncmp (argv
[0], "exe", strlen (argv
[0])) == 0)
337 else if (strcmp (argv
[0], "cwd") == 0)
341 else if (strncmp (argv
[0], "all", strlen (argv
[0])) == 0)
347 /* [...] (future options here) */
352 error ("No current process: you must name one.");
354 sprintf (fname1
, "/proc/%lld", pid
);
355 if (stat (fname1
, &dummy
) != 0)
356 error ("No /proc directory: '%s'", fname1
);
358 printf_filtered ("process %lld\n", pid
);
359 if (cmdline_f
|| all
)
361 sprintf (fname1
, "/proc/%lld/cmdline", pid
);
362 if ((procfile
= fopen (fname1
, "r")) > 0)
364 fgets (buffer
, sizeof (buffer
), procfile
);
365 printf_filtered ("cmdline = '%s'\n", buffer
);
369 warning ("unable to open /proc file '%s'", fname1
);
373 sprintf (fname1
, "/proc/%lld/cwd", pid
);
374 memset (fname2
, 0, sizeof (fname2
));
375 if (readlink (fname1
, fname2
, sizeof (fname2
)) > 0)
376 printf_filtered ("cwd = '%s'\n", fname2
);
378 warning ("unable to read link '%s'", fname1
);
382 sprintf (fname1
, "/proc/%lld/exe", pid
);
383 memset (fname2
, 0, sizeof (fname2
));
384 if (readlink (fname1
, fname2
, sizeof (fname2
)) > 0)
385 printf_filtered ("exe = '%s'\n", fname2
);
387 warning ("unable to read link '%s'", fname1
);
389 if (mappings_f
|| all
)
391 sprintf (fname1
, "/proc/%lld/maps", pid
);
392 if ((procfile
= fopen (fname1
, "r")) > 0)
394 long long addr
, endaddr
, size
, offset
, inode
;
395 char permissions
[8], device
[8], filename
[MAXPATHLEN
];
396 char *header_fmt_string
, *data_fmt_string
;
398 if (TARGET_ADDR_BIT
== 32)
400 header_fmt_string
= "\t%10s %10s %10s %10s %7s\n";
401 data_fmt_string
= "\t%#10lx %#10lx %#10x %#10x %7s\n";
405 header_fmt_string
= " %18s %18s %10s %10s %7s\n";
406 data_fmt_string
= " %#18lx %#18lx %#10x %#10x %7s\n";
409 printf_filtered ("Mapped address spaces:\n\n");
410 printf_filtered (header_fmt_string
,
417 while (read_mapping (procfile
, &addr
, &endaddr
, &permissions
[0],
418 &offset
, &device
[0], &inode
, &filename
[0]))
420 size
= endaddr
- addr
;
421 printf_filtered (data_fmt_string
,
422 (unsigned long) addr
, /* FIXME: pr_addr */
423 (unsigned long) endaddr
,
425 (unsigned int) offset
,
426 filename
[0] ? filename
: "");
433 warning ("unable to open /proc file '%s'", fname1
);
437 sprintf (fname1
, "/proc/%lld/status", pid
);
438 if ((procfile
= fopen (fname1
, "r")) > 0)
440 while (fgets (buffer
, sizeof (buffer
), procfile
) != NULL
)
441 printf_filtered (buffer
);
445 warning ("unable to open /proc file '%s'", fname1
);
449 sprintf (fname1
, "/proc/%lld/stat", pid
);
450 if ((procfile
= fopen (fname1
, "r")) > 0)
455 if (fscanf (procfile
, "%d ", &itmp
) > 0)
456 printf_filtered ("Process: %d\n", itmp
);
457 if (fscanf (procfile
, "%s ", &buffer
[0]) > 0)
458 printf_filtered ("Exec file: %s\n", buffer
);
459 if (fscanf (procfile
, "%c ", &ctmp
) > 0)
460 printf_filtered ("State: %c\n", ctmp
);
461 if (fscanf (procfile
, "%d ", &itmp
) > 0)
462 printf_filtered ("Parent process: %d\n", itmp
);
463 if (fscanf (procfile
, "%d ", &itmp
) > 0)
464 printf_filtered ("Process group: %d\n", itmp
);
465 if (fscanf (procfile
, "%d ", &itmp
) > 0)
466 printf_filtered ("Session id: %d\n", itmp
);
467 if (fscanf (procfile
, "%d ", &itmp
) > 0)
468 printf_filtered ("TTY: %d\n", itmp
);
469 if (fscanf (procfile
, "%d ", &itmp
) > 0)
470 printf_filtered ("TTY owner process group: %d\n", itmp
);
471 if (fscanf (procfile
, "%u ", &itmp
) > 0)
472 printf_filtered ("Flags: 0x%x\n", itmp
);
473 if (fscanf (procfile
, "%u ", &itmp
) > 0)
474 printf_filtered ("Minor faults (no memory page): %u\n",
475 (unsigned int) itmp
);
476 if (fscanf (procfile
, "%u ", &itmp
) > 0)
477 printf_filtered ("Minor faults, children: %u\n",
478 (unsigned int) itmp
);
479 if (fscanf (procfile
, "%u ", &itmp
) > 0)
480 printf_filtered ("Major faults (memory page faults): %u\n",
481 (unsigned int) itmp
);
482 if (fscanf (procfile
, "%u ", &itmp
) > 0)
483 printf_filtered ("Major faults, children: %u\n",
484 (unsigned int) itmp
);
485 if (fscanf (procfile
, "%d ", &itmp
) > 0)
486 printf_filtered ("utime: %d\n", itmp
);
487 if (fscanf (procfile
, "%d ", &itmp
) > 0)
488 printf_filtered ("stime: %d\n", itmp
);
489 if (fscanf (procfile
, "%d ", &itmp
) > 0)
490 printf_filtered ("utime, children: %d\n", itmp
);
491 if (fscanf (procfile
, "%d ", &itmp
) > 0)
492 printf_filtered ("stime, children: %d\n", itmp
);
493 if (fscanf (procfile
, "%d ", &itmp
) > 0)
494 printf_filtered ("jiffies remaining in current time slice: %d\n",
496 if (fscanf (procfile
, "%d ", &itmp
) > 0)
497 printf_filtered ("'nice' value: %d\n", itmp
);
498 if (fscanf (procfile
, "%u ", &itmp
) > 0)
499 printf_filtered ("jiffies until next timeout: %u\n",
500 (unsigned int) itmp
);
501 if (fscanf (procfile
, "%u ", &itmp
) > 0)
502 printf_filtered ("jiffies until next SIGALRM: %u\n",
503 (unsigned int) itmp
);
504 if (fscanf (procfile
, "%d ", &itmp
) > 0)
505 printf_filtered ("start time (jiffies since system boot): %d\n",
507 if (fscanf (procfile
, "%u ", &itmp
) > 0)
508 printf_filtered ("Virtual memory size: %u\n",
509 (unsigned int) itmp
);
510 if (fscanf (procfile
, "%u ", &itmp
) > 0)
511 printf_filtered ("Resident set size: %u\n",
512 (unsigned int) itmp
);
513 if (fscanf (procfile
, "%u ", &itmp
) > 0)
514 printf_filtered ("rlim: %u\n",
515 (unsigned int) itmp
);
516 if (fscanf (procfile
, "%u ", &itmp
) > 0)
517 printf_filtered ("Start of text: 0x%x\n", itmp
);
518 if (fscanf (procfile
, "%u ", &itmp
) > 0)
519 printf_filtered ("End of text: 0x%x\n", itmp
);
520 if (fscanf (procfile
, "%u ", &itmp
) > 0)
521 printf_filtered ("Start of stack: 0x%x\n", itmp
);
522 #if 0 /* Don't know how architecture-dependent the rest is...
523 Anyway the signal bitmap info is available from "status". */
524 if (fscanf (procfile
, "%u ", &itmp
) > 0) /* FIXME arch? */
525 printf_filtered ("Kernel stack pointer: 0x%x\n", itmp
);
526 if (fscanf (procfile
, "%u ", &itmp
) > 0) /* FIXME arch? */
527 printf_filtered ("Kernel instr pointer: 0x%x\n", itmp
);
528 if (fscanf (procfile
, "%d ", &itmp
) > 0)
529 printf_filtered ("Pending signals bitmap: 0x%x\n", itmp
);
530 if (fscanf (procfile
, "%d ", &itmp
) > 0)
531 printf_filtered ("Blocked signals bitmap: 0x%x\n", itmp
);
532 if (fscanf (procfile
, "%d ", &itmp
) > 0)
533 printf_filtered ("Ignored signals bitmap: 0x%x\n", itmp
);
534 if (fscanf (procfile
, "%d ", &itmp
) > 0)
535 printf_filtered ("Catched signals bitmap: 0x%x\n", itmp
);
536 if (fscanf (procfile
, "%u ", &itmp
) > 0) /* FIXME arch? */
537 printf_filtered ("wchan (system call): 0x%x\n", itmp
);
542 warning ("unable to open /proc file '%s'", fname1
);
547 _initialize_linux_proc (void)
549 extern void inftarg_set_find_memory_regions ();
550 extern void inftarg_set_make_corefile_notes ();
552 inftarg_set_find_memory_regions (linux_find_memory_regions
);
553 inftarg_set_make_corefile_notes (linux_make_note_section
);
555 add_info ("proc", linux_info_proc_cmd
,
556 "Show /proc process information about any running process.\n\
557 Specify any process id, or use the program being debugged by default.\n\
558 Specify any of the following keywords for detailed info:\n\
559 mappings -- list of mapped memory regions.\n\
560 stat -- list a bunch of random process info.\n\
561 status -- list a different bunch of random process info.\n\
562 all -- list all available /proc info.");