*** empty log message ***
[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
211 *
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 ();
224 target_fetch_registers (-1); /* FIXME should not be necessary;
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 ();
233 target_fetch_registers (-1); /* FIXME should not be necessary;
234 fill_gregset should do it automatically. */
235 return 0;
236}
237
cf50a87a
EZ
238/* Function: linux_do_registers
239 *
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 ();
248 target_fetch_registers (-1); /* FIXME should not be necessary;
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.
261 * Builds the note section for a corefile, and returns it
262 * in a malloc buffer.
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;
274
275 if (get_exec_file (0))
276 {
277 strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname));
6949171e 278 strncpy (psargs, get_exec_file (0), sizeof (psargs));
be4d1333
MS
279 if (get_inferior_args ())
280 {
6949171e
JJ
281 strncat (psargs, " ", sizeof (psargs) - strlen (psargs));
282 strncat (psargs, get_inferior_args (),
be4d1333
MS
283 sizeof (psargs) - strlen (psargs));
284 }
6949171e
JJ
285 note_data = (char *) elfcore_write_prpsinfo (obfd,
286 note_data,
287 note_size, fname, psargs);
be4d1333
MS
288 }
289
290 /* Dump information for threads. */
291 thread_args.obfd = obfd;
292 thread_args.note_data = note_data;
293 thread_args.note_size = note_size;
8acc2935 294 thread_args.num_notes = 0;
0274a8ce 295 iterate_over_lwps (linux_corefile_thread_callback, &thread_args);
8acc2935 296 if (thread_args.num_notes == 0)
be4d1333
MS
297 {
298 /* iterate_over_threads didn't come up with any threads;
6949171e 299 just use inferior_ptid. */
cf50a87a
EZ
300 note_data = linux_do_registers (obfd, inferior_ptid,
301 note_data, note_size);
be4d1333
MS
302 }
303 else
304 {
305 note_data = thread_args.note_data;
306 }
307
308 make_cleanup (xfree, note_data);
309 return note_data;
310}
311
2bf543a6
MS
312/*
313 * Function: linux_info_proc_cmd
314 *
315 * Implement the "info proc" command.
316 */
317
318static void
319linux_info_proc_cmd (char *args, int from_tty)
320{
321 long long pid = PIDGET (inferior_ptid);
322 FILE *procfile;
323 char **argv = NULL;
324 char buffer[MAXPATHLEN];
325 char fname1[MAXPATHLEN], fname2[MAXPATHLEN];
326 int cmdline_f = 1;
327 int cwd_f = 1;
328 int exe_f = 1;
329 int mappings_f = 0;
330 int environ_f = 0;
331 int status_f = 0;
332 int stat_f = 0;
333 int all = 0;
334 struct stat dummy;
335
336 if (args)
337 {
338 /* Break up 'args' into an argv array. */
339 if ((argv = buildargv (args)) == NULL)
340 nomem (0);
341 else
342 make_cleanup_freeargv (argv);
343 }
344 while (argv != NULL && *argv != NULL)
345 {
346 if (isdigit (argv[0][0]))
347 {
348 pid = strtoul (argv[0], NULL, 10);
349 }
350 else if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0)
351 {
352 mappings_f = 1;
353 }
354 else if (strcmp (argv[0], "status") == 0)
355 {
356 status_f = 1;
357 }
358 else if (strcmp (argv[0], "stat") == 0)
359 {
360 stat_f = 1;
361 }
362 else if (strcmp (argv[0], "cmd") == 0)
363 {
364 cmdline_f = 1;
365 }
366 else if (strncmp (argv[0], "exe", strlen (argv[0])) == 0)
367 {
368 exe_f = 1;
369 }
370 else if (strcmp (argv[0], "cwd") == 0)
371 {
372 cwd_f = 1;
373 }
374 else if (strncmp (argv[0], "all", strlen (argv[0])) == 0)
375 {
376 all = 1;
377 }
378 else
379 {
380 /* [...] (future options here) */
381 }
382 argv++;
383 }
384 if (pid == 0)
385 error ("No current process: you must name one.");
386
387 sprintf (fname1, "/proc/%lld", pid);
388 if (stat (fname1, &dummy) != 0)
389 error ("No /proc directory: '%s'", fname1);
390
391 printf_filtered ("process %lld\n", pid);
392 if (cmdline_f || all)
393 {
394 sprintf (fname1, "/proc/%lld/cmdline", pid);
395 if ((procfile = fopen (fname1, "r")) > 0)
396 {
397 fgets (buffer, sizeof (buffer), procfile);
398 printf_filtered ("cmdline = '%s'\n", buffer);
399 fclose (procfile);
400 }
401 else
402 warning ("unable to open /proc file '%s'", fname1);
403 }
404 if (cwd_f || all)
405 {
406 sprintf (fname1, "/proc/%lld/cwd", pid);
407 memset (fname2, 0, sizeof (fname2));
408 if (readlink (fname1, fname2, sizeof (fname2)) > 0)
409 printf_filtered ("cwd = '%s'\n", fname2);
410 else
411 warning ("unable to read link '%s'", fname1);
412 }
413 if (exe_f || all)
414 {
415 sprintf (fname1, "/proc/%lld/exe", pid);
416 memset (fname2, 0, sizeof (fname2));
417 if (readlink (fname1, fname2, sizeof (fname2)) > 0)
418 printf_filtered ("exe = '%s'\n", fname2);
419 else
420 warning ("unable to read link '%s'", fname1);
421 }
422 if (mappings_f || all)
423 {
424 sprintf (fname1, "/proc/%lld/maps", pid);
425 if ((procfile = fopen (fname1, "r")) > 0)
426 {
427 long long addr, endaddr, size, offset, inode;
428 char permissions[8], device[8], filename[MAXPATHLEN];
2bf543a6 429
ba058b66 430 printf_filtered ("Mapped address spaces:\n\n");
2bf543a6
MS
431 if (TARGET_ADDR_BIT == 32)
432 {
ba058b66
DC
433 printf_filtered ("\t%10s %10s %10s %10s %7s\n",
434 "Start Addr",
435 " End Addr",
436 " Size", " Offset", "objfile");
437 }
2bf543a6 438 else
ba058b66
DC
439 {
440 printf_filtered (" %18s %18s %10s %10s %7s\n",
2bf543a6
MS
441 "Start Addr",
442 " End Addr",
6949171e 443 " Size", " Offset", "objfile");
ba058b66 444 }
6949171e
JJ
445
446 while (read_mapping (procfile, &addr, &endaddr, &permissions[0],
2bf543a6
MS
447 &offset, &device[0], &inode, &filename[0]))
448 {
449 size = endaddr - addr;
ba058b66
DC
450
451 /* FIXME: carlton/2003-08-27: Maybe the printf_filtered
452 calls here (and possibly above) should be abstracted
453 out into their own functions? Andrew suggests using
454 a generic local_address_string instead to print out
455 the addresses; that makes sense to me, too. */
456
457 if (TARGET_ADDR_BIT == 32)
458 {
459 printf_filtered ("\t%#10lx %#10lx %#10x %#10x %7s\n",
460 (unsigned long) addr, /* FIXME: pr_addr */
6949171e
JJ
461 (unsigned long) endaddr,
462 (int) size,
463 (unsigned int) offset,
2bf543a6 464 filename[0] ? filename : "");
ba058b66
DC
465 }
466 else
467 {
468 printf_filtered (" %#18lx %#18lx %#10x %#10x %7s\n",
469 (unsigned long) addr, /* FIXME: pr_addr */
470 (unsigned long) endaddr,
471 (int) size,
472 (unsigned int) offset,
473 filename[0] ? filename : "");
474 }
2bf543a6
MS
475 }
476
477 fclose (procfile);
478 }
479 else
480 warning ("unable to open /proc file '%s'", fname1);
481 }
482 if (status_f || all)
483 {
484 sprintf (fname1, "/proc/%lld/status", pid);
485 if ((procfile = fopen (fname1, "r")) > 0)
486 {
487 while (fgets (buffer, sizeof (buffer), procfile) != NULL)
306d9ac5 488 puts_filtered (buffer);
2bf543a6
MS
489 fclose (procfile);
490 }
6949171e 491 else
2bf543a6
MS
492 warning ("unable to open /proc file '%s'", fname1);
493 }
494 if (stat_f || all)
495 {
496 sprintf (fname1, "/proc/%lld/stat", pid);
497 if ((procfile = fopen (fname1, "r")) > 0)
498 {
499 int itmp;
500 char ctmp;
501
502 if (fscanf (procfile, "%d ", &itmp) > 0)
503 printf_filtered ("Process: %d\n", itmp);
504 if (fscanf (procfile, "%s ", &buffer[0]) > 0)
505 printf_filtered ("Exec file: %s\n", buffer);
506 if (fscanf (procfile, "%c ", &ctmp) > 0)
507 printf_filtered ("State: %c\n", ctmp);
508 if (fscanf (procfile, "%d ", &itmp) > 0)
509 printf_filtered ("Parent process: %d\n", itmp);
510 if (fscanf (procfile, "%d ", &itmp) > 0)
511 printf_filtered ("Process group: %d\n", itmp);
512 if (fscanf (procfile, "%d ", &itmp) > 0)
513 printf_filtered ("Session id: %d\n", itmp);
514 if (fscanf (procfile, "%d ", &itmp) > 0)
515 printf_filtered ("TTY: %d\n", itmp);
516 if (fscanf (procfile, "%d ", &itmp) > 0)
517 printf_filtered ("TTY owner process group: %d\n", itmp);
518 if (fscanf (procfile, "%u ", &itmp) > 0)
519 printf_filtered ("Flags: 0x%x\n", itmp);
520 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 521 printf_filtered ("Minor faults (no memory page): %u\n",
2bf543a6
MS
522 (unsigned int) itmp);
523 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 524 printf_filtered ("Minor faults, children: %u\n",
2bf543a6
MS
525 (unsigned int) itmp);
526 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 527 printf_filtered ("Major faults (memory page faults): %u\n",
2bf543a6
MS
528 (unsigned int) itmp);
529 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 530 printf_filtered ("Major faults, children: %u\n",
2bf543a6
MS
531 (unsigned int) itmp);
532 if (fscanf (procfile, "%d ", &itmp) > 0)
533 printf_filtered ("utime: %d\n", itmp);
534 if (fscanf (procfile, "%d ", &itmp) > 0)
535 printf_filtered ("stime: %d\n", itmp);
536 if (fscanf (procfile, "%d ", &itmp) > 0)
537 printf_filtered ("utime, children: %d\n", itmp);
538 if (fscanf (procfile, "%d ", &itmp) > 0)
539 printf_filtered ("stime, children: %d\n", itmp);
540 if (fscanf (procfile, "%d ", &itmp) > 0)
6949171e 541 printf_filtered ("jiffies remaining in current time slice: %d\n",
2bf543a6
MS
542 itmp);
543 if (fscanf (procfile, "%d ", &itmp) > 0)
544 printf_filtered ("'nice' value: %d\n", itmp);
545 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 546 printf_filtered ("jiffies until next timeout: %u\n",
2bf543a6
MS
547 (unsigned int) itmp);
548 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 549 printf_filtered ("jiffies until next SIGALRM: %u\n",
2bf543a6
MS
550 (unsigned int) itmp);
551 if (fscanf (procfile, "%d ", &itmp) > 0)
6949171e 552 printf_filtered ("start time (jiffies since system boot): %d\n",
2bf543a6
MS
553 itmp);
554 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 555 printf_filtered ("Virtual memory size: %u\n",
2bf543a6
MS
556 (unsigned int) itmp);
557 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 558 printf_filtered ("Resident set size: %u\n", (unsigned int) itmp);
2bf543a6 559 if (fscanf (procfile, "%u ", &itmp) > 0)
6949171e 560 printf_filtered ("rlim: %u\n", (unsigned int) itmp);
2bf543a6
MS
561 if (fscanf (procfile, "%u ", &itmp) > 0)
562 printf_filtered ("Start of text: 0x%x\n", itmp);
563 if (fscanf (procfile, "%u ", &itmp) > 0)
564 printf_filtered ("End of text: 0x%x\n", itmp);
565 if (fscanf (procfile, "%u ", &itmp) > 0)
566 printf_filtered ("Start of stack: 0x%x\n", itmp);
6949171e
JJ
567#if 0 /* Don't know how architecture-dependent the rest is...
568 Anyway the signal bitmap info is available from "status". */
2bf543a6
MS
569 if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
570 printf_filtered ("Kernel stack pointer: 0x%x\n", itmp);
571 if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
572 printf_filtered ("Kernel instr pointer: 0x%x\n", itmp);
573 if (fscanf (procfile, "%d ", &itmp) > 0)
574 printf_filtered ("Pending signals bitmap: 0x%x\n", itmp);
575 if (fscanf (procfile, "%d ", &itmp) > 0)
576 printf_filtered ("Blocked signals bitmap: 0x%x\n", itmp);
577 if (fscanf (procfile, "%d ", &itmp) > 0)
578 printf_filtered ("Ignored signals bitmap: 0x%x\n", itmp);
579 if (fscanf (procfile, "%d ", &itmp) > 0)
580 printf_filtered ("Catched signals bitmap: 0x%x\n", itmp);
581 if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
582 printf_filtered ("wchan (system call): 0x%x\n", itmp);
583#endif
584 fclose (procfile);
585 }
586 else
587 warning ("unable to open /proc file '%s'", fname1);
588 }
589}
590
be4d1333
MS
591void
592_initialize_linux_proc (void)
593{
594 extern void inftarg_set_find_memory_regions ();
595 extern void inftarg_set_make_corefile_notes ();
596
597 inftarg_set_find_memory_regions (linux_find_memory_regions);
598 inftarg_set_make_corefile_notes (linux_make_note_section);
2bf543a6 599
6949171e 600 add_info ("proc", linux_info_proc_cmd,
2bf543a6
MS
601 "Show /proc process information about any running process.\n\
602Specify any process id, or use the program being debugged by default.\n\
603Specify any of the following keywords for detailed info:\n\
604 mappings -- list of mapped memory regions.\n\
605 stat -- list a bunch of random process info.\n\
606 status -- list a different bunch of random process info.\n\
607 all -- list all available /proc info.");
be4d1333 608}
eb784848 609
6949171e
JJ
610int
611linux_proc_xfer_memory (CORE_ADDR addr, char *myaddr, int len, int write,
612 struct mem_attrib *attrib, struct target_ops *target)
eb784848
DJ
613{
614 int fd, ret;
615 char filename[64];
616
617 if (write)
618 return 0;
619
620 /* Don't bother for one word. */
621 if (len < 3 * sizeof (long))
622 return 0;
623
624 /* We could keep this file open and cache it - possibly one
625 per thread. That requires some juggling, but is even faster. */
626 sprintf (filename, "/proc/%d/mem", PIDGET (inferior_ptid));
627 fd = open (filename, O_RDONLY | O_LARGEFILE);
628 if (fd == -1)
629 return 0;
630
631 /* If pread64 is available, use it. It's faster if the kernel
632 supports it (only one syscall), and it's 64-bit safe even
633 on 32-bit platforms (for instance, SPARC debugging a SPARC64
6564f77d 634 application). */
eb784848
DJ
635#ifdef HAVE_PREAD64
636 if (pread64 (fd, myaddr, len, addr) != len)
637#else
6949171e 638 if (lseek (fd, addr, SEEK_SET) == -1 || read (fd, myaddr, len) != len)
eb784848
DJ
639#endif
640 ret = 0;
641 else
642 ret = len;
643
644 close (fd);
645 return ret;
646}
bfb39158
DJ
647
648/* Parse LINE as a signal set and add its set bits to SIGS. */
649
650static void
651linux_proc_add_line_to_sigset (const char *line, sigset_t *sigs)
652{
653 int len = strlen (line) - 1;
654 const char *p;
655 int signum;
656
657 if (line[len] != '\n')
658 error ("Could not parse signal set: %s", line);
659
660 p = line;
661 signum = len * 4;
662 while (len-- > 0)
663 {
664 int digit;
665
666 if (*p >= '0' && *p <= '9')
667 digit = *p - '0';
668 else if (*p >= 'a' && *p <= 'f')
669 digit = *p - 'a' + 10;
670 else
671 error ("Could not parse signal set: %s", line);
672
673 signum -= 4;
674
675 if (digit & 1)
676 sigaddset (sigs, signum + 1);
677 if (digit & 2)
678 sigaddset (sigs, signum + 2);
679 if (digit & 4)
680 sigaddset (sigs, signum + 3);
681 if (digit & 8)
682 sigaddset (sigs, signum + 4);
683
684 p++;
685 }
686}
687
688/* Find process PID's pending signals from /proc/pid/status and set SIGS
689 to match. */
690
691void
692linux_proc_pending_signals (int pid, sigset_t *pending, sigset_t *blocked, sigset_t *ignored)
693{
694 FILE *procfile;
695 char buffer[MAXPATHLEN], fname[MAXPATHLEN];
696 int signum;
697
698 sigemptyset (pending);
699 sigemptyset (blocked);
700 sigemptyset (ignored);
701 sprintf (fname, "/proc/%d/status", pid);
702 procfile = fopen (fname, "r");
703 if (procfile == NULL)
704 error ("Could not open %s", fname);
705
706 while (fgets (buffer, MAXPATHLEN, procfile) != NULL)
707 {
708 /* Normal queued signals are on the SigPnd line in the status
709 file. However, 2.6 kernels also have a "shared" pending queue
710 for delivering signals to a thread group, so check for a ShdPnd
711 line also.
712
713 Unfortunately some Red Hat kernels include the shared pending queue
714 but not the ShdPnd status field. */
715
716 if (strncmp (buffer, "SigPnd:\t", 8) == 0)
717 linux_proc_add_line_to_sigset (buffer + 8, pending);
718 else if (strncmp (buffer, "ShdPnd:\t", 8) == 0)
719 linux_proc_add_line_to_sigset (buffer + 8, pending);
720 else if (strncmp (buffer, "SigBlk:\t", 8) == 0)
721 linux_proc_add_line_to_sigset (buffer + 8, blocked);
722 else if (strncmp (buffer, "SigIgn:\t", 8) == 0)
723 linux_proc_add_line_to_sigset (buffer + 8, ignored);
724 }
725
726 fclose (procfile);
727}
This page took 0.244032 seconds and 4 git commands to generate.