utils.c (puts_filtered_tabular): New function.
[deliverable/binutils-gdb.git] / gdb / linux-proc.c
1 /* GNU/Linux specific methods for using the /proc file system.
2
3 Copyright 2001, 2002 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
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.
11
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.
16
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. */
21
22 #include "defs.h"
23 #include "inferior.h"
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"
35
36 /* Function: child_pid_to_exec_file
37 *
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.
41 */
42
43 char *
44 child_pid_to_exec_file (int pid)
45 {
46 char *name1, *name2;
47
48 name1 = xmalloc (MAXPATHLEN);
49 name2 = xmalloc (MAXPATHLEN);
50 make_cleanup (xfree, name1);
51 make_cleanup (xfree, name2);
52 memset (name2, 0, MAXPATHLEN);
53
54 sprintf (name1, "/proc/%d/exe", pid);
55 if (readlink (name1, name2, MAXPATHLEN) > 0)
56 return name2;
57 else
58 return name1;
59 }
60
61 /* Function: read_mappings
62 *
63 * Service function for corefiles and info proc.
64 */
65
66 static int
67 read_mapping (FILE *mapfile,
68 long long *addr,
69 long long *endaddr,
70 char *permissions,
71 long long *offset,
72 char *device,
73 long long *inode,
74 char *filename)
75 {
76 int ret = fscanf (mapfile, "%llx-%llx %s %llx %s %llx",
77 addr, endaddr, permissions, offset, device, inode);
78
79 if (ret > 0 && ret != EOF && *inode != 0)
80 {
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
85 filename.
86
87 Note the filename is used for informational purposes only. */
88 ret += fscanf (mapfile, "%[^\n]\n", filename);
89 }
90 else
91 {
92 filename[0] = '\0'; /* no filename */
93 fscanf (mapfile, "\n");
94 }
95 return (ret != 0 && ret != EOF);
96 }
97
98 /* Function: linux_find_memory_regions
99 *
100 * Fills the "to_find_memory_regions" target vector.
101 * Lists the memory regions in the inferior for a corefile.
102 */
103
104 static int
105 linux_find_memory_regions (int (*func) (CORE_ADDR,
106 unsigned long,
107 int, int, int,
108 void *),
109 void *obfd)
110 {
111 long long pid = PIDGET (inferior_ptid);
112 char mapsfilename[MAXPATHLEN];
113 FILE *mapsfile;
114 long long addr, endaddr, size, offset, inode;
115 char permissions[8], device[8], filename[MAXPATHLEN];
116 int read, write, exec;
117 int ret;
118
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);
123
124 if (info_verbose)
125 fprintf_filtered (gdb_stdout,
126 "Reading memory regions from %s\n", mapsfilename);
127
128 /* Now iterate until end-of-file. */
129 while (read_mapping (mapsfile, &addr, &endaddr, &permissions[0],
130 &offset, &device[0], &inode, &filename[0]))
131 {
132 size = endaddr - addr;
133
134 /* Get the segment's permissions. */
135 read = (strchr (permissions, 'r') != 0);
136 write = (strchr (permissions, 'w') != 0);
137 exec = (strchr (permissions, 'x') != 0);
138
139 if (info_verbose)
140 {
141 fprintf_filtered (gdb_stdout,
142 "Save segment, %lld bytes at 0x%s (%c%c%c)",
143 size, paddr_nz (addr),
144 read ? 'r' : ' ',
145 write ? 'w' : ' ',
146 exec ? 'x' : ' ');
147 if (filename && filename[0])
148 fprintf_filtered (gdb_stdout,
149 " for %s", filename);
150 fprintf_filtered (gdb_stdout, "\n");
151 }
152
153 /* Invoke the callback function to create the corefile segment. */
154 func (addr, size, read, write, exec, obfd);
155 }
156 fclose (mapsfile);
157 return 0;
158 }
159
160 /* Function: linux_do_thread_registers
161 *
162 * Records the thread's register state for the corefile note section.
163 */
164
165 static char *
166 linux_do_thread_registers (bfd *obfd, ptid_t ptid,
167 char *note_data, int *note_size)
168 {
169 gdb_gregset_t gregs;
170 gdb_fpregset_t fpregs;
171 #ifdef FILL_FPXREGSET
172 gdb_fpxregset_t fpxregs;
173 #endif
174 unsigned long merged_pid = ptid_get_tid (ptid) << 16 | ptid_get_pid (ptid);
175
176 fill_gregset (&gregs, -1);
177 note_data = (char *) elfcore_write_prstatus (obfd,
178 note_data,
179 note_size,
180 merged_pid,
181 stop_signal,
182 &gregs);
183
184 fill_fpregset (&fpregs, -1);
185 note_data = (char *) elfcore_write_prfpreg (obfd,
186 note_data,
187 note_size,
188 &fpregs,
189 sizeof (fpregs));
190 #ifdef FILL_FPXREGSET
191 fill_fpxregset (&fpxregs, -1);
192 note_data = (char *) elfcore_write_prxfpreg (obfd,
193 note_data,
194 note_size,
195 &fpxregs,
196 sizeof (fpxregs));
197 #endif
198 return note_data;
199 }
200
201 struct linux_corefile_thread_data
202 {
203 bfd *obfd;
204 char *note_data;
205 int *note_size;
206 int num_notes;
207 };
208
209 /* Function: linux_corefile_thread_callback
210 *
211 * Called by gdbthread.c once per thread.
212 * Records the thread's register state for the corefile note section.
213 */
214
215 static int
216 linux_corefile_thread_callback (struct thread_info *ti, void *data)
217 {
218 struct linux_corefile_thread_data *args = data;
219 ptid_t saved_ptid = inferior_ptid;
220
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,
226 ti->ptid,
227 args->note_data,
228 args->note_size);
229 args->num_notes++;
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. */
234 return 0;
235 }
236
237 /* Function: linux_make_note_section
238 *
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.
242 */
243
244 static char *
245 linux_make_note_section (bfd *obfd, int *note_size)
246 {
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;
253
254 if (get_exec_file (0))
255 {
256 strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname));
257 strncpy (psargs, get_exec_file (0),
258 sizeof (psargs));
259 if (get_inferior_args ())
260 {
261 strncat (psargs, " ",
262 sizeof (psargs) - strlen (psargs));
263 strncat (psargs, get_inferior_args (),
264 sizeof (psargs) - strlen (psargs));
265 }
266 note_data = (char *) elfcore_write_prpsinfo (obfd,
267 note_data,
268 note_size,
269 fname,
270 psargs);
271 }
272
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)
280 {
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);
285 }
286 else
287 {
288 note_data = thread_args.note_data;
289 }
290
291 make_cleanup (xfree, note_data);
292 return note_data;
293 }
294
295 /*
296 * Function: linux_info_proc_cmd
297 *
298 * Implement the "info proc" command.
299 */
300
301 static void
302 linux_info_proc_cmd (char *args, int from_tty)
303 {
304 long long pid = PIDGET (inferior_ptid);
305 FILE *procfile;
306 char **argv = NULL;
307 char buffer[MAXPATHLEN];
308 char fname1[MAXPATHLEN], fname2[MAXPATHLEN];
309 int cmdline_f = 1;
310 int cwd_f = 1;
311 int exe_f = 1;
312 int mappings_f = 0;
313 int environ_f = 0;
314 int status_f = 0;
315 int stat_f = 0;
316 int all = 0;
317 struct stat dummy;
318
319 if (args)
320 {
321 /* Break up 'args' into an argv array. */
322 if ((argv = buildargv (args)) == NULL)
323 nomem (0);
324 else
325 make_cleanup_freeargv (argv);
326 }
327 while (argv != NULL && *argv != NULL)
328 {
329 if (isdigit (argv[0][0]))
330 {
331 pid = strtoul (argv[0], NULL, 10);
332 }
333 else if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0)
334 {
335 mappings_f = 1;
336 }
337 else if (strcmp (argv[0], "status") == 0)
338 {
339 status_f = 1;
340 }
341 else if (strcmp (argv[0], "stat") == 0)
342 {
343 stat_f = 1;
344 }
345 else if (strcmp (argv[0], "cmd") == 0)
346 {
347 cmdline_f = 1;
348 }
349 else if (strncmp (argv[0], "exe", strlen (argv[0])) == 0)
350 {
351 exe_f = 1;
352 }
353 else if (strcmp (argv[0], "cwd") == 0)
354 {
355 cwd_f = 1;
356 }
357 else if (strncmp (argv[0], "all", strlen (argv[0])) == 0)
358 {
359 all = 1;
360 }
361 else
362 {
363 /* [...] (future options here) */
364 }
365 argv++;
366 }
367 if (pid == 0)
368 error ("No current process: you must name one.");
369
370 sprintf (fname1, "/proc/%lld", pid);
371 if (stat (fname1, &dummy) != 0)
372 error ("No /proc directory: '%s'", fname1);
373
374 printf_filtered ("process %lld\n", pid);
375 if (cmdline_f || all)
376 {
377 sprintf (fname1, "/proc/%lld/cmdline", pid);
378 if ((procfile = fopen (fname1, "r")) > 0)
379 {
380 fgets (buffer, sizeof (buffer), procfile);
381 printf_filtered ("cmdline = '%s'\n", buffer);
382 fclose (procfile);
383 }
384 else
385 warning ("unable to open /proc file '%s'", fname1);
386 }
387 if (cwd_f || all)
388 {
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);
393 else
394 warning ("unable to read link '%s'", fname1);
395 }
396 if (exe_f || all)
397 {
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);
402 else
403 warning ("unable to read link '%s'", fname1);
404 }
405 if (mappings_f || all)
406 {
407 sprintf (fname1, "/proc/%lld/maps", pid);
408 if ((procfile = fopen (fname1, "r")) > 0)
409 {
410 long long addr, endaddr, size, offset, inode;
411 char permissions[8], device[8], filename[MAXPATHLEN];
412 char *header_fmt_string, *data_fmt_string;
413
414 if (TARGET_ADDR_BIT == 32)
415 {
416 header_fmt_string = "\t%10s %10s %10s %10s %7s\n";
417 data_fmt_string = "\t%#10lx %#10lx %#10x %#10x %7s\n";
418 }
419 else
420 {
421 header_fmt_string = " %18s %18s %10s %10s %7s\n";
422 data_fmt_string = " %#18lx %#18lx %#10x %#10x %7s\n";
423 }
424
425 printf_filtered ("Mapped address spaces:\n\n");
426 printf_filtered (header_fmt_string,
427 "Start Addr",
428 " End Addr",
429 " Size",
430 " Offset",
431 "objfile");
432
433 while (read_mapping (procfile, &addr, &endaddr, &permissions[0],
434 &offset, &device[0], &inode, &filename[0]))
435 {
436 size = endaddr - addr;
437 printf_filtered (data_fmt_string,
438 (unsigned long) addr, /* FIXME: pr_addr */
439 (unsigned long) endaddr,
440 (int) size,
441 (unsigned int) offset,
442 filename[0] ? filename : "");
443
444 }
445
446 fclose (procfile);
447 }
448 else
449 warning ("unable to open /proc file '%s'", fname1);
450 }
451 if (status_f || all)
452 {
453 sprintf (fname1, "/proc/%lld/status", pid);
454 if ((procfile = fopen (fname1, "r")) > 0)
455 {
456 while (fgets (buffer, sizeof (buffer), procfile) != NULL)
457 printf_filtered (buffer);
458 fclose (procfile);
459 }
460 else
461 warning ("unable to open /proc file '%s'", fname1);
462 }
463 if (stat_f || all)
464 {
465 sprintf (fname1, "/proc/%lld/stat", pid);
466 if ((procfile = fopen (fname1, "r")) > 0)
467 {
468 int itmp;
469 char ctmp;
470
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",
511 itmp);
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",
522 itmp);
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);
554 #endif
555 fclose (procfile);
556 }
557 else
558 warning ("unable to open /proc file '%s'", fname1);
559 }
560 }
561
562 void
563 _initialize_linux_proc (void)
564 {
565 extern void inftarg_set_find_memory_regions ();
566 extern void inftarg_set_make_corefile_notes ();
567
568 inftarg_set_find_memory_regions (linux_find_memory_regions);
569 inftarg_set_make_corefile_notes (linux_make_note_section);
570
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.");
579 }
This page took 0.043155 seconds and 4 git commands to generate.