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