/* Target-dependent code for GNU/Linux, architecture independent.
- Copyright (C) 2009-2017 Free Software Foundation, Inc.
+ Copyright (C) 2009-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "cli/cli-utils.h"
#include "arch-utils.h"
#include "gdb_obstack.h"
-#include "observer.h"
+#include "observable.h"
#include "objfiles.h"
#include "infcall.h"
#include "gdbcmd.h"
static int use_coredump_filter = 1;
+/* Whether the value of smaps_vmflags->exclude_coredump should be
+ ignored, including mappings marked with the VM_DONTDUMP flag in
+ the dump. */
+static int dump_excluded_mappings = 0;
+
/* This enum represents the signals' numbers on a generic architecture
running the Linux kernel. The definition of "generic" comes from
the file <include/uapi/asm-generic/signal.h>, from the Linux kernel
/* __pid_t */
pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
- TYPE_LENGTH (int_type), "__pid_t");
+ TYPE_LENGTH (int_type) * TARGET_CHAR_BIT, "__pid_t");
TYPE_TARGET_TYPE (pid_type) = int_type;
TYPE_TARGET_STUB (pid_type) = 1;
/* __uid_t */
uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
- TYPE_LENGTH (uint_type), "__uid_t");
+ TYPE_LENGTH (uint_type) * TARGET_CHAR_BIT, "__uid_t");
TYPE_TARGET_TYPE (uid_type) = uint_type;
TYPE_TARGET_STUB (uid_type) = 1;
/* __clock_t */
clock_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
- TYPE_LENGTH (long_type), "__clock_t");
+ TYPE_LENGTH (long_type) * TARGET_CHAR_BIT,
+ "__clock_t");
TYPE_TARGET_TYPE (clock_type) = long_type;
TYPE_TARGET_STUB (clock_type) = 1;
p++;
*endaddr = strtoulst (p, &p, 16);
- p = skip_spaces_const (p);
+ p = skip_spaces (p);
*permissions = p;
while (*p && !isspace (*p))
p++;
*offset = strtoulst (p, &p, 16);
- p = skip_spaces_const (p);
+ p = skip_spaces (p);
*device = p;
while (*p && !isspace (*p))
p++;
*inode = strtoulst (p, &p, 10);
- p = skip_spaces_const (p);
+ p = skip_spaces (p);
*filename = p;
}
return 0;
/* Check if we should exclude this mapping. */
- if (v->exclude_coredump)
+ if (!dump_excluded_mappings && v->exclude_coredump)
return 0;
/* Update our notion of whether this mapping is shared or
pid = current_inferior ()->pid;
}
- args = skip_spaces_const (args);
+ args = skip_spaces (args);
if (args && args[0])
error (_("Too many parameters: %s"), args);
if (cmdline_f)
{
xsnprintf (filename, sizeof filename, "/proc/%ld/cmdline", pid);
- data = target_fileio_read_stralloc (NULL, filename);
- if (data)
+ gdb_byte *buffer;
+ ssize_t len = target_fileio_read_alloc (NULL, filename, &buffer);
+
+ if (len > 0)
{
- struct cleanup *cleanup = make_cleanup (xfree, data);
- printf_filtered ("cmdline = '%s'\n", data);
- do_cleanups (cleanup);
+ gdb::unique_xmalloc_ptr<char> cmdline ((char *) buffer);
+ ssize_t pos;
+
+ for (pos = 0; pos < len - 1; pos++)
+ {
+ if (buffer[pos] == '\0')
+ buffer[pos] = ' ';
+ }
+ buffer[len - 1] = '\0';
+ printf_filtered ("cmdline = '%s'\n", buffer);
}
else
warning (_("unable to open /proc file '%s'"), filename);
if (cwd_f)
{
xsnprintf (filename, sizeof filename, "/proc/%ld/cwd", pid);
- data = target_fileio_readlink (NULL, filename, &target_errno);
- if (data)
- {
- struct cleanup *cleanup = make_cleanup (xfree, data);
- printf_filtered ("cwd = '%s'\n", data);
- do_cleanups (cleanup);
- }
+ gdb::optional<std::string> contents
+ = target_fileio_readlink (NULL, filename, &target_errno);
+ if (contents.has_value ())
+ printf_filtered ("cwd = '%s'\n", contents->c_str ());
else
warning (_("unable to read link '%s'"), filename);
}
if (exe_f)
{
xsnprintf (filename, sizeof filename, "/proc/%ld/exe", pid);
- data = target_fileio_readlink (NULL, filename, &target_errno);
- if (data)
- {
- struct cleanup *cleanup = make_cleanup (xfree, data);
- printf_filtered ("exe = '%s'\n", data);
- do_cleanups (cleanup);
- }
+ gdb::optional<std::string> contents
+ = target_fileio_readlink (NULL, filename, &target_errno);
+ if (contents.has_value ())
+ printf_filtered ("exe = '%s'\n", contents->c_str ());
else
warning (_("unable to read link '%s'"), filename);
}
if (mappings_f)
{
xsnprintf (filename, sizeof filename, "/proc/%ld/maps", pid);
- data = target_fileio_read_stralloc (NULL, filename);
- if (data)
+ gdb::unique_xmalloc_ptr<char> map
+ = target_fileio_read_stralloc (NULL, filename);
+ if (map != NULL)
{
- struct cleanup *cleanup = make_cleanup (xfree, data);
char *line;
printf_filtered (_("Mapped address spaces:\n\n"));
" Size", " Offset", "objfile");
}
- for (line = strtok (data, "\n"); line; line = strtok (NULL, "\n"))
+ for (line = strtok (map.get (), "\n");
+ line;
+ line = strtok (NULL, "\n"))
{
ULONGEST addr, endaddr, offset, inode;
const char *permissions, *device, *filename;
*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 (NULL, filename);
- if (data)
- {
- struct cleanup *cleanup = make_cleanup (xfree, data);
- puts_filtered (data);
- do_cleanups (cleanup);
- }
+ gdb::unique_xmalloc_ptr<char> status
+ = target_fileio_read_stralloc (NULL, filename);
+ if (status)
+ puts_filtered (status.get ());
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 (NULL, filename);
- if (data)
+ gdb::unique_xmalloc_ptr<char> statstr
+ = target_fileio_read_stralloc (NULL, filename);
+ if (statstr)
{
- struct cleanup *cleanup = make_cleanup (xfree, data);
- const char *p = data;
+ const char *p = statstr.get ();
printf_filtered (_("Process: %s\n"),
pulongest (strtoulst (p, &p, 10)));
- p = skip_spaces_const (p);
+ p = skip_spaces (p);
if (*p == '(')
{
/* ps command also relies on no trailing fields
}
}
- p = skip_spaces_const (p);
+ p = skip_spaces (p);
if (*p)
printf_filtered (_("State: %c\n"), *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);
{
asection *section;
ULONGEST count, page_size;
- unsigned char *descdata, *filenames, *descend, *contents;
+ unsigned char *descdata, *filenames, *descend;
size_t note_size;
unsigned int addr_size_bits, addr_size;
- struct cleanup *cleanup;
struct gdbarch *core_gdbarch = gdbarch_from_bfd (core_bfd);
/* We assume this for reading 64-bit core files. */
gdb_static_assert (sizeof (ULONGEST) >= 8);
if (note_size < 2 * addr_size)
error (_("malformed core note - too short for header"));
- contents = (unsigned char *) xmalloc (note_size);
- cleanup = make_cleanup (xfree, contents);
- if (!bfd_get_section_contents (core_bfd, section, contents, 0, note_size))
+ gdb::def_vector<unsigned char> contents (note_size);
+ if (!bfd_get_section_contents (core_bfd, section, contents.data (),
+ 0, note_size))
error (_("could not get core note contents"));
- descdata = contents;
+ descdata = contents.data ();
descend = descdata + note_size;
if (descdata[note_size - 1] != '\0')
filenames += 1 + strlen ((char *) filenames);
}
-
- do_cleanups (cleanup);
}
/* Implement "info proc" for a corefile. */
{
char mapsfilename[100];
char coredumpfilter_name[100];
- char *data, *coredumpfilterdata;
pid_t pid;
/* Default dump behavior of coredump_filter (0x33), according to
Documentation/filesystems/proc.txt from the Linux kernel
{
xsnprintf (coredumpfilter_name, sizeof (coredumpfilter_name),
"/proc/%d/coredump_filter", pid);
- coredumpfilterdata = target_fileio_read_stralloc (NULL,
- coredumpfilter_name);
+ gdb::unique_xmalloc_ptr<char> coredumpfilterdata
+ = target_fileio_read_stralloc (NULL, coredumpfilter_name);
if (coredumpfilterdata != NULL)
{
unsigned int flags;
- sscanf (coredumpfilterdata, "%x", &flags);
+ sscanf (coredumpfilterdata.get (), "%x", &flags);
filterflags = (enum filter_flag) flags;
- xfree (coredumpfilterdata);
}
}
xsnprintf (mapsfilename, sizeof mapsfilename, "/proc/%d/smaps", pid);
- data = target_fileio_read_stralloc (NULL, mapsfilename);
+ gdb::unique_xmalloc_ptr<char> data
+ = target_fileio_read_stralloc (NULL, mapsfilename);
if (data == NULL)
{
/* Older Linux kernels did not support /proc/PID/smaps. */
if (data != NULL)
{
- struct cleanup *cleanup = make_cleanup (xfree, data);
char *line, *t;
- line = strtok_r (data, "\n", &t);
+ line = strtok_r (data.get (), "\n", &t);
while (line != NULL)
{
ULONGEST addr, endaddr, offset, inode;
filename, obfd);
}
- do_cleanups (cleanup);
return 0;
}
};
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
- gdb_byte *spu_ids;
- LONGEST i, j, size;
/* Determine list of SPU ids. */
- size = target_read_alloc (¤t_target, TARGET_OBJECT_SPU,
- NULL, &spu_ids);
+ gdb::optional<gdb::byte_vector>
+ spu_ids = target_read_alloc (¤t_target, TARGET_OBJECT_SPU, NULL);
+
+ if (!spu_ids)
+ return note_data;
/* Generate corefile notes for each SPU file. */
- for (i = 0; i < size; i += 4)
+ for (size_t i = 0; i < spu_ids->size (); i += 4)
{
- int fd = extract_unsigned_integer (spu_ids + i, 4, byte_order);
+ int fd = extract_unsigned_integer (spu_ids->data () + i, 4, byte_order);
- for (j = 0; j < sizeof (spu_files) / sizeof (spu_files[0]); j++)
+ for (size_t j = 0; j < sizeof (spu_files) / sizeof (spu_files[0]); j++)
{
char annex[32], note_name[32];
- gdb_byte *spu_data;
- LONGEST spu_len;
xsnprintf (annex, sizeof annex, "%d/%s", fd, spu_files[j]);
- spu_len = target_read_alloc (¤t_target, TARGET_OBJECT_SPU,
- annex, &spu_data);
- if (spu_len > 0)
+ gdb::optional<gdb::byte_vector> spu_data
+ = target_read_alloc (¤t_target, TARGET_OBJECT_SPU, annex);
+
+ if (spu_data && !spu_data->empty ())
{
xsnprintf (note_name, sizeof note_name, "SPU/%s", annex);
note_data = elfcore_write_note (obfd, note_data, note_size,
note_name, NT_SPU,
- spu_data, spu_len);
- xfree (spu_data);
+ spu_data->data (),
+ spu_data->size ());
if (!note_data)
- {
- xfree (spu_ids);
- return NULL;
- }
+ return nullptr;
}
}
}
- if (size > 0)
- xfree (spu_ids);
-
return note_data;
}
linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd,
char *note_data, int *note_size)
{
- struct cleanup *cleanup;
struct linux_make_mappings_data mapping_data;
struct type *long_type
= arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch), 0, "long");
char *note_data, int *note_size,
enum gdb_signal stop_signal)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct linux_collect_regset_section_cb_data data;
data.gdbarch = gdbarch;
}
/* Fetch the siginfo data for the specified thread, if it exists. If
- there is no data, or we could not read it, return NULL. Otherwise,
- return a newly malloc'd buffer holding the data and fill in *SIZE
- with the size of the data. The caller is responsible for freeing
- the data. */
-
-static gdb_byte *
-linux_get_siginfo_data (thread_info *thread, struct gdbarch *gdbarch,
- LONGEST *size)
+ there is no data, or we could not read it, return an empty
+ buffer. */
+
+static gdb::byte_vector
+linux_get_siginfo_data (thread_info *thread, struct gdbarch *gdbarch)
{
struct type *siginfo_type;
- gdb_byte *buf;
LONGEST bytes_read;
- struct cleanup *cleanups;
if (!gdbarch_get_siginfo_type_p (gdbarch))
- return NULL;
-
+ return gdb::byte_vector ();
+
scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
inferior_ptid = thread->ptid;
siginfo_type = gdbarch_get_siginfo_type (gdbarch);
- buf = (gdb_byte *) xmalloc (TYPE_LENGTH (siginfo_type));
- cleanups = make_cleanup (xfree, buf);
+ gdb::byte_vector buf (TYPE_LENGTH (siginfo_type));
bytes_read = target_read (¤t_target, TARGET_OBJECT_SIGNAL_INFO, NULL,
- buf, 0, TYPE_LENGTH (siginfo_type));
- if (bytes_read == TYPE_LENGTH (siginfo_type))
- {
- discard_cleanups (cleanups);
- *size = bytes_read;
- }
- else
- {
- do_cleanups (cleanups);
- buf = NULL;
- }
+ buf.data (), 0, TYPE_LENGTH (siginfo_type));
+ if (bytes_read != TYPE_LENGTH (siginfo_type))
+ buf.clear ();
return buf;
}
linux_corefile_thread (struct thread_info *info,
struct linux_corefile_thread_data *args)
{
- struct cleanup *old_chain;
struct regcache *regcache;
- gdb_byte *siginfo_data;
- LONGEST siginfo_size = 0;
regcache = get_thread_arch_regcache (info->ptid, args->gdbarch);
target_fetch_registers (regcache, -1);
- siginfo_data = linux_get_siginfo_data (info, args->gdbarch, &siginfo_size);
-
- old_chain = make_cleanup (xfree, siginfo_data);
+ gdb::byte_vector siginfo_data = linux_get_siginfo_data (info, args->gdbarch);
args->note_data = linux_collect_thread_registers
(regcache, info->ptid, args->obfd, args->note_data,
/* Don't return anything if we got no register information above,
such a core file is useless. */
if (args->note_data != NULL)
- if (siginfo_data != NULL)
+ if (!siginfo_data.empty ())
args->note_data = elfcore_write_note (args->obfd,
args->note_data,
args->note_size,
"CORE", NT_SIGINFO,
- siginfo_data, siginfo_size);
-
- do_cleanups (old_chain);
+ siginfo_data.data (),
+ siginfo_data.size ());
}
/* Fill the PRPSINFO structure with information about the process being
/* The filename which we will use to obtain some info about the process.
We will basically use this to store the `/proc/PID/FILENAME' file. */
char filename[100];
- /* The full name of the program which generated the corefile. */
- char *fname;
/* The basename of the executable. */
const char *basename;
- /* The arguments of the program. */
- char *psargs;
char *infargs;
- /* The contents of `/proc/PID/stat' and `/proc/PID/status' files. */
- char *proc_stat, *proc_status;
/* Temporary buffer. */
char *tmpstr;
/* The valid states of a process, according to the Linux kernel. */
long pr_nice;
/* The number of fields read by `sscanf'. */
int n_fields = 0;
- /* Cleanups. */
- struct cleanup *c;
gdb_assert (p != NULL);
/* Obtaining PID and filename. */
pid = ptid_get_pid (inferior_ptid);
xsnprintf (filename, sizeof (filename), "/proc/%d/cmdline", (int) pid);
- fname = target_fileio_read_stralloc (NULL, filename);
+ /* The full name of the program which generated the corefile. */
+ gdb::unique_xmalloc_ptr<char> fname
+ = target_fileio_read_stralloc (NULL, filename);
- if (fname == NULL || *fname == '\0')
+ if (fname == NULL || fname.get ()[0] == '\0')
{
/* No program name was read, so we won't be able to retrieve more
information about the process. */
- xfree (fname);
return 0;
}
- c = make_cleanup (xfree, fname);
memset (p, 0, sizeof (*p));
/* Defining the PID. */
p->pr_pid = pid;
/* Copying the program name. Only the basename matters. */
- basename = lbasename (fname);
+ basename = lbasename (fname.get ());
strncpy (p->pr_fname, basename, sizeof (p->pr_fname));
p->pr_fname[sizeof (p->pr_fname) - 1] = '\0';
infargs = get_inferior_args ();
- psargs = xstrdup (fname);
+ /* The arguments of the program. */
+ std::string psargs = fname.get ();
if (infargs != NULL)
- psargs = reconcat (psargs, psargs, " ", infargs, (char *) NULL);
+ psargs = psargs + " " + infargs;
- make_cleanup (xfree, psargs);
-
- strncpy (p->pr_psargs, psargs, sizeof (p->pr_psargs));
+ strncpy (p->pr_psargs, psargs.c_str (), sizeof (p->pr_psargs));
p->pr_psargs[sizeof (p->pr_psargs) - 1] = '\0';
xsnprintf (filename, sizeof (filename), "/proc/%d/stat", (int) pid);
- proc_stat = target_fileio_read_stralloc (NULL, filename);
- make_cleanup (xfree, proc_stat);
+ /* The contents of `/proc/PID/stat'. */
+ gdb::unique_xmalloc_ptr<char> proc_stat_contents
+ = target_fileio_read_stralloc (NULL, filename);
+ char *proc_stat = proc_stat_contents.get ();
if (proc_stat == NULL || *proc_stat == '\0')
{
/* Despite being unable to read more information about the
process, we return 1 here because at least we have its
command line, PID and arguments. */
- do_cleanups (c);
return 1;
}
/* ps command also relies on no trailing fields ever contain ')'. */
proc_stat = strrchr (proc_stat, ')');
if (proc_stat == NULL)
- {
- do_cleanups (c);
- return 1;
- }
+ return 1;
proc_stat++;
proc_stat = skip_spaces (proc_stat);
/* Again, we couldn't read the complementary information about
the process state. However, we already have minimal
information, so we just return 1 here. */
- do_cleanups (c);
return 1;
}
/* Finally, obtaining the UID and GID. For that, we read and parse the
contents of the `/proc/PID/status' file. */
xsnprintf (filename, sizeof (filename), "/proc/%d/status", (int) pid);
- proc_status = target_fileio_read_stralloc (NULL, filename);
- make_cleanup (xfree, proc_status);
+ /* The contents of `/proc/PID/status'. */
+ gdb::unique_xmalloc_ptr<char> proc_status_contents
+ = target_fileio_read_stralloc (NULL, filename);
+ char *proc_status = proc_status_contents.get ();
if (proc_status == NULL || *proc_status == '\0')
{
/* Returning 1 since we already have a bunch of information. */
- do_cleanups (c);
return 1;
}
p->pr_gid = strtol (tmpstr, &tmpstr, 10);
}
- do_cleanups (c);
-
return 1;
}
struct linux_corefile_thread_data thread_args;
struct elf_internal_linux_prpsinfo prpsinfo;
char *note_data = NULL;
- gdb_byte *auxv;
- int auxv_len;
struct thread_info *curr_thr, *signalled_thr, *thr;
if (! gdbarch_iterate_over_regset_sections_p (gdbarch))
if (linux_fill_prpsinfo (&prpsinfo))
{
- if (gdbarch_elfcore_write_linux_prpsinfo_p (gdbarch))
- {
- note_data = gdbarch_elfcore_write_linux_prpsinfo (gdbarch, obfd,
- note_data, note_size,
- &prpsinfo);
- }
+ if (gdbarch_ptr_bit (gdbarch) == 64)
+ note_data = elfcore_write_linux_prpsinfo64 (obfd,
+ note_data, note_size,
+ &prpsinfo);
else
- {
- if (gdbarch_ptr_bit (gdbarch) == 64)
- note_data = elfcore_write_linux_prpsinfo64 (obfd,
- note_data, note_size,
- &prpsinfo);
- else
- note_data = elfcore_write_linux_prpsinfo32 (obfd,
- note_data, note_size,
- &prpsinfo);
- }
+ note_data = elfcore_write_linux_prpsinfo32 (obfd,
+ note_data, note_size,
+ &prpsinfo);
}
/* Thread register information. */
return NULL;
/* Auxillary vector. */
- auxv_len = target_read_alloc (¤t_target, TARGET_OBJECT_AUXV,
- NULL, &auxv);
- if (auxv_len > 0)
+ gdb::optional<gdb::byte_vector> auxv =
+ target_read_alloc (¤t_target, TARGET_OBJECT_AUXV, NULL);
+ if (auxv && !auxv->empty ())
{
note_data = elfcore_write_note (obfd, note_data, note_size,
- "CORE", NT_AUXV, auxv, auxv_len);
- xfree (auxv);
+ "CORE", NT_AUXV, auxv->data (),
+ auxv->size ());
if (!note_data)
return NULL;
{
char filename[100];
long pid;
- char *data;
if (target_auxv_search (¤t_target, AT_SYSINFO_EHDR, &range->start) <= 0)
return 0;
takes several seconds. Also note that "smaps", what we read for
determining core dump mappings, is even slower than "maps". */
xsnprintf (filename, sizeof filename, "/proc/%ld/task/%ld/maps", pid, pid);
- data = target_fileio_read_stralloc (NULL, filename);
+ gdb::unique_xmalloc_ptr<char> data
+ = target_fileio_read_stralloc (NULL, filename);
if (data != NULL)
{
- struct cleanup *cleanup = make_cleanup (xfree, data);
char *line;
char *saveptr = NULL;
- for (line = strtok_r (data, "\n", &saveptr);
+ for (line = strtok_r (data.get (), "\n", &saveptr);
line != NULL;
line = strtok_r (NULL, "\n", &saveptr))
{
p++;
endaddr = strtoulst (p, &p, 16);
range->length = endaddr - addr;
- do_cleanups (cleanup);
return 1;
}
}
-
- do_cleanups (cleanup);
}
else
warning (_("unable to open /proc file '%s'"), filename);
arg[ARG_FD] = value_from_longest (builtin_type (gdbarch)->builtin_int, -1);
arg[ARG_OFFSET] = value_from_longest (builtin_type (gdbarch)->builtin_int64,
0);
- addr_val = call_function_by_hand (mmap_val, ARG_LAST, arg);
+ addr_val = call_function_by_hand (mmap_val, NULL, ARG_LAST, arg);
retval = value_as_address (addr_val);
if (retval == (CORE_ADDR) -1)
error (_("Failed inferior mmap call for %s bytes, errno is changed."),
/* Assuming sizeof (unsigned long) == sizeof (size_t). */
arg[ARG_LENGTH] = value_from_ulongest
(builtin_type (gdbarch)->builtin_unsigned_long, size);
- retval_val = call_function_by_hand (munmap_val, ARG_LAST, arg);
+ retval_val = call_function_by_hand (munmap_val, NULL, ARG_LAST, arg);
retval = value_as_long (retval_val);
if (retval != 0)
warning (_("Failed inferior munmap call at %s for %s bytes, "
" corefiles is %s.\n"), value);
}
+/* Display whether the gcore command is dumping mappings marked with
+ the VM_DONTDUMP flag. */
+
+static void
+show_dump_excluded_mappings (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Dumping of mappings marked with the VM_DONTDUMP"
+ " flag is %s.\n"), value);
+}
+
/* To be called from the various GDB_OSABI_LINUX handlers for the
various GNU/Linux architectures and machine types. */
set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
}
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_linux_tdep;
-
void
_initialize_linux_tdep (void)
{
linux_inferior_data
= register_inferior_data_with_cleanup (NULL, linux_inferior_data_cleanup);
/* Observers used to invalidate the cache when needed. */
- observer_attach_inferior_exit (invalidate_linux_cache_inf);
- observer_attach_inferior_appeared (invalidate_linux_cache_inf);
+ gdb::observers::inferior_exit.attach (invalidate_linux_cache_inf);
+ gdb::observers::inferior_appeared.attach (invalidate_linux_cache_inf);
add_setshow_boolean_cmd ("use-coredump-filter", class_files,
&use_coredump_filter, _("\
about this file, refer to the manpage of core(5)."),
NULL, show_use_coredump_filter,
&setlist, &showlist);
+
+ add_setshow_boolean_cmd ("dump-excluded-mappings", class_files,
+ &dump_excluded_mappings, _("\
+Set whether gcore should dump mappings marked with the VM_DONTDUMP flag."),
+ _("\
+Show whether gcore should dump mappings marked with the VM_DONTDUMP flag."),
+ _("\
+Use this command to set whether gcore should dump mappings marked with the\n\
+VM_DONTDUMP flag (\"dd\" in /proc/PID/smaps) when generating the corefile. For\n\
+more information about this file, refer to the manpage of proc(5) and core(5)."),
+ NULL, show_dump_excluded_mappings,
+ &setlist, &showlist);
}