* ld.h: Fix formatting.
[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
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 */
41
42 char *
43 child_pid_to_exec_file (int pid)
44 {
45 char *name1, *name2;
46
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;
58 }
59
60 /* Function: read_mappings
61 *
62 * Service function for corefiles and info proc.
63 */
64
65 static int
66 read_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 {
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);
88 }
89 else
90 {
91 filename[0] = '\0'; /* no filename */
92 fscanf (mapfile, "\n");
93 }
94 return (ret != 0 && ret != EOF);
95 }
96
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
103 static int
104 linux_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);
111 char mapsfilename[MAXPATHLEN];
112 FILE *mapsfile;
113 long long addr, endaddr, size, offset, inode;
114 char permissions[8], device[8], filename[MAXPATHLEN];
115 int read, write, exec;
116 int ret;
117
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);
122
123 if (info_verbose)
124 fprintf_filtered (gdb_stdout,
125 "Reading memory regions from %s\n", mapsfilename);
126
127 /* Now iterate until end-of-file. */
128 while (read_mapping (mapsfile, &addr, &endaddr, &permissions[0],
129 &offset, &device[0], &inode, &filename[0]))
130 {
131 size = endaddr - addr;
132
133 /* Get the segment's permissions. */
134 read = (strchr (permissions, 'r') != 0);
135 write = (strchr (permissions, 'w') != 0);
136 exec = (strchr (permissions, 'x') != 0);
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);
154 }
155 fclose (mapsfile);
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
164 static char *
165 linux_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;
170 #ifdef FILL_FPXREGSET
171 gdb_fpxregset_t fpxregs;
172 #endif
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));
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
197 return note_data;
198 }
199
200 struct 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
212 static int
213 linux_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
240 static char *
241 linux_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
290 /*
291 * Function: linux_info_proc_cmd
292 *
293 * Implement the "info proc" command.
294 */
295
296 static void
297 linux_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
557 void
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);
565
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.");
574 }
This page took 0.041214 seconds and 4 git commands to generate.