* gdbarch.sh (info_proc): New callback.
* gdbarch.c, gdbarch.h: Regenerate. * infcmd.c (info_proc_cmd_1): Try gdbarch info_proc callback before falling back to the target info_proc callback. * linux-nat.c: Do not include "cli/cli-utils.h". (linux_nat_info_proc): Remove. (linux_target_install_ops): No longer install it. * linux-tdep.c: Include "cli/cli-utils.h" and <ctype.h>. (read_mapping): New function. (linux_info_proc): Likewise. (linux_init_abi): Install it.
This commit is contained in:
parent
145b16a97a
commit
3030c96e66
7 changed files with 397 additions and 248 deletions
|
@ -1,3 +1,20 @@
|
||||||
|
2012-01-20 Ulrich Weigand <ulrich.weigand@linaro.org>
|
||||||
|
|
||||||
|
* gdbarch.sh (info_proc): New callback.
|
||||||
|
* gdbarch.c, gdbarch.h: Regenerate.
|
||||||
|
|
||||||
|
* infcmd.c (info_proc_cmd_1): Try gdbarch info_proc callback
|
||||||
|
before falling back to the target info_proc callback.
|
||||||
|
|
||||||
|
* linux-nat.c: Do not include "cli/cli-utils.h".
|
||||||
|
(linux_nat_info_proc): Remove.
|
||||||
|
(linux_target_install_ops): No longer install it.
|
||||||
|
|
||||||
|
* linux-tdep.c: Include "cli/cli-utils.h" and <ctype.h>.
|
||||||
|
(read_mapping): New function.
|
||||||
|
(linux_info_proc): Likewise.
|
||||||
|
(linux_init_abi): Install it.
|
||||||
|
|
||||||
2012-01-20 Ulrich Weigand <ulrich.weigand@linaro.org>
|
2012-01-20 Ulrich Weigand <ulrich.weigand@linaro.org>
|
||||||
|
|
||||||
* defs.h (enum info_proc_what): Moved here from linux-nat.c
|
* defs.h (enum info_proc_what): Moved here from linux-nat.c
|
||||||
|
|
|
@ -272,6 +272,7 @@ struct gdbarch
|
||||||
const char * solib_symbols_extension;
|
const char * solib_symbols_extension;
|
||||||
int has_dos_based_file_system;
|
int has_dos_based_file_system;
|
||||||
gdbarch_gen_return_address_ftype *gen_return_address;
|
gdbarch_gen_return_address_ftype *gen_return_address;
|
||||||
|
gdbarch_info_proc_ftype *info_proc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -427,6 +428,7 @@ struct gdbarch startup_gdbarch =
|
||||||
0, /* solib_symbols_extension */
|
0, /* solib_symbols_extension */
|
||||||
0, /* has_dos_based_file_system */
|
0, /* has_dos_based_file_system */
|
||||||
default_gen_return_address, /* gen_return_address */
|
default_gen_return_address, /* gen_return_address */
|
||||||
|
0, /* info_proc */
|
||||||
/* startup_gdbarch() */
|
/* startup_gdbarch() */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -715,6 +717,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
||||||
/* Skip verify of auto_wide_charset, invalid_p == 0 */
|
/* Skip verify of auto_wide_charset, invalid_p == 0 */
|
||||||
/* Skip verify of has_dos_based_file_system, invalid_p == 0 */
|
/* Skip verify of has_dos_based_file_system, invalid_p == 0 */
|
||||||
/* Skip verify of gen_return_address, invalid_p == 0 */
|
/* Skip verify of gen_return_address, invalid_p == 0 */
|
||||||
|
/* Skip verify of info_proc, has predicate. */
|
||||||
buf = ui_file_xstrdup (log, &length);
|
buf = ui_file_xstrdup (log, &length);
|
||||||
make_cleanup (xfree, buf);
|
make_cleanup (xfree, buf);
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
|
@ -1002,6 +1005,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
||||||
fprintf_unfiltered (file,
|
fprintf_unfiltered (file,
|
||||||
"gdbarch_dump: in_solib_return_trampoline = <%s>\n",
|
"gdbarch_dump: in_solib_return_trampoline = <%s>\n",
|
||||||
host_address_to_string (gdbarch->in_solib_return_trampoline));
|
host_address_to_string (gdbarch->in_solib_return_trampoline));
|
||||||
|
fprintf_unfiltered (file,
|
||||||
|
"gdbarch_dump: gdbarch_info_proc_p() = %d\n",
|
||||||
|
gdbarch_info_proc_p (gdbarch));
|
||||||
|
fprintf_unfiltered (file,
|
||||||
|
"gdbarch_dump: info_proc = <%s>\n",
|
||||||
|
host_address_to_string (gdbarch->info_proc));
|
||||||
fprintf_unfiltered (file,
|
fprintf_unfiltered (file,
|
||||||
"gdbarch_dump: inner_than = <%s>\n",
|
"gdbarch_dump: inner_than = <%s>\n",
|
||||||
host_address_to_string (gdbarch->inner_than));
|
host_address_to_string (gdbarch->inner_than));
|
||||||
|
@ -3911,6 +3920,30 @@ set_gdbarch_gen_return_address (struct gdbarch *gdbarch,
|
||||||
gdbarch->gen_return_address = gen_return_address;
|
gdbarch->gen_return_address = gen_return_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gdbarch_info_proc_p (struct gdbarch *gdbarch)
|
||||||
|
{
|
||||||
|
gdb_assert (gdbarch != NULL);
|
||||||
|
return gdbarch->info_proc != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdbarch_info_proc (struct gdbarch *gdbarch, char *args, enum info_proc_what what)
|
||||||
|
{
|
||||||
|
gdb_assert (gdbarch != NULL);
|
||||||
|
gdb_assert (gdbarch->info_proc != NULL);
|
||||||
|
if (gdbarch_debug >= 2)
|
||||||
|
fprintf_unfiltered (gdb_stdlog, "gdbarch_info_proc called\n");
|
||||||
|
gdbarch->info_proc (gdbarch, args, what);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_gdbarch_info_proc (struct gdbarch *gdbarch,
|
||||||
|
gdbarch_info_proc_ftype info_proc)
|
||||||
|
{
|
||||||
|
gdbarch->info_proc = info_proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Keep a registry of per-architecture data-pointers required by GDB
|
/* Keep a registry of per-architecture data-pointers required by GDB
|
||||||
modules. */
|
modules. */
|
||||||
|
|
|
@ -1031,6 +1031,14 @@ typedef void (gdbarch_gen_return_address_ftype) (struct gdbarch *gdbarch, struct
|
||||||
extern void gdbarch_gen_return_address (struct gdbarch *gdbarch, struct agent_expr *ax, struct axs_value *value, CORE_ADDR scope);
|
extern void gdbarch_gen_return_address (struct gdbarch *gdbarch, struct agent_expr *ax, struct axs_value *value, CORE_ADDR scope);
|
||||||
extern void set_gdbarch_gen_return_address (struct gdbarch *gdbarch, gdbarch_gen_return_address_ftype *gen_return_address);
|
extern void set_gdbarch_gen_return_address (struct gdbarch *gdbarch, gdbarch_gen_return_address_ftype *gen_return_address);
|
||||||
|
|
||||||
|
/* Implement the "info proc" command. */
|
||||||
|
|
||||||
|
extern int gdbarch_info_proc_p (struct gdbarch *gdbarch);
|
||||||
|
|
||||||
|
typedef void (gdbarch_info_proc_ftype) (struct gdbarch *gdbarch, char *args, enum info_proc_what what);
|
||||||
|
extern void gdbarch_info_proc (struct gdbarch *gdbarch, char *args, enum info_proc_what what);
|
||||||
|
extern void set_gdbarch_info_proc (struct gdbarch *gdbarch, gdbarch_info_proc_ftype *info_proc);
|
||||||
|
|
||||||
/* Definition for an unknown syscall, used basically in error-cases. */
|
/* Definition for an unknown syscall, used basically in error-cases. */
|
||||||
#define UNKNOWN_SYSCALL (-1)
|
#define UNKNOWN_SYSCALL (-1)
|
||||||
|
|
||||||
|
|
|
@ -830,6 +830,9 @@ v:int:has_dos_based_file_system:::0:0::0
|
||||||
# places that the return address may be found.
|
# places that the return address may be found.
|
||||||
m:void:gen_return_address:struct agent_expr *ax, struct axs_value *value, CORE_ADDR scope:ax, value, scope::default_gen_return_address::0
|
m:void:gen_return_address:struct agent_expr *ax, struct axs_value *value, CORE_ADDR scope:ax, value, scope::default_gen_return_address::0
|
||||||
|
|
||||||
|
# Implement the "info proc" command.
|
||||||
|
M:void:info_proc:char *args, enum info_proc_what what:args, what
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2810,6 +2810,11 @@ unset_command (char *args, int from_tty)
|
||||||
static void
|
static void
|
||||||
info_proc_cmd_1 (char *args, enum info_proc_what what, int from_tty)
|
info_proc_cmd_1 (char *args, enum info_proc_what what, int from_tty)
|
||||||
{
|
{
|
||||||
|
struct gdbarch *gdbarch = get_current_arch ();
|
||||||
|
|
||||||
|
if (gdbarch_info_proc_p (gdbarch))
|
||||||
|
gdbarch_info_proc (gdbarch, args, what);
|
||||||
|
else
|
||||||
target_info_proc (args, what);
|
target_info_proc (args, what);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
247
gdb/linux-nat.c
247
gdb/linux-nat.c
|
@ -58,7 +58,6 @@
|
||||||
#include <sys/vfs.h>
|
#include <sys/vfs.h>
|
||||||
#include "solib.h"
|
#include "solib.h"
|
||||||
#include "linux-osdata.h"
|
#include "linux-osdata.h"
|
||||||
#include "cli/cli-utils.h"
|
|
||||||
|
|
||||||
#ifndef SPUFS_MAGIC
|
#ifndef SPUFS_MAGIC
|
||||||
#define SPUFS_MAGIC 0x23c9b64e
|
#define SPUFS_MAGIC 0x23c9b64e
|
||||||
|
@ -4801,251 +4800,6 @@ linux_nat_make_corefile_notes (bfd *obfd, int *note_size)
|
||||||
return note_data;
|
return note_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implement the "info proc" command. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
linux_nat_info_proc (struct target_ops *ops, char *args,
|
|
||||||
enum info_proc_what what)
|
|
||||||
{
|
|
||||||
/* A long is used for pid instead of an int to avoid a loss of precision
|
|
||||||
compiler warning from the output of strtoul. */
|
|
||||||
long pid = PIDGET (inferior_ptid);
|
|
||||||
FILE *procfile;
|
|
||||||
char buffer[MAXPATHLEN];
|
|
||||||
char fname1[MAXPATHLEN], fname2[MAXPATHLEN];
|
|
||||||
int cmdline_f = (what == IP_MINIMAL || what == IP_CMDLINE || what == IP_ALL);
|
|
||||||
int cwd_f = (what == IP_MINIMAL || what == IP_CWD || what == IP_ALL);
|
|
||||||
int exe_f = (what == IP_MINIMAL || what == IP_EXE || what == IP_ALL);
|
|
||||||
int mappings_f = (what == IP_MAPPINGS || what == IP_ALL);
|
|
||||||
int status_f = (what == IP_STATUS || what == IP_ALL);
|
|
||||||
int stat_f = (what == IP_STAT || what == IP_ALL);
|
|
||||||
struct stat dummy;
|
|
||||||
|
|
||||||
if (args && isdigit (args[0]))
|
|
||||||
pid = strtoul (args, &args, 10);
|
|
||||||
|
|
||||||
args = skip_spaces (args);
|
|
||||||
if (args && args[0])
|
|
||||||
error (_("Too many parameters: %s"), args);
|
|
||||||
|
|
||||||
if (pid == 0)
|
|
||||||
error (_("No current process: you must name one."));
|
|
||||||
|
|
||||||
sprintf (fname1, "/proc/%ld", pid);
|
|
||||||
if (stat (fname1, &dummy) != 0)
|
|
||||||
error (_("No /proc directory: '%s'"), fname1);
|
|
||||||
|
|
||||||
printf_filtered (_("process %ld\n"), pid);
|
|
||||||
if (cmdline_f)
|
|
||||||
{
|
|
||||||
sprintf (fname1, "/proc/%ld/cmdline", pid);
|
|
||||||
if ((procfile = fopen (fname1, "r")) != NULL)
|
|
||||||
{
|
|
||||||
struct cleanup *cleanup = make_cleanup_fclose (procfile);
|
|
||||||
|
|
||||||
if (fgets (buffer, sizeof (buffer), procfile))
|
|
||||||
printf_filtered ("cmdline = '%s'\n", buffer);
|
|
||||||
else
|
|
||||||
warning (_("unable to read '%s'"), fname1);
|
|
||||||
do_cleanups (cleanup);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
warning (_("unable to open /proc file '%s'"), fname1);
|
|
||||||
}
|
|
||||||
if (cwd_f)
|
|
||||||
{
|
|
||||||
sprintf (fname1, "/proc/%ld/cwd", pid);
|
|
||||||
memset (fname2, 0, sizeof (fname2));
|
|
||||||
if (readlink (fname1, fname2, sizeof (fname2)) > 0)
|
|
||||||
printf_filtered ("cwd = '%s'\n", fname2);
|
|
||||||
else
|
|
||||||
warning (_("unable to read link '%s'"), fname1);
|
|
||||||
}
|
|
||||||
if (exe_f)
|
|
||||||
{
|
|
||||||
sprintf (fname1, "/proc/%ld/exe", pid);
|
|
||||||
memset (fname2, 0, sizeof (fname2));
|
|
||||||
if (readlink (fname1, fname2, sizeof (fname2)) > 0)
|
|
||||||
printf_filtered ("exe = '%s'\n", fname2);
|
|
||||||
else
|
|
||||||
warning (_("unable to read link '%s'"), fname1);
|
|
||||||
}
|
|
||||||
if (mappings_f)
|
|
||||||
{
|
|
||||||
sprintf (fname1, "/proc/%ld/maps", pid);
|
|
||||||
if ((procfile = fopen (fname1, "r")) != NULL)
|
|
||||||
{
|
|
||||||
long long addr, endaddr, size, offset, inode;
|
|
||||||
char permissions[8], device[8], filename[MAXPATHLEN];
|
|
||||||
struct cleanup *cleanup;
|
|
||||||
|
|
||||||
cleanup = make_cleanup_fclose (procfile);
|
|
||||||
printf_filtered (_("Mapped address spaces:\n\n"));
|
|
||||||
if (gdbarch_addr_bit (target_gdbarch) == 32)
|
|
||||||
{
|
|
||||||
printf_filtered ("\t%10s %10s %10s %10s %7s\n",
|
|
||||||
"Start Addr",
|
|
||||||
" End Addr",
|
|
||||||
" Size", " Offset", "objfile");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf_filtered (" %18s %18s %10s %10s %7s\n",
|
|
||||||
"Start Addr",
|
|
||||||
" End Addr",
|
|
||||||
" Size", " Offset", "objfile");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (read_mapping (procfile, &addr, &endaddr, &permissions[0],
|
|
||||||
&offset, &device[0], &inode, &filename[0]))
|
|
||||||
{
|
|
||||||
size = endaddr - addr;
|
|
||||||
|
|
||||||
/* FIXME: carlton/2003-08-27: Maybe the printf_filtered
|
|
||||||
calls here (and possibly above) should be abstracted
|
|
||||||
out into their own functions? Andrew suggests using
|
|
||||||
a generic local_address_string instead to print out
|
|
||||||
the addresses; that makes sense to me, too. */
|
|
||||||
|
|
||||||
if (gdbarch_addr_bit (target_gdbarch) == 32)
|
|
||||||
{
|
|
||||||
printf_filtered ("\t%#10lx %#10lx %#10x %#10x %7s\n",
|
|
||||||
(unsigned long) addr, /* FIXME: pr_addr */
|
|
||||||
(unsigned long) endaddr,
|
|
||||||
(int) size,
|
|
||||||
(unsigned int) offset,
|
|
||||||
filename[0] ? filename : "");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf_filtered (" %#18lx %#18lx %#10x %#10x %7s\n",
|
|
||||||
(unsigned long) addr, /* FIXME: pr_addr */
|
|
||||||
(unsigned long) endaddr,
|
|
||||||
(int) size,
|
|
||||||
(unsigned int) offset,
|
|
||||||
filename[0] ? filename : "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
do_cleanups (cleanup);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
warning (_("unable to open /proc file '%s'"), fname1);
|
|
||||||
}
|
|
||||||
if (status_f)
|
|
||||||
{
|
|
||||||
sprintf (fname1, "/proc/%ld/status", pid);
|
|
||||||
if ((procfile = fopen (fname1, "r")) != NULL)
|
|
||||||
{
|
|
||||||
struct cleanup *cleanup = make_cleanup_fclose (procfile);
|
|
||||||
|
|
||||||
while (fgets (buffer, sizeof (buffer), procfile) != NULL)
|
|
||||||
puts_filtered (buffer);
|
|
||||||
do_cleanups (cleanup);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
warning (_("unable to open /proc file '%s'"), fname1);
|
|
||||||
}
|
|
||||||
if (stat_f)
|
|
||||||
{
|
|
||||||
sprintf (fname1, "/proc/%ld/stat", pid);
|
|
||||||
if ((procfile = fopen (fname1, "r")) != NULL)
|
|
||||||
{
|
|
||||||
int itmp;
|
|
||||||
char ctmp;
|
|
||||||
long ltmp;
|
|
||||||
struct cleanup *cleanup = make_cleanup_fclose (procfile);
|
|
||||||
|
|
||||||
if (fscanf (procfile, "%d ", &itmp) > 0)
|
|
||||||
printf_filtered (_("Process: %d\n"), itmp);
|
|
||||||
if (fscanf (procfile, "(%[^)]) ", &buffer[0]) > 0)
|
|
||||||
printf_filtered (_("Exec file: %s\n"), buffer);
|
|
||||||
if (fscanf (procfile, "%c ", &ctmp) > 0)
|
|
||||||
printf_filtered (_("State: %c\n"), ctmp);
|
|
||||||
if (fscanf (procfile, "%d ", &itmp) > 0)
|
|
||||||
printf_filtered (_("Parent process: %d\n"), itmp);
|
|
||||||
if (fscanf (procfile, "%d ", &itmp) > 0)
|
|
||||||
printf_filtered (_("Process group: %d\n"), itmp);
|
|
||||||
if (fscanf (procfile, "%d ", &itmp) > 0)
|
|
||||||
printf_filtered (_("Session id: %d\n"), itmp);
|
|
||||||
if (fscanf (procfile, "%d ", &itmp) > 0)
|
|
||||||
printf_filtered (_("TTY: %d\n"), itmp);
|
|
||||||
if (fscanf (procfile, "%d ", &itmp) > 0)
|
|
||||||
printf_filtered (_("TTY owner process group: %d\n"), itmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0)
|
|
||||||
printf_filtered (_("Flags: 0x%lx\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0)
|
|
||||||
printf_filtered (_("Minor faults (no memory page): %lu\n"),
|
|
||||||
(unsigned long) ltmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0)
|
|
||||||
printf_filtered (_("Minor faults, children: %lu\n"),
|
|
||||||
(unsigned long) ltmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0)
|
|
||||||
printf_filtered (_("Major faults (memory page faults): %lu\n"),
|
|
||||||
(unsigned long) ltmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0)
|
|
||||||
printf_filtered (_("Major faults, children: %lu\n"),
|
|
||||||
(unsigned long) ltmp);
|
|
||||||
if (fscanf (procfile, "%ld ", <mp) > 0)
|
|
||||||
printf_filtered (_("utime: %ld\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%ld ", <mp) > 0)
|
|
||||||
printf_filtered (_("stime: %ld\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%ld ", <mp) > 0)
|
|
||||||
printf_filtered (_("utime, children: %ld\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%ld ", <mp) > 0)
|
|
||||||
printf_filtered (_("stime, children: %ld\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%ld ", <mp) > 0)
|
|
||||||
printf_filtered (_("jiffies remaining in current "
|
|
||||||
"time slice: %ld\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%ld ", <mp) > 0)
|
|
||||||
printf_filtered (_("'nice' value: %ld\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0)
|
|
||||||
printf_filtered (_("jiffies until next timeout: %lu\n"),
|
|
||||||
(unsigned long) ltmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0)
|
|
||||||
printf_filtered (_("jiffies until next SIGALRM: %lu\n"),
|
|
||||||
(unsigned long) ltmp);
|
|
||||||
if (fscanf (procfile, "%ld ", <mp) > 0)
|
|
||||||
printf_filtered (_("start time (jiffies since "
|
|
||||||
"system boot): %ld\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0)
|
|
||||||
printf_filtered (_("Virtual memory size: %lu\n"),
|
|
||||||
(unsigned long) ltmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0)
|
|
||||||
printf_filtered (_("Resident set size: %lu\n"),
|
|
||||||
(unsigned long) ltmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0)
|
|
||||||
printf_filtered (_("rlim: %lu\n"), (unsigned long) ltmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0)
|
|
||||||
printf_filtered (_("Start of text: 0x%lx\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0)
|
|
||||||
printf_filtered (_("End of text: 0x%lx\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0)
|
|
||||||
printf_filtered (_("Start of stack: 0x%lx\n"), ltmp);
|
|
||||||
#if 0 /* Don't know how architecture-dependent the rest is...
|
|
||||||
Anyway the signal bitmap info is available from "status". */
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0) /* FIXME arch? */
|
|
||||||
printf_filtered (_("Kernel stack pointer: 0x%lx\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0) /* FIXME arch? */
|
|
||||||
printf_filtered (_("Kernel instr pointer: 0x%lx\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%ld ", <mp) > 0)
|
|
||||||
printf_filtered (_("Pending signals bitmap: 0x%lx\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%ld ", <mp) > 0)
|
|
||||||
printf_filtered (_("Blocked signals bitmap: 0x%lx\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%ld ", <mp) > 0)
|
|
||||||
printf_filtered (_("Ignored signals bitmap: 0x%lx\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%ld ", <mp) > 0)
|
|
||||||
printf_filtered (_("Catched signals bitmap: 0x%lx\n"), ltmp);
|
|
||||||
if (fscanf (procfile, "%lu ", <mp) > 0) /* FIXME arch? */
|
|
||||||
printf_filtered (_("wchan (system call): 0x%lx\n"), ltmp);
|
|
||||||
#endif
|
|
||||||
do_cleanups (cleanup);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
warning (_("unable to open /proc file '%s'"), fname1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Implement the to_xfer_partial interface for memory reads using the /proc
|
/* Implement the to_xfer_partial interface for memory reads using the /proc
|
||||||
filesystem. Because we can use a single read() call for /proc, this
|
filesystem. Because we can use a single read() call for /proc, this
|
||||||
can be much more efficient than banging away at PTRACE_PEEKTEXT,
|
can be much more efficient than banging away at PTRACE_PEEKTEXT,
|
||||||
|
@ -5340,7 +5094,6 @@ linux_target_install_ops (struct target_ops *t)
|
||||||
t->to_follow_fork = linux_child_follow_fork;
|
t->to_follow_fork = linux_child_follow_fork;
|
||||||
t->to_find_memory_regions = linux_nat_find_memory_regions;
|
t->to_find_memory_regions = linux_nat_find_memory_regions;
|
||||||
t->to_make_corefile_notes = linux_nat_make_corefile_notes;
|
t->to_make_corefile_notes = linux_nat_make_corefile_notes;
|
||||||
t->to_info_proc = linux_nat_info_proc;
|
|
||||||
|
|
||||||
super_xfer_partial = t->to_xfer_partial;
|
super_xfer_partial = t->to_xfer_partial;
|
||||||
t->to_xfer_partial = linux_xfer_partial;
|
t->to_xfer_partial = linux_xfer_partial;
|
||||||
|
|
330
gdb/linux-tdep.c
330
gdb/linux-tdep.c
|
@ -24,6 +24,9 @@
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "elf/common.h"
|
#include "elf/common.h"
|
||||||
#include "inferior.h"
|
#include "inferior.h"
|
||||||
|
#include "cli/cli-utils.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
static struct gdbarch_data *linux_gdbarch_data_handle;
|
static struct gdbarch_data *linux_gdbarch_data_handle;
|
||||||
|
|
||||||
|
@ -196,6 +199,332 @@ linux_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
|
||||||
return normal_pid_to_str (ptid);
|
return normal_pid_to_str (ptid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Service function for corefiles and info proc. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
read_mapping (const char *line,
|
||||||
|
ULONGEST *addr, ULONGEST *endaddr,
|
||||||
|
const char **permissions, size_t *permissions_len,
|
||||||
|
ULONGEST *offset,
|
||||||
|
const char **device, size_t *device_len,
|
||||||
|
ULONGEST *inode,
|
||||||
|
const char **filename)
|
||||||
|
{
|
||||||
|
const char *p = line;
|
||||||
|
|
||||||
|
*addr = strtoulst (p, &p, 16);
|
||||||
|
if (*p == '-')
|
||||||
|
p++;
|
||||||
|
*endaddr = strtoulst (p, &p, 16);
|
||||||
|
|
||||||
|
while (*p && isspace (*p))
|
||||||
|
p++;
|
||||||
|
*permissions = p;
|
||||||
|
while (*p && !isspace (*p))
|
||||||
|
p++;
|
||||||
|
*permissions_len = p - *permissions;
|
||||||
|
|
||||||
|
*offset = strtoulst (p, &p, 16);
|
||||||
|
|
||||||
|
while (*p && isspace (*p))
|
||||||
|
p++;
|
||||||
|
*device = p;
|
||||||
|
while (*p && !isspace (*p))
|
||||||
|
p++;
|
||||||
|
*device_len = p - *device;
|
||||||
|
|
||||||
|
*inode = strtoulst (p, &p, 10);
|
||||||
|
|
||||||
|
while (*p && isspace (*p))
|
||||||
|
p++;
|
||||||
|
*filename = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implement the "info proc" command. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
linux_info_proc (struct gdbarch *gdbarch, char *args,
|
||||||
|
enum info_proc_what what)
|
||||||
|
{
|
||||||
|
/* A long is used for pid instead of an int to avoid a loss of precision
|
||||||
|
compiler warning from the output of strtoul. */
|
||||||
|
long pid;
|
||||||
|
int cmdline_f = (what == IP_MINIMAL || what == IP_CMDLINE || what == IP_ALL);
|
||||||
|
int cwd_f = (what == IP_MINIMAL || what == IP_CWD || what == IP_ALL);
|
||||||
|
int exe_f = (what == IP_MINIMAL || what == IP_EXE || what == IP_ALL);
|
||||||
|
int mappings_f = (what == IP_MAPPINGS || what == IP_ALL);
|
||||||
|
int status_f = (what == IP_STATUS || what == IP_ALL);
|
||||||
|
int stat_f = (what == IP_STAT || what == IP_ALL);
|
||||||
|
char filename[100];
|
||||||
|
gdb_byte *data;
|
||||||
|
int target_errno;
|
||||||
|
|
||||||
|
if (args && isdigit (args[0]))
|
||||||
|
pid = strtoul (args, &args, 10);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!target_has_execution)
|
||||||
|
error (_("No current process: you must name one."));
|
||||||
|
if (current_inferior ()->fake_pid_p)
|
||||||
|
error (_("Can't determine the current process's PID: you must name one."));
|
||||||
|
|
||||||
|
pid = current_inferior ()->pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
args = skip_spaces (args);
|
||||||
|
if (args && args[0])
|
||||||
|
error (_("Too many parameters: %s"), args);
|
||||||
|
|
||||||
|
printf_filtered (_("process %ld\n"), pid);
|
||||||
|
if (cmdline_f)
|
||||||
|
{
|
||||||
|
xsnprintf (filename, sizeof filename, "/proc/%ld/cmdline", pid);
|
||||||
|
data = target_fileio_read_stralloc (filename);
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
struct cleanup *cleanup = make_cleanup (xfree, data);
|
||||||
|
printf_filtered ("cmdline = '%s'\n", data);
|
||||||
|
do_cleanups (cleanup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
warning (_("unable to open /proc file '%s'"), filename);
|
||||||
|
}
|
||||||
|
if (cwd_f)
|
||||||
|
{
|
||||||
|
xsnprintf (filename, sizeof filename, "/proc/%ld/cwd", pid);
|
||||||
|
data = target_fileio_readlink (filename, &target_errno);
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
struct cleanup *cleanup = make_cleanup (xfree, data);
|
||||||
|
printf_filtered ("cwd = '%s'\n", data);
|
||||||
|
do_cleanups (cleanup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
warning (_("unable to read link '%s'"), filename);
|
||||||
|
}
|
||||||
|
if (exe_f)
|
||||||
|
{
|
||||||
|
xsnprintf (filename, sizeof filename, "/proc/%ld/exe", pid);
|
||||||
|
data = target_fileio_readlink (filename, &target_errno);
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
struct cleanup *cleanup = make_cleanup (xfree, data);
|
||||||
|
printf_filtered ("exe = '%s'\n", data);
|
||||||
|
do_cleanups (cleanup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
warning (_("unable to read link '%s'"), filename);
|
||||||
|
}
|
||||||
|
if (mappings_f)
|
||||||
|
{
|
||||||
|
xsnprintf (filename, sizeof filename, "/proc/%ld/maps", pid);
|
||||||
|
data = target_fileio_read_stralloc (filename);
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
struct cleanup *cleanup = make_cleanup (xfree, data);
|
||||||
|
char *line;
|
||||||
|
|
||||||
|
printf_filtered (_("Mapped address spaces:\n\n"));
|
||||||
|
if (gdbarch_addr_bit (gdbarch) == 32)
|
||||||
|
{
|
||||||
|
printf_filtered ("\t%10s %10s %10s %10s %s\n",
|
||||||
|
"Start Addr",
|
||||||
|
" End Addr",
|
||||||
|
" Size", " Offset", "objfile");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf_filtered (" %18s %18s %10s %10s %s\n",
|
||||||
|
"Start Addr",
|
||||||
|
" End Addr",
|
||||||
|
" Size", " Offset", "objfile");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (line = strtok (data, "\n"); line; line = strtok (NULL, "\n"))
|
||||||
|
{
|
||||||
|
ULONGEST addr, endaddr, offset, inode;
|
||||||
|
const char *permissions, *device, *filename;
|
||||||
|
size_t permissions_len, device_len;
|
||||||
|
|
||||||
|
read_mapping (line, &addr, &endaddr,
|
||||||
|
&permissions, &permissions_len,
|
||||||
|
&offset, &device, &device_len,
|
||||||
|
&inode, &filename);
|
||||||
|
|
||||||
|
if (gdbarch_addr_bit (gdbarch) == 32)
|
||||||
|
{
|
||||||
|
printf_filtered ("\t%10s %10s %10s %10s %s\n",
|
||||||
|
paddress (gdbarch, addr),
|
||||||
|
paddress (gdbarch, endaddr),
|
||||||
|
hex_string (endaddr - addr),
|
||||||
|
hex_string (offset),
|
||||||
|
*filename? filename : "");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf_filtered (" %18s %18s %10s %10s %s\n",
|
||||||
|
paddress (gdbarch, addr),
|
||||||
|
paddress (gdbarch, endaddr),
|
||||||
|
hex_string (endaddr - addr),
|
||||||
|
hex_string (offset),
|
||||||
|
*filename? filename : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do_cleanups (cleanup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
warning (_("unable to open /proc file '%s'"), filename);
|
||||||
|
}
|
||||||
|
if (status_f)
|
||||||
|
{
|
||||||
|
xsnprintf (filename, sizeof filename, "/proc/%ld/status", pid);
|
||||||
|
data = target_fileio_read_stralloc (filename);
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
struct cleanup *cleanup = make_cleanup (xfree, data);
|
||||||
|
puts_filtered (data);
|
||||||
|
do_cleanups (cleanup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
warning (_("unable to open /proc file '%s'"), filename);
|
||||||
|
}
|
||||||
|
if (stat_f)
|
||||||
|
{
|
||||||
|
xsnprintf (filename, sizeof filename, "/proc/%ld/stat", pid);
|
||||||
|
data = target_fileio_read_stralloc (filename);
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
struct cleanup *cleanup = make_cleanup (xfree, data);
|
||||||
|
const char *p = data;
|
||||||
|
const char *ep;
|
||||||
|
ULONGEST val;
|
||||||
|
|
||||||
|
printf_filtered (_("Process: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
|
||||||
|
while (*p && isspace (*p))
|
||||||
|
p++;
|
||||||
|
if (*p == '(' && (ep = strchr (p, ')')) != NULL)
|
||||||
|
{
|
||||||
|
printf_filtered ("Exec file: %.*s\n", (int) (ep - p - 1), p + 1);
|
||||||
|
p = ep + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*p && isspace (*p))
|
||||||
|
p++;
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("State: %c\n"), *p++);
|
||||||
|
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Parent process: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Process group: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Session id: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("TTY: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("TTY owner process group: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Flags: %s\n"),
|
||||||
|
hex_string (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Minor faults (no memory page): %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Minor faults, children: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Major faults (memory page faults): %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Major faults, children: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("utime: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("stime: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("utime, children: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("stime, children: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("jiffies remaining in current "
|
||||||
|
"time slice: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("'nice' value: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("jiffies until next timeout: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("jiffies until next SIGALRM: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("start time (jiffies since "
|
||||||
|
"system boot): %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Virtual memory size: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Resident set size: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("rlim: %s\n"),
|
||||||
|
pulongest (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Start of text: %s\n"),
|
||||||
|
hex_string (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("End of text: %s\n"),
|
||||||
|
hex_string (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Start of stack: %s\n"),
|
||||||
|
hex_string (strtoulst (p, &p, 10)));
|
||||||
|
#if 0 /* Don't know how architecture-dependent the rest is...
|
||||||
|
Anyway the signal bitmap info is available from "status". */
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Kernel stack pointer: %s\n"),
|
||||||
|
hex_string (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Kernel instr pointer: %s\n"),
|
||||||
|
hex_string (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Pending signals bitmap: %s\n"),
|
||||||
|
hex_string (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Blocked signals bitmap: %s\n"),
|
||||||
|
hex_string (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Ignored signals bitmap: %s\n"),
|
||||||
|
hex_string (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("Catched signals bitmap: %s\n"),
|
||||||
|
hex_string (strtoulst (p, &p, 10)));
|
||||||
|
if (*p)
|
||||||
|
printf_filtered (_("wchan (system call): %s\n"),
|
||||||
|
hex_string (strtoulst (p, &p, 10)));
|
||||||
|
#endif
|
||||||
|
do_cleanups (cleanup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
warning (_("unable to open /proc file '%s'"), filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* To be called from the various GDB_OSABI_LINUX handlers for the
|
/* To be called from the various GDB_OSABI_LINUX handlers for the
|
||||||
various GNU/Linux architectures and machine types. */
|
various GNU/Linux architectures and machine types. */
|
||||||
|
|
||||||
|
@ -203,6 +532,7 @@ void
|
||||||
linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
set_gdbarch_core_pid_to_str (gdbarch, linux_core_pid_to_str);
|
set_gdbarch_core_pid_to_str (gdbarch, linux_core_pid_to_str);
|
||||||
|
set_gdbarch_info_proc (gdbarch, linux_info_proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue