2003-01-27 Andrew Cagney <ac131313@redhat.com>
[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 */
eb784848
DJ
28#include <unistd.h> /* for open, pread64 */
29#include <fcntl.h> /* for O_RDONLY */
1e4d76e7 30#include "regcache.h" /* for registers_changed */
be4d1333
MS
31#include "gregset.h" /* for gregset */
32#include "gdbcore.h" /* for get_exec_file */
33#include "gdbthread.h" /* for struct thread_info etc. */
2bf543a6
MS
34#include "elf-bfd.h" /* for elfcore_write_* */
35#include "cli/cli-decode.h" /* for add_info */
ff5922b5 36#include "gdb_string.h"
be4d1333 37
eb784848
DJ
38#ifndef O_LARGEFILE
39#define O_LARGEFILE 0
40#endif
41
be4d1333
MS
42/* Function: child_pid_to_exec_file
43 *
44 * Accepts an integer pid
45 * Returns a string representing a file that can be opened
46 * to get the symbols for the child process.
47 */
4b09dc8c
MS
48
49char *
50child_pid_to_exec_file (int pid)
51{
145fdc6e 52 char *name1, *name2;
4b09dc8c 53
145fdc6e
MS
54 name1 = xmalloc (MAXPATHLEN);
55 name2 = xmalloc (MAXPATHLEN);
56 make_cleanup (xfree, name1);
57 make_cleanup (xfree, name2);
58 memset (name2, 0, MAXPATHLEN);
59
60 sprintf (name1, "/proc/%d/exe", pid);
61 if (readlink (name1, name2, MAXPATHLEN) > 0)
62 return name2;
63 else
64 return name1;
4b09dc8c 65}
be4d1333 66
2bf543a6
MS
67/* Function: read_mappings
68 *
69 * Service function for corefiles and info proc.
70 */
71
72static int
73read_mapping (FILE *mapfile,
74 long long *addr,
75 long long *endaddr,
76 char *permissions,
77 long long *offset,
78 char *device,
79 long long *inode,
80 char *filename)
81{
82 int ret = fscanf (mapfile, "%llx-%llx %s %llx %s %llx",
83 addr, endaddr, permissions, offset, device, inode);
84
85 if (ret > 0 && ret != EOF && *inode != 0)
86 {
ee677e8d
MS
87 /* Eat everything up to EOL for the filename. This will prevent
88 weird filenames (such as one with embedded whitespace) from
89 confusing this code. It also makes this code more robust
90 in respect to annotations the kernel may add after the
91 filename.
92
93 Note the filename is used for informational purposes only. */
94 ret += fscanf (mapfile, "%[^\n]\n", filename);
2bf543a6
MS
95 }
96 else
97 {
98 filename[0] = '\0'; /* no filename */
99 fscanf (mapfile, "\n");
100 }
101 return (ret != 0 && ret != EOF);
102}
103
be4d1333
MS
104/* Function: linux_find_memory_regions
105 *
106 * Fills the "to_find_memory_regions" target vector.
107 * Lists the memory regions in the inferior for a corefile.
108 */
109
110static int
111linux_find_memory_regions (int (*func) (CORE_ADDR,
112 unsigned long,
113 int, int, int,
114 void *),
115 void *obfd)
116{
117 long long pid = PIDGET (inferior_ptid);
2bf543a6
MS
118 char mapsfilename[MAXPATHLEN];
119 FILE *mapsfile;
be4d1333 120 long long addr, endaddr, size, offset, inode;
2bf543a6 121 char permissions[8], device[8], filename[MAXPATHLEN];
be4d1333
MS
122 int read, write, exec;
123 int ret;
124
125 /* Compose the filename for the /proc memory map, and open it. */
2bf543a6
MS
126 sprintf (mapsfilename, "/proc/%lld/maps", pid);
127 if ((mapsfile = fopen (mapsfilename, "r")) == NULL)
128 error ("Could not open %s\n", mapsfilename);
be4d1333
MS
129
130 if (info_verbose)
131 fprintf_filtered (gdb_stdout,
2bf543a6 132 "Reading memory regions from %s\n", mapsfilename);
be4d1333
MS
133
134 /* Now iterate until end-of-file. */
2bf543a6
MS
135 while (read_mapping (mapsfile, &addr, &endaddr, &permissions[0],
136 &offset, &device[0], &inode, &filename[0]))
be4d1333
MS
137 {
138 size = endaddr - addr;
139
140 /* Get the segment's permissions. */
2bf543a6
MS
141 read = (strchr (permissions, 'r') != 0);
142 write = (strchr (permissions, 'w') != 0);
143 exec = (strchr (permissions, 'x') != 0);
be4d1333
MS
144
145 if (info_verbose)
146 {
147 fprintf_filtered (gdb_stdout,
148 "Save segment, %lld bytes at 0x%s (%c%c%c)",
149 size, paddr_nz (addr),
150 read ? 'r' : ' ',
151 write ? 'w' : ' ',
152 exec ? 'x' : ' ');
153 if (filename && filename[0])
154 fprintf_filtered (gdb_stdout,
155 " for %s", filename);
156 fprintf_filtered (gdb_stdout, "\n");
157 }
158
159 /* Invoke the callback function to create the corefile segment. */
160 func (addr, size, read, write, exec, obfd);
be4d1333 161 }
2bf543a6 162 fclose (mapsfile);
be4d1333
MS
163 return 0;
164}
165
166/* Function: linux_do_thread_registers
167 *
168 * Records the thread's register state for the corefile note section.
169 */
170
171static char *
172linux_do_thread_registers (bfd *obfd, ptid_t ptid,
173 char *note_data, int *note_size)
174{
175 gdb_gregset_t gregs;
176 gdb_fpregset_t fpregs;
32872fa7
DJ
177#ifdef FILL_FPXREGSET
178 gdb_fpxregset_t fpxregs;
179#endif
be4d1333
MS
180 unsigned long merged_pid = ptid_get_tid (ptid) << 16 | ptid_get_pid (ptid);
181
182 fill_gregset (&gregs, -1);
183 note_data = (char *) elfcore_write_prstatus (obfd,
184 note_data,
185 note_size,
186 merged_pid,
187 stop_signal,
188 &gregs);
189
190 fill_fpregset (&fpregs, -1);
191 note_data = (char *) elfcore_write_prfpreg (obfd,
192 note_data,
193 note_size,
194 &fpregs,
195 sizeof (fpregs));
32872fa7
DJ
196#ifdef FILL_FPXREGSET
197 fill_fpxregset (&fpxregs, -1);
198 note_data = (char *) elfcore_write_prxfpreg (obfd,
199 note_data,
200 note_size,
201 &fpxregs,
202 sizeof (fpxregs));
203#endif
be4d1333
MS
204 return note_data;
205}
206
8acc2935
MK
207struct linux_corefile_thread_data
208{
209 bfd *obfd;
be4d1333 210 char *note_data;
8acc2935
MK
211 int *note_size;
212 int num_notes;
be4d1333
MS
213};
214
215/* Function: linux_corefile_thread_callback
216 *
217 * Called by gdbthread.c once per thread.
218 * Records the thread's register state for the corefile note section.
219 */
220
221static int
222linux_corefile_thread_callback (struct thread_info *ti, void *data)
223{
224 struct linux_corefile_thread_data *args = data;
225 ptid_t saved_ptid = inferior_ptid;
226
227 inferior_ptid = ti->ptid;
228 registers_changed ();
229 target_fetch_registers (-1); /* FIXME should not be necessary;
230 fill_gregset should do it automatically. */
231 args->note_data = linux_do_thread_registers (args->obfd,
232 ti->ptid,
233 args->note_data,
234 args->note_size);
8acc2935 235 args->num_notes++;
be4d1333
MS
236 inferior_ptid = saved_ptid;
237 registers_changed ();
238 target_fetch_registers (-1); /* FIXME should not be necessary;
239 fill_gregset should do it automatically. */
240 return 0;
241}
242
243/* Function: linux_make_note_section
244 *
245 * Fills the "to_make_corefile_note" target vector.
246 * Builds the note section for a corefile, and returns it
247 * in a malloc buffer.
248 */
249
250static char *
251linux_make_note_section (bfd *obfd, int *note_size)
252{
253 struct linux_corefile_thread_data thread_args;
254 struct cleanup *old_chain;
255 char fname[16] = {'\0'};
256 char psargs[80] = {'\0'};
257 char *note_data = NULL;
258 ptid_t current_ptid = inferior_ptid;
259
260 if (get_exec_file (0))
261 {
262 strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname));
263 strncpy (psargs, get_exec_file (0),
264 sizeof (psargs));
265 if (get_inferior_args ())
266 {
267 strncat (psargs, " ",
268 sizeof (psargs) - strlen (psargs));
269 strncat (psargs, get_inferior_args (),
270 sizeof (psargs) - strlen (psargs));
271 }
272 note_data = (char *) elfcore_write_prpsinfo (obfd,
273 note_data,
274 note_size,
275 fname,
276 psargs);
277 }
278
279 /* Dump information for threads. */
280 thread_args.obfd = obfd;
281 thread_args.note_data = note_data;
282 thread_args.note_size = note_size;
8acc2935 283 thread_args.num_notes = 0;
be4d1333 284 iterate_over_threads (linux_corefile_thread_callback, &thread_args);
8acc2935 285 if (thread_args.num_notes == 0)
be4d1333
MS
286 {
287 /* iterate_over_threads didn't come up with any threads;
8acc2935 288 just use inferior_ptid. */
be4d1333
MS
289 note_data = linux_do_thread_registers (obfd, inferior_ptid,
290 note_data, note_size);
291 }
292 else
293 {
294 note_data = thread_args.note_data;
295 }
296
297 make_cleanup (xfree, note_data);
298 return note_data;
299}
300
2bf543a6
MS
301/*
302 * Function: linux_info_proc_cmd
303 *
304 * Implement the "info proc" command.
305 */
306
307static void
308linux_info_proc_cmd (char *args, int from_tty)
309{
310 long long pid = PIDGET (inferior_ptid);
311 FILE *procfile;
312 char **argv = NULL;
313 char buffer[MAXPATHLEN];
314 char fname1[MAXPATHLEN], fname2[MAXPATHLEN];
315 int cmdline_f = 1;
316 int cwd_f = 1;
317 int exe_f = 1;
318 int mappings_f = 0;
319 int environ_f = 0;
320 int status_f = 0;
321 int stat_f = 0;
322 int all = 0;
323 struct stat dummy;
324
325 if (args)
326 {
327 /* Break up 'args' into an argv array. */
328 if ((argv = buildargv (args)) == NULL)
329 nomem (0);
330 else
331 make_cleanup_freeargv (argv);
332 }
333 while (argv != NULL && *argv != NULL)
334 {
335 if (isdigit (argv[0][0]))
336 {
337 pid = strtoul (argv[0], NULL, 10);
338 }
339 else if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0)
340 {
341 mappings_f = 1;
342 }
343 else if (strcmp (argv[0], "status") == 0)
344 {
345 status_f = 1;
346 }
347 else if (strcmp (argv[0], "stat") == 0)
348 {
349 stat_f = 1;
350 }
351 else if (strcmp (argv[0], "cmd") == 0)
352 {
353 cmdline_f = 1;
354 }
355 else if (strncmp (argv[0], "exe", strlen (argv[0])) == 0)
356 {
357 exe_f = 1;
358 }
359 else if (strcmp (argv[0], "cwd") == 0)
360 {
361 cwd_f = 1;
362 }
363 else if (strncmp (argv[0], "all", strlen (argv[0])) == 0)
364 {
365 all = 1;
366 }
367 else
368 {
369 /* [...] (future options here) */
370 }
371 argv++;
372 }
373 if (pid == 0)
374 error ("No current process: you must name one.");
375
376 sprintf (fname1, "/proc/%lld", pid);
377 if (stat (fname1, &dummy) != 0)
378 error ("No /proc directory: '%s'", fname1);
379
380 printf_filtered ("process %lld\n", pid);
381 if (cmdline_f || all)
382 {
383 sprintf (fname1, "/proc/%lld/cmdline", pid);
384 if ((procfile = fopen (fname1, "r")) > 0)
385 {
386 fgets (buffer, sizeof (buffer), procfile);
387 printf_filtered ("cmdline = '%s'\n", buffer);
388 fclose (procfile);
389 }
390 else
391 warning ("unable to open /proc file '%s'", fname1);
392 }
393 if (cwd_f || all)
394 {
395 sprintf (fname1, "/proc/%lld/cwd", pid);
396 memset (fname2, 0, sizeof (fname2));
397 if (readlink (fname1, fname2, sizeof (fname2)) > 0)
398 printf_filtered ("cwd = '%s'\n", fname2);
399 else
400 warning ("unable to read link '%s'", fname1);
401 }
402 if (exe_f || all)
403 {
404 sprintf (fname1, "/proc/%lld/exe", pid);
405 memset (fname2, 0, sizeof (fname2));
406 if (readlink (fname1, fname2, sizeof (fname2)) > 0)
407 printf_filtered ("exe = '%s'\n", fname2);
408 else
409 warning ("unable to read link '%s'", fname1);
410 }
411 if (mappings_f || all)
412 {
413 sprintf (fname1, "/proc/%lld/maps", pid);
414 if ((procfile = fopen (fname1, "r")) > 0)
415 {
416 long long addr, endaddr, size, offset, inode;
417 char permissions[8], device[8], filename[MAXPATHLEN];
418 char *header_fmt_string, *data_fmt_string;
419
420 if (TARGET_ADDR_BIT == 32)
421 {
422 header_fmt_string = "\t%10s %10s %10s %10s %7s\n";
423 data_fmt_string = "\t%#10lx %#10lx %#10x %#10x %7s\n";
424 }
425 else
426 {
427 header_fmt_string = " %18s %18s %10s %10s %7s\n";
428 data_fmt_string = " %#18lx %#18lx %#10x %#10x %7s\n";
429 }
430
431 printf_filtered ("Mapped address spaces:\n\n");
432 printf_filtered (header_fmt_string,
433 "Start Addr",
434 " End Addr",
435 " Size",
436 " Offset",
437 "objfile");
438
439 while (read_mapping (procfile, &addr, &endaddr, &permissions[0],
440 &offset, &device[0], &inode, &filename[0]))
441 {
442 size = endaddr - addr;
443 printf_filtered (data_fmt_string,
444 (unsigned long) addr, /* FIXME: pr_addr */
445 (unsigned long) endaddr,
446 (int) size,
447 (unsigned int) offset,
448 filename[0] ? filename : "");
449
450 }
451
452 fclose (procfile);
453 }
454 else
455 warning ("unable to open /proc file '%s'", fname1);
456 }
457 if (status_f || all)
458 {
459 sprintf (fname1, "/proc/%lld/status", pid);
460 if ((procfile = fopen (fname1, "r")) > 0)
461 {
462 while (fgets (buffer, sizeof (buffer), procfile) != NULL)
463 printf_filtered (buffer);
464 fclose (procfile);
465 }
466 else
467 warning ("unable to open /proc file '%s'", fname1);
468 }
469 if (stat_f || all)
470 {
471 sprintf (fname1, "/proc/%lld/stat", pid);
472 if ((procfile = fopen (fname1, "r")) > 0)
473 {
474 int itmp;
475 char ctmp;
476
477 if (fscanf (procfile, "%d ", &itmp) > 0)
478 printf_filtered ("Process: %d\n", itmp);
479 if (fscanf (procfile, "%s ", &buffer[0]) > 0)
480 printf_filtered ("Exec file: %s\n", buffer);
481 if (fscanf (procfile, "%c ", &ctmp) > 0)
482 printf_filtered ("State: %c\n", ctmp);
483 if (fscanf (procfile, "%d ", &itmp) > 0)
484 printf_filtered ("Parent process: %d\n", itmp);
485 if (fscanf (procfile, "%d ", &itmp) > 0)
486 printf_filtered ("Process group: %d\n", itmp);
487 if (fscanf (procfile, "%d ", &itmp) > 0)
488 printf_filtered ("Session id: %d\n", itmp);
489 if (fscanf (procfile, "%d ", &itmp) > 0)
490 printf_filtered ("TTY: %d\n", itmp);
491 if (fscanf (procfile, "%d ", &itmp) > 0)
492 printf_filtered ("TTY owner process group: %d\n", itmp);
493 if (fscanf (procfile, "%u ", &itmp) > 0)
494 printf_filtered ("Flags: 0x%x\n", itmp);
495 if (fscanf (procfile, "%u ", &itmp) > 0)
496 printf_filtered ("Minor faults (no memory page): %u\n",
497 (unsigned int) itmp);
498 if (fscanf (procfile, "%u ", &itmp) > 0)
499 printf_filtered ("Minor faults, children: %u\n",
500 (unsigned int) itmp);
501 if (fscanf (procfile, "%u ", &itmp) > 0)
502 printf_filtered ("Major faults (memory page faults): %u\n",
503 (unsigned int) itmp);
504 if (fscanf (procfile, "%u ", &itmp) > 0)
505 printf_filtered ("Major faults, children: %u\n",
506 (unsigned int) itmp);
507 if (fscanf (procfile, "%d ", &itmp) > 0)
508 printf_filtered ("utime: %d\n", itmp);
509 if (fscanf (procfile, "%d ", &itmp) > 0)
510 printf_filtered ("stime: %d\n", itmp);
511 if (fscanf (procfile, "%d ", &itmp) > 0)
512 printf_filtered ("utime, children: %d\n", itmp);
513 if (fscanf (procfile, "%d ", &itmp) > 0)
514 printf_filtered ("stime, children: %d\n", itmp);
515 if (fscanf (procfile, "%d ", &itmp) > 0)
516 printf_filtered ("jiffies remaining in current time slice: %d\n",
517 itmp);
518 if (fscanf (procfile, "%d ", &itmp) > 0)
519 printf_filtered ("'nice' value: %d\n", itmp);
520 if (fscanf (procfile, "%u ", &itmp) > 0)
521 printf_filtered ("jiffies until next timeout: %u\n",
522 (unsigned int) itmp);
523 if (fscanf (procfile, "%u ", &itmp) > 0)
524 printf_filtered ("jiffies until next SIGALRM: %u\n",
525 (unsigned int) itmp);
526 if (fscanf (procfile, "%d ", &itmp) > 0)
527 printf_filtered ("start time (jiffies since system boot): %d\n",
528 itmp);
529 if (fscanf (procfile, "%u ", &itmp) > 0)
530 printf_filtered ("Virtual memory size: %u\n",
531 (unsigned int) itmp);
532 if (fscanf (procfile, "%u ", &itmp) > 0)
533 printf_filtered ("Resident set size: %u\n",
534 (unsigned int) itmp);
535 if (fscanf (procfile, "%u ", &itmp) > 0)
536 printf_filtered ("rlim: %u\n",
537 (unsigned int) itmp);
538 if (fscanf (procfile, "%u ", &itmp) > 0)
539 printf_filtered ("Start of text: 0x%x\n", itmp);
540 if (fscanf (procfile, "%u ", &itmp) > 0)
541 printf_filtered ("End of text: 0x%x\n", itmp);
542 if (fscanf (procfile, "%u ", &itmp) > 0)
543 printf_filtered ("Start of stack: 0x%x\n", itmp);
544#if 0 /* Don't know how architecture-dependent the rest is...
545 Anyway the signal bitmap info is available from "status". */
546 if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
547 printf_filtered ("Kernel stack pointer: 0x%x\n", itmp);
548 if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
549 printf_filtered ("Kernel instr pointer: 0x%x\n", itmp);
550 if (fscanf (procfile, "%d ", &itmp) > 0)
551 printf_filtered ("Pending signals bitmap: 0x%x\n", itmp);
552 if (fscanf (procfile, "%d ", &itmp) > 0)
553 printf_filtered ("Blocked signals bitmap: 0x%x\n", itmp);
554 if (fscanf (procfile, "%d ", &itmp) > 0)
555 printf_filtered ("Ignored signals bitmap: 0x%x\n", itmp);
556 if (fscanf (procfile, "%d ", &itmp) > 0)
557 printf_filtered ("Catched signals bitmap: 0x%x\n", itmp);
558 if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
559 printf_filtered ("wchan (system call): 0x%x\n", itmp);
560#endif
561 fclose (procfile);
562 }
563 else
564 warning ("unable to open /proc file '%s'", fname1);
565 }
566}
567
be4d1333
MS
568void
569_initialize_linux_proc (void)
570{
571 extern void inftarg_set_find_memory_regions ();
572 extern void inftarg_set_make_corefile_notes ();
573
574 inftarg_set_find_memory_regions (linux_find_memory_regions);
575 inftarg_set_make_corefile_notes (linux_make_note_section);
2bf543a6
MS
576
577 add_info ("proc", linux_info_proc_cmd,
578 "Show /proc process information about any running process.\n\
579Specify any process id, or use the program being debugged by default.\n\
580Specify any of the following keywords for detailed info:\n\
581 mappings -- list of mapped memory regions.\n\
582 stat -- list a bunch of random process info.\n\
583 status -- list a different bunch of random process info.\n\
584 all -- list all available /proc info.");
be4d1333 585}
eb784848
DJ
586
587int linux_proc_xfer_memory (CORE_ADDR addr, char *myaddr, int len, int write,
588 struct mem_attrib *attrib,
589 struct target_ops *target)
590{
591 int fd, ret;
592 char filename[64];
593
594 if (write)
595 return 0;
596
597 /* Don't bother for one word. */
598 if (len < 3 * sizeof (long))
599 return 0;
600
601 /* We could keep this file open and cache it - possibly one
602 per thread. That requires some juggling, but is even faster. */
603 sprintf (filename, "/proc/%d/mem", PIDGET (inferior_ptid));
604 fd = open (filename, O_RDONLY | O_LARGEFILE);
605 if (fd == -1)
606 return 0;
607
608 /* If pread64 is available, use it. It's faster if the kernel
609 supports it (only one syscall), and it's 64-bit safe even
610 on 32-bit platforms (for instance, SPARC debugging a SPARC64
611 application).
612
613 We play some autoconf and CFLAGS games to get this declaration
614 exposed: -D_XOPEN_SOURCE=500 -D_LARGEFILE64_SOURCE. And then
615 a -D_BSD_SOURCE to counteract the defaults for _XOPEN_SOURCE. */
616#ifdef HAVE_PREAD64
617 if (pread64 (fd, myaddr, len, addr) != len)
618#else
619 if (lseek (fd, addr, SEEK_SET) == -1
620 || read (fd, myaddr, len) != len)
621#endif
622 ret = 0;
623 else
624 ret = len;
625
626 close (fd);
627 return ret;
628}
This page took 0.178585 seconds and 4 git commands to generate.