2004-09-13 Andrew Cagney <cagney@gnu.org>
[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"
6949171e
JJ
24#include <sys/param.h> /* for MAXPATHLEN */
25#include <sys/procfs.h> /* for elf_gregset etc. */
26#include "gdb_stat.h" /* for struct stat */
27#include <ctype.h> /* for isdigit */
28#include <unistd.h> /* for open, pread64 */
29#include <fcntl.h> /* for O_RDONLY */
30#include "regcache.h" /* for registers_changed */
31#include "gregset.h" /* for gregset */
32#include "gdbcore.h" /* for get_exec_file */
33#include "gdbthread.h" /* for struct thread_info etc. */
34#include "elf-bfd.h" /* for elfcore_write_* */
2bf543a6 35#include "cli/cli-decode.h" /* for add_info */
ff5922b5 36#include "gdb_string.h"
be4d1333 37
bfb39158
DJ
38#include <signal.h>
39
0274a8ce
MS
40#include "linux-nat.h"
41
eb784848
DJ
42#ifndef O_LARGEFILE
43#define O_LARGEFILE 0
44#endif
45
be4d1333
MS
46/* Function: child_pid_to_exec_file
47 *
48 * Accepts an integer pid
49 * Returns a string representing a file that can be opened
50 * to get the symbols for the child process.
51 */
4b09dc8c
MS
52
53char *
54child_pid_to_exec_file (int pid)
55{
145fdc6e 56 char *name1, *name2;
4b09dc8c 57
145fdc6e
MS
58 name1 = xmalloc (MAXPATHLEN);
59 name2 = xmalloc (MAXPATHLEN);
60 make_cleanup (xfree, name1);
61 make_cleanup (xfree, name2);
62 memset (name2, 0, MAXPATHLEN);
63
64 sprintf (name1, "/proc/%d/exe", pid);
65 if (readlink (name1, name2, MAXPATHLEN) > 0)
66 return name2;
67 else
68 return name1;
4b09dc8c 69}
be4d1333 70
2bf543a6
MS
71/* Function: read_mappings
72 *
73 * Service function for corefiles and info proc.
74 */
75
6949171e
JJ
76static int
77read_mapping (FILE *mapfile,
78 long long *addr,
79 long long *endaddr,
80 char *permissions,
81 long long *offset,
82 char *device, long long *inode, char *filename)
2bf543a6 83{
6949171e 84 int ret = fscanf (mapfile, "%llx-%llx %s %llx %s %llx",
2bf543a6
MS
85 addr, endaddr, permissions, offset, device, inode);
86
87 if (ret > 0 && ret != EOF && *inode != 0)
88 {
ee677e8d 89 /* Eat everything up to EOL for the filename. This will prevent
6949171e
JJ
90 weird filenames (such as one with embedded whitespace) from
91 confusing this code. It also makes this code more robust
92 in respect to annotations the kernel may add after the
93 filename.
ee677e8d 94
6949171e 95 Note the filename is used for informational purposes only. */
ee677e8d 96 ret += fscanf (mapfile, "%[^\n]\n", filename);
2bf543a6
MS
97 }
98 else
99 {
100 filename[0] = '\0'; /* no filename */
101 fscanf (mapfile, "\n");
102 }
103 return (ret != 0 && ret != EOF);
104}
105
be4d1333
MS
106/* Function: linux_find_memory_regions
107 *
108 * Fills the "to_find_memory_regions" target vector.
109 * Lists the memory regions in the inferior for a corefile.
110 */
111
112static int
6949171e 113linux_find_memory_regions (int (*func) (CORE_ADDR,
be4d1333 114 unsigned long,
6949171e 115 int, int, int, void *), void *obfd)
be4d1333
MS
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)
6949171e 131 fprintf_filtered (gdb_stdout,
2bf543a6 132 "Reading memory regions from %s\n", mapsfilename);
be4d1333
MS
133
134 /* Now iterate until end-of-file. */
6949171e 135 while (read_mapping (mapsfile, &addr, &endaddr, &permissions[0],
2bf543a6 136 &offset, &device[0], &inode, &filename[0]))
be4d1333
MS
137 {
138 size = endaddr - addr;
139
140 /* Get the segment's permissions. */
6949171e 141 read = (strchr (permissions, 'r') != 0);
2bf543a6 142 write = (strchr (permissions, 'w') != 0);
6949171e 143 exec = (strchr (permissions, 'x') != 0);
be4d1333
MS
144
145 if (info_verbose)
146 {
6949171e
JJ
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' : ' ', exec ? 'x' : ' ');
be4d1333 152 if (filename && filename[0])
6949171e 153 fprintf_filtered (gdb_stdout, " for %s", filename);
be4d1333
MS
154 fprintf_filtered (gdb_stdout, "\n");
155 }
156
157 /* Invoke the callback function to create the corefile segment. */
158 func (addr, size, read, write, exec, obfd);
be4d1333 159 }
2bf543a6 160 fclose (mapsfile);
be4d1333
MS
161 return 0;
162}
163
164/* Function: linux_do_thread_registers
165 *
166 * Records the thread's register state for the corefile note section.
167 */
168
169static char *
6949171e 170linux_do_thread_registers (bfd *obfd, ptid_t ptid,
be4d1333
MS
171 char *note_data, int *note_size)
172{
173 gdb_gregset_t gregs;
174 gdb_fpregset_t fpregs;
32872fa7
DJ
175#ifdef FILL_FPXREGSET
176 gdb_fpxregset_t fpxregs;
177#endif
0274a8ce 178 unsigned long lwp = ptid_get_lwp (ptid);
be4d1333
MS
179
180 fill_gregset (&gregs, -1);
6949171e
JJ
181 note_data = (char *) elfcore_write_prstatus (obfd,
182 note_data,
183 note_size,
0274a8ce 184 lwp,
6949171e 185 stop_signal, &gregs);
be4d1333
MS
186
187 fill_fpregset (&fpregs, -1);
6949171e
JJ
188 note_data = (char *) elfcore_write_prfpreg (obfd,
189 note_data,
190 note_size,
191 &fpregs, sizeof (fpregs));
32872fa7
DJ
192#ifdef FILL_FPXREGSET
193 fill_fpxregset (&fpxregs, -1);
6949171e
JJ
194 note_data = (char *) elfcore_write_prxfpreg (obfd,
195 note_data,
196 note_size,
197 &fpxregs, sizeof (fpxregs));
32872fa7 198#endif
be4d1333
MS
199 return note_data;
200}
201
8acc2935
MK
202struct linux_corefile_thread_data
203{
204 bfd *obfd;
be4d1333 205 char *note_data;
8acc2935
MK
206 int *note_size;
207 int num_notes;
be4d1333
MS
208};
209
210/* Function: linux_corefile_thread_callback
cbb685f3 211 *
be4d1333
MS
212 * Called by gdbthread.c once per thread.
213 * Records the thread's register state for the corefile note section.
214 */
215
216static int
0274a8ce 217linux_corefile_thread_callback (struct lwp_info *ti, void *data)
be4d1333
MS
218{
219 struct linux_corefile_thread_data *args = data;
220 ptid_t saved_ptid = inferior_ptid;
221
222 inferior_ptid = ti->ptid;
223 registers_changed ();
cbb685f3 224 target_fetch_registers (-1); /* FIXME should not be necessary;
be4d1333 225 fill_gregset should do it automatically. */
6949171e
JJ
226 args->note_data = linux_do_thread_registers (args->obfd,
227 ti->ptid,
228 args->note_data,
be4d1333 229 args->note_size);
8acc2935 230 args->num_notes++;
be4d1333
MS
231 inferior_ptid = saved_ptid;
232 registers_changed ();
cbb685f3 233 target_fetch_registers (-1); /* FIXME should not be necessary;
be4d1333
MS
234 fill_gregset should do it automatically. */
235 return 0;
236}
237
cf50a87a 238/* Function: linux_do_registers
cbb685f3 239 *
cf50a87a
EZ
240 * Records the register state for the corefile note section.
241 */
242
243static char *
244linux_do_registers (bfd *obfd, ptid_t ptid,
245 char *note_data, int *note_size)
246{
247 registers_changed ();
cbb685f3 248 target_fetch_registers (-1); /* FIXME should not be necessary;
cf50a87a
EZ
249 fill_gregset should do it automatically. */
250 return linux_do_thread_registers (obfd,
251 ptid_build (ptid_get_pid (inferior_ptid),
252 ptid_get_pid (inferior_ptid),
253 0),
254 note_data, note_size);
255 return note_data;
256}
257
be4d1333
MS
258/* Function: linux_make_note_section
259 *
260 * Fills the "to_make_corefile_note" target vector.
cbb685f3
RM
261 * Builds the note section for a corefile, and returns it
262 * in a malloc buffer.
be4d1333
MS
263 */
264
265static char *
266linux_make_note_section (bfd *obfd, int *note_size)
267{
268 struct linux_corefile_thread_data thread_args;
269 struct cleanup *old_chain;
6949171e
JJ
270 char fname[16] = { '\0' };
271 char psargs[80] = { '\0' };
be4d1333
MS
272 char *note_data = NULL;
273 ptid_t current_ptid = inferior_ptid;
cbb685f3
RM
274 char *auxv;
275 int auxv_len;
be4d1333
MS
276
277 if (get_exec_file (0))
278 {
279 strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname));
6949171e 280 strncpy (psargs, get_exec_file (0), sizeof (psargs));
be4d1333
MS
281 if (get_inferior_args ())
282 {
6949171e
JJ
283 strncat (psargs, " ", sizeof (psargs) - strlen (psargs));
284 strncat (psargs, get_inferior_args (),
be4d1333
MS
285 sizeof (psargs) - strlen (psargs));
286 }
6949171e
JJ
287 note_data = (char *) elfcore_write_prpsinfo (obfd,
288 note_data,
289 note_size, fname, psargs);
be4d1333
MS
290 }
291
292 /* Dump information for threads. */
293 thread_args.obfd = obfd;
294 thread_args.note_data = note_data;
295 thread_args.note_size = note_size;
8acc2935 296 thread_args.num_notes = 0;
0274a8ce 297 iterate_over_lwps (linux_corefile_thread_callback, &thread_args);
8acc2935 298 if (thread_args.num_notes == 0)
be4d1333
MS
299 {
300 /* iterate_over_threads didn't come up with any threads;
6949171e 301 just use inferior_ptid. */
cf50a87a
EZ
302 note_data = linux_do_registers (obfd, inferior_ptid,
303 note_data, note_size);
be4d1333
MS
304 }
305 else
306 {
307 note_data = thread_args.note_data;
308 }
309
cbb685f3
RM
310 auxv_len = target_auxv_read (&current_target, &auxv);
311 if (auxv_len > 0)
312 {
313 note_data = elfcore_write_note (obfd, note_data, note_size,
314 "CORE", NT_AUXV, auxv, auxv_len);
315 xfree (auxv);
316 }
317
be4d1333
MS
318 make_cleanup (xfree, note_data);
319 return note_data;
320}
321
2bf543a6
MS
322/*
323 * Function: linux_info_proc_cmd
324 *
325 * Implement the "info proc" command.
326 */
327
328static void
329linux_info_proc_cmd (char *args, int from_tty)
330{
331 long long pid = PIDGET (inferior_ptid);
332 FILE *procfile;
333 char **argv = NULL;
334 char buffer[MAXPATHLEN];
335 char fname1[MAXPATHLEN], fname2[MAXPATHLEN];
336 int cmdline_f = 1;
337 int cwd_f = 1;
338 int exe_f = 1;
339 int mappings_f = 0;
340 int environ_f = 0;
341 int status_f = 0;
342 int stat_f = 0;
343 int all = 0;
344 struct stat dummy;
345
346 if (args)
347 {
348 /* Break up 'args' into an argv array. */
349 if ((argv = buildargv (args)) == NULL)
350 nomem (0);
351 else
352 make_cleanup_freeargv (argv);
353 }
354 while (argv != NULL && *argv != NULL)
355 {
356 if (isdigit (argv[0][0]))
357 {
358 pid = strtoul (argv[0], NULL, 10);
359 }
360 else if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0)
361 {
362 mappings_f = 1;
363 }
364 else if (strcmp (argv[0], "status") == 0)
365 {
366 status_f = 1;
367 }
368 else if (strcmp (argv[0], "stat") == 0)
369 {
370 stat_f = 1;
371 }
372 else if (strcmp (argv[0], "cmd") == 0)
373 {
374 cmdline_f = 1;
375 }
376 else if (strncmp (argv[0], "exe", strlen (argv[0])) == 0)
377 {
378 exe_f = 1;
379 }
380 else if (strcmp (argv[0], "cwd") == 0)
381 {
382 cwd_f = 1;
383 }
384 else if (strncmp (argv[0], "all", strlen (argv[0])) == 0)
385 {
386 all = 1;
387 }
388 else
389 {
390 /* [...] (future options here) */
391 }
392 argv++;
393 }
394 if (pid == 0)
395 error ("No current process: you must name one.");
396
397 sprintf (fname1, "/proc/%lld", pid);
398 if (stat (fname1, &dummy) != 0)
399 error ("No /proc directory: '%s'", fname1);
400
401 printf_filtered ("process %lld\n", pid);
402 if (cmdline_f || all)
403 {
404 sprintf (fname1, "/proc/%lld/cmdline", pid);
405 if ((procfile = fopen (fname1, "r")) > 0)
406 {
407 fgets (buffer, sizeof (buffer), procfile);
408 printf_filtered ("cmdline = '%s'\n", buffer);
409 fclose (procfile);
410 }
411 else
412 warning ("unable to open /proc file '%s'", fname1);
413 }
414 if (cwd_f || all)
415 {
416 sprintf (fname1, "/proc/%lld/cwd", pid);
417 memset (fname2, 0, sizeof (fname2));
418 if (readlink (fname1, fname2, sizeof (fname2)) > 0)
419 printf_filtered ("cwd = '%s'\n", fname2);
420 else
421 warning ("unable to read link '%s'", fname1);
422 }
423 if (exe_f || all)
424 {
425 sprintf (fname1, "/proc/%lld/exe", pid);
426 memset (fname2, 0, sizeof (fname2));
427 if (readlink (fname1, fname2, sizeof (fname2)) > 0)
428 printf_filtered ("exe = '%s'\n", fname2);
429 else
430 warning ("unable to read link '%s'", fname1);
431 }
432 if (mappings_f || all)
433 {
434 sprintf (fname1, "/proc/%lld/maps", pid);
435 if ((procfile = fopen (fname1, "r")) > 0)
436 {
437 long long addr, endaddr, size, offset, inode;
438 char permissions[8], device[8], filename[MAXPATHLEN];
2bf543a6 439
ba058b66 440 printf_filtered ("Mapped address spaces:\n\n");
2bf543a6
MS
441 if (TARGET_ADDR_BIT == 32)
442 {
ba058b66
DC
443 printf_filtered ("\t%10s %10s %10s %10s %7s\n",
444 "Start Addr",
445 " End Addr",
446 " Size", " Offset", "objfile");
447 }
2bf543a6 448 else
ba058b66
DC
449 {
450 printf_filtered (" %18s %18s %10s %10s %7s\n",
2bf543a6
MS
451 "Start Addr",
452 " End Addr",
6949171e 453 " Size", " Offset", "objfile");
ba058b66 454 }
6949171e
JJ
455
456 while (read_mapping (procfile, &addr, &endaddr, &permissions[0],
2bf543a6
MS
457 &offset, &device[0], &inode, &filename[0]))
458 {
459 size = endaddr - addr;
ba058b66
DC
460
461 /* FIXME: carlton/2003-08-27: Maybe the printf_filtered
462 calls here (and possibly above) should be abstracted
463 out into their own functions? Andrew suggests using
464 a generic local_address_string instead to print out
465 the addresses; that makes sense to me, too. */
466
467 if (TARGET_ADDR_BIT == 32)
468 {
469 printf_filtered ("\t%#10lx %#10lx %#10x %#10x %7s\n",
470 (unsigned long) addr, /* FIXME: pr_addr */
6949171e
JJ
471 (unsigned long) endaddr,
472 (int) size,
473 (unsigned int) offset,
2bf543a6 474 filename[0] ? filename : "");
ba058b66
DC
475 }
476 else
477 {
478 printf_filtered (" %#18lx %#18lx %#10x %#10x %7s\n",
479 (unsigned long) addr, /* FIXME: pr_addr */
480 (unsigned long) endaddr,
481 (int) size,
482 (unsigned int) offset,
483 filename[0] ? filename : "");
484 }
2bf543a6
MS
485 }
486
487 fclose (procfile);
488 }
489 else
490 warning ("unable to open /proc file '%s'", fname1);
491 }
492 if (status_f || all)
493 {
494 sprintf (fname1, "/proc/%lld/status", pid);
495 if ((procfile = fopen (fname1, "r")) > 0)
496 {
497 while (fgets (buffer, sizeof (buffer), procfile) != NULL)
306d9ac5 498 puts_filtered (buffer);
2bf543a6
MS
499 fclose (procfile);
500 }
6949171e 501 else
2bf543a6
MS
502 warning ("unable to open /proc file '%s'", fname1);
503 }
504 if (stat_f || all)
505 {
506 sprintf (fname1, "/proc/%lld/stat", pid);
507 if ((procfile = fopen (fname1, "r")) > 0)
508 {
509 int itmp;
510 char ctmp;
511
512 if (fscanf (procfile, "%d ", &itmp) > 0)
513 printf_filtered ("Process: %d\n", itmp);
514 if (fscanf (procfile, "%s ", &buffer[0]) > 0)
515 printf_filtered ("Exec file: %s\n", buffer);
516 if (fscanf (procfile, "%c ", &ctmp) > 0)
517 printf_filtered ("State: %c\n", ctmp);
518 if (fscanf (procfile, "%d ", &itmp) > 0)
519 printf_filtered ("Parent process: %d\n", itmp);
520 if (fscanf (procfile, "%d ", &itmp) > 0)
521 printf_filtered ("Process group: %d\n", itmp);
522 if (fscanf (procfile, "%d ", &itmp) > 0)
523 printf_filtered ("Session id: %d\n", itmp);
524 if (fscanf (procfile, "%d ", &itmp) > 0)
525 printf_filtered ("TTY: %d\n", itmp);
526 if (fscanf (procfile, "%d ", &itmp) > 0)
527 printf_filtered ("TTY owner process group: %d\n", itmp);
528 if (fscanf (procfile, "%u ", &itmp) > 0)
529 printf_filtered ("Flags: 0x%x\n", itmp);
530 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 531 printf_filtered ("Minor faults (no memory page): %u\n",
2bf543a6
MS
532 (unsigned int) itmp);
533 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 534 printf_filtered ("Minor faults, children: %u\n",
2bf543a6
MS
535 (unsigned int) itmp);
536 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 537 printf_filtered ("Major faults (memory page faults): %u\n",
2bf543a6
MS
538 (unsigned int) itmp);
539 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 540 printf_filtered ("Major faults, children: %u\n",
2bf543a6
MS
541 (unsigned int) itmp);
542 if (fscanf (procfile, "%d ", &itmp) > 0)
543 printf_filtered ("utime: %d\n", itmp);
544 if (fscanf (procfile, "%d ", &itmp) > 0)
545 printf_filtered ("stime: %d\n", itmp);
546 if (fscanf (procfile, "%d ", &itmp) > 0)
547 printf_filtered ("utime, children: %d\n", itmp);
548 if (fscanf (procfile, "%d ", &itmp) > 0)
549 printf_filtered ("stime, children: %d\n", itmp);
550 if (fscanf (procfile, "%d ", &itmp) > 0)
6949171e 551 printf_filtered ("jiffies remaining in current time slice: %d\n",
2bf543a6
MS
552 itmp);
553 if (fscanf (procfile, "%d ", &itmp) > 0)
554 printf_filtered ("'nice' value: %d\n", itmp);
555 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 556 printf_filtered ("jiffies until next timeout: %u\n",
2bf543a6
MS
557 (unsigned int) itmp);
558 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 559 printf_filtered ("jiffies until next SIGALRM: %u\n",
2bf543a6
MS
560 (unsigned int) itmp);
561 if (fscanf (procfile, "%d ", &itmp) > 0)
6949171e 562 printf_filtered ("start time (jiffies since system boot): %d\n",
2bf543a6
MS
563 itmp);
564 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 565 printf_filtered ("Virtual memory size: %u\n",
2bf543a6
MS
566 (unsigned int) itmp);
567 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 568 printf_filtered ("Resident set size: %u\n", (unsigned int) itmp);
2bf543a6 569 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 570 printf_filtered ("rlim: %u\n", (unsigned int) itmp);
2bf543a6
MS
571 if (fscanf (procfile, "%u ", &itmp) > 0)
572 printf_filtered ("Start of text: 0x%x\n", itmp);
573 if (fscanf (procfile, "%u ", &itmp) > 0)
574 printf_filtered ("End of text: 0x%x\n", itmp);
575 if (fscanf (procfile, "%u ", &itmp) > 0)
576 printf_filtered ("Start of stack: 0x%x\n", itmp);
cbb685f3 577#if 0 /* Don't know how architecture-dependent the rest is...
6949171e 578 Anyway the signal bitmap info is available from "status". */
2bf543a6
MS
579 if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
580 printf_filtered ("Kernel stack pointer: 0x%x\n", itmp);
581 if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
582 printf_filtered ("Kernel instr pointer: 0x%x\n", itmp);
583 if (fscanf (procfile, "%d ", &itmp) > 0)
584 printf_filtered ("Pending signals bitmap: 0x%x\n", itmp);
585 if (fscanf (procfile, "%d ", &itmp) > 0)
586 printf_filtered ("Blocked signals bitmap: 0x%x\n", itmp);
587 if (fscanf (procfile, "%d ", &itmp) > 0)
588 printf_filtered ("Ignored signals bitmap: 0x%x\n", itmp);
589 if (fscanf (procfile, "%d ", &itmp) > 0)
590 printf_filtered ("Catched signals bitmap: 0x%x\n", itmp);
591 if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
592 printf_filtered ("wchan (system call): 0x%x\n", itmp);
593#endif
594 fclose (procfile);
595 }
596 else
597 warning ("unable to open /proc file '%s'", fname1);
598 }
599}
600
be4d1333
MS
601void
602_initialize_linux_proc (void)
603{
604 extern void inftarg_set_find_memory_regions ();
605 extern void inftarg_set_make_corefile_notes ();
606
607 inftarg_set_find_memory_regions (linux_find_memory_regions);
608 inftarg_set_make_corefile_notes (linux_make_note_section);
2bf543a6 609
6949171e 610 add_info ("proc", linux_info_proc_cmd,
2bf543a6
MS
611 "Show /proc process information about any running process.\n\
612Specify any process id, or use the program being debugged by default.\n\
613Specify any of the following keywords for detailed info:\n\
614 mappings -- list of mapped memory regions.\n\
615 stat -- list a bunch of random process info.\n\
616 status -- list a different bunch of random process info.\n\
617 all -- list all available /proc info.");
be4d1333 618}
eb784848 619
6949171e
JJ
620int
621linux_proc_xfer_memory (CORE_ADDR addr, char *myaddr, int len, int write,
622 struct mem_attrib *attrib, struct target_ops *target)
eb784848
DJ
623{
624 int fd, ret;
625 char filename[64];
626
627 if (write)
628 return 0;
629
630 /* Don't bother for one word. */
631 if (len < 3 * sizeof (long))
632 return 0;
633
634 /* We could keep this file open and cache it - possibly one
635 per thread. That requires some juggling, but is even faster. */
636 sprintf (filename, "/proc/%d/mem", PIDGET (inferior_ptid));
637 fd = open (filename, O_RDONLY | O_LARGEFILE);
638 if (fd == -1)
639 return 0;
640
641 /* If pread64 is available, use it. It's faster if the kernel
642 supports it (only one syscall), and it's 64-bit safe even
643 on 32-bit platforms (for instance, SPARC debugging a SPARC64
6564f77d 644 application). */
eb784848
DJ
645#ifdef HAVE_PREAD64
646 if (pread64 (fd, myaddr, len, addr) != len)
647#else
6949171e 648 if (lseek (fd, addr, SEEK_SET) == -1 || read (fd, myaddr, len) != len)
eb784848
DJ
649#endif
650 ret = 0;
651 else
652 ret = len;
653
654 close (fd);
655 return ret;
656}
bfb39158
DJ
657
658/* Parse LINE as a signal set and add its set bits to SIGS. */
659
660static void
661linux_proc_add_line_to_sigset (const char *line, sigset_t *sigs)
662{
663 int len = strlen (line) - 1;
664 const char *p;
665 int signum;
666
667 if (line[len] != '\n')
668 error ("Could not parse signal set: %s", line);
669
670 p = line;
671 signum = len * 4;
672 while (len-- > 0)
673 {
674 int digit;
675
676 if (*p >= '0' && *p <= '9')
677 digit = *p - '0';
678 else if (*p >= 'a' && *p <= 'f')
679 digit = *p - 'a' + 10;
680 else
681 error ("Could not parse signal set: %s", line);
682
683 signum -= 4;
684
685 if (digit & 1)
686 sigaddset (sigs, signum + 1);
687 if (digit & 2)
688 sigaddset (sigs, signum + 2);
689 if (digit & 4)
690 sigaddset (sigs, signum + 3);
691 if (digit & 8)
692 sigaddset (sigs, signum + 4);
693
694 p++;
695 }
696}
697
698/* Find process PID's pending signals from /proc/pid/status and set SIGS
699 to match. */
700
701void
702linux_proc_pending_signals (int pid, sigset_t *pending, sigset_t *blocked, sigset_t *ignored)
703{
704 FILE *procfile;
705 char buffer[MAXPATHLEN], fname[MAXPATHLEN];
706 int signum;
707
708 sigemptyset (pending);
709 sigemptyset (blocked);
710 sigemptyset (ignored);
711 sprintf (fname, "/proc/%d/status", pid);
712 procfile = fopen (fname, "r");
713 if (procfile == NULL)
714 error ("Could not open %s", fname);
715
716 while (fgets (buffer, MAXPATHLEN, procfile) != NULL)
717 {
718 /* Normal queued signals are on the SigPnd line in the status
719 file. However, 2.6 kernels also have a "shared" pending queue
720 for delivering signals to a thread group, so check for a ShdPnd
721 line also.
722
723 Unfortunately some Red Hat kernels include the shared pending queue
724 but not the ShdPnd status field. */
725
726 if (strncmp (buffer, "SigPnd:\t", 8) == 0)
727 linux_proc_add_line_to_sigset (buffer + 8, pending);
728 else if (strncmp (buffer, "ShdPnd:\t", 8) == 0)
729 linux_proc_add_line_to_sigset (buffer + 8, pending);
730 else if (strncmp (buffer, "SigBlk:\t", 8) == 0)
731 linux_proc_add_line_to_sigset (buffer + 8, blocked);
732 else if (strncmp (buffer, "SigIgn:\t", 8) == 0)
733 linux_proc_add_line_to_sigset (buffer + 8, ignored);
734 }
735
736 fclose (procfile);
737}
This page took 0.318651 seconds and 4 git commands to generate.