Re: [PATCH 4/4] Documentation and testcase

Sergio Durigan Junior
2015-03-18T20:18:42Z

On Wednesday, March 18 2015, Eli Zaretskii wrote:

>> From: Sergio Durigan Junior <sergiodj@redhat.com>
>> Cc: Pedro Alves <palves@redhat.com>, Sergio Durigan Junior <sergiodj@redhat.com>
>> Date: Wed, 18 Mar 2015 15:38:43 -0400
>>
>> This patch extends the documentation to include the new feature, and
>> implements a new testcase for it.
>
> Thanks, the docs are OK.

Thanks.

>> +value is currently @code{0x33}, which means that bits @code{0}
>> +(anonymous private mappings), @code{1} (anonymous shared mappings) and
>> +@code{4} (ELF headers) are active.
>
> What happened to bit 5?

Same mistake that I made on the first e-mail. Fixed now.

Thanks,

--
Sergio
GPG key ID: 0x65FC5E36
Please send encrypted e-mail if possible
http://sergiodj.net/

gdb/doc/ChangeLog:
2015-03-18 Sergio Durigan Junior <sergiodj@redhat.com>

PR corefiles/16092
* gdb.texinfo (gcore): Mention new command 'set
use-coredump-filter'.
(set use-coredump-filter): Document new command.

gdb/testsuite/ChangeLog:
2015-03-18 Sergio Durigan Junior <sergiodj@redhat.com>

PR corefiles/16092
* gdb.base/coredump-filter.c: New file.
* gdb.base/coredump-filter.exp: Likewise.

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 552da31..5382e91 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -10952,6 +10952,39 @@ specified, the file name defaults to @file{core.@var{pid}}, where

Note that this command is implemented only for some systems (as of
this writing, @sc{gnu}/Linux, FreeBSD, Solaris, and S390).
+
+On @sc{gnu}/Linux, this command can take into account the value of the
+file @file{/proc/@var{pid}/coredump_filter} when generating the core
+dump (@pxref{set use-coredump-filter}).
+
+@kindex set use-coredump-filter
+@anchor{set use-coredump-filter}
+@item set use-coredump-filter on
+@itemx set use-coredump-filter off
+Enable or disable the use of the file
+@file{/proc/@var{pid}/coredump_filter} when generating core dump
+files. This file is used by the Linux kernel to decide what types of
+memory mappings will be dumped or ignored when generating a core dump
+file. @var{pid} is the process ID of a currently running process.
+
+
+To make use of this feature, you have to write in the
+@file{/proc/@var{pid}/coredump_filter} file a value, in hexadecimal,
+which is a bit mask representing the memory mapping types. If a bit
+is set in the bit mask, then the memory mappings of the corresponding
+types will be dumped; otherwise, they will be ignored. For more
+information about the bits that can be set in the
+@file{/proc/@var{pid}/coredump_filter} file, please refer to the
+manpage of @code{core(5)}.
+
+By default, this option is @code{on}. If this option is turned
+@code{off}, @value{GDBN} does not read the @file{coredump_filter} file
+and instead uses the same default value as the Linux kernel in order
+to decide which pages will be dumped in the core dump file. This
+value is currently @code{0x33}, which means that bits @code{0}
+(anonymous private mappings), @code{1} (anonymous shared mappings),
+@code{4} (ELF headers) and @code{5} (private huge pages) are active.
+This will cause these memory mappings to be dumped automatically.
@end table

@node Character Sets
diff --git a/gdb/testsuite/gdb.base/coredump-filter.c b/gdb/testsuite/gdb.base/coredump-filter.c
new file mode 100644
index 0000000..192c469
--- /dev/null
+++ b/gdb/testsuite/gdb.base/coredump-filter.c
@@ -0,0 +1,61 @@
+/* Copyright 2015 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <string.h>
+
+static void *
+do_mmap (void *addr, size_t size, int prot, int flags, int fd, off_t offset)
+{
+ void *ret = mmap (addr, size, prot, flags, fd, offset);
+
+ assert (ret != NULL);
+ return ret;
+}
+
+int
+main (int argc, char *argv[])
+{
+ const size_t size = 10;
+ const int default_prot = PROT_READ | PROT_WRITE;
+ char *private_anon, *shared_anon;
+ char *dont_dump;
+ int i;
+
+ private_anon = do_mmap (NULL, size, default_prot,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ memset (private_anon, 0x11, size);
+
+ shared_anon = do_mmap (NULL, size, default_prot,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ memset (shared_anon, 0x22, size);
+
+ dont_dump = do_mmap (NULL, size, default_prot,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ memset (dont_dump, 0x55, size);
+ i = madvise (dont_dump, size, MADV_DONTDUMP);
+ assert_perror (errno);
+ assert (i == 0);
+
+ return 0; /* break-here */
+}
diff --git a/gdb/testsuite/gdb.base/coredump-filter.exp b/gdb/testsuite/gdb.base/coredump-filter.exp
new file mode 100644
index 0000000..b7eb74d
--- /dev/null
+++ b/gdb/testsuite/gdb.base/coredump-filter.exp
@@ -0,0 +1,128 @@
+# Copyright 2015 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+standard_testfile
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile debug] } {
+ untested "could not compile test program"
+ return -1
+}
+
+if { ![runto_main] } {
+ untested "could not run to main"
+ return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "break-here"]
+gdb_continue_to_breakpoint "break-here" ".* break-here .*"
+
+proc do_save_core { filter_flag core ipid } {
+ verbose -log "writing $filter_flag to /proc/$ipid/coredump_filter"
+
+ remote_exec target "sh -c \"echo $filter_flag > /proc/$ipid/coredump_filter\""
+
+ # Generate a corefile
+ gdb_gcore_cmd "$core" "save corefile"
+}
+
+proc do_load_and_test_core { core var working_var working_value } {
+ global hex decimal addr
+
+ set core_loaded [gdb_core_cmd "$core" "load core"]
+ if { $core_loaded == -1 } {
+ fail "loading $core"
+ return
+ }
+
+ # The variables are 'char', and using it here would be OK because
+ # GDB actually reads the contents of the memory (i.e., it
+ # dereferences the pointer). However, to make it clear that we
+ # are interested not in the pointer itself, but in the memory it
+ # points to, we are using '*(unsigned int *)'.
+ gdb_test "print *(unsigned int *) $addr($var)" "\(\\\$$decimal = <error: \)?Cannot access memory at address $hex\(>\)?" \
+ "printing $var when core is loaded (should not work)"
+ gdb_test "print/x *(unsigned int *) $addr($working_var)" " = $working_value.*" \
+ "print/x *$working_var ( = $working_value)"
+}
+
+set non_private_anon_core [standard_output_file non-private-anon.gcore]
+set non_shared_anon_core [standard_output_file non-shared-anon.gcore]
+set dont_dump_core [standard_output_file dont-dump.gcore]
+
+# We will generate a few corefiles.
+#
+# This list is composed by sub-lists, and their elements are (in
+# order):
+#
+# - name of the test
+# - hexadecimal value to be put in the /proc/PID/coredump_filter file
+# - name of the variable that contains the name of the corefile to be
+# generated (including the initial $).
+# - name of the variable in the C source code that points to the
+# memory mapping that will NOT be present in the corefile.
+# - name of a variable in the C source code that points to a memory
+# mapping that WILL be present in the corefile
+# - corresponding value expected for the above variable
+
+set all_corefiles { { "non-Private-Anonymous" "0x7e" \
+ $non_private_anon_core \
+ "private_anon" \
+ "shared_anon" "0x22" }
+ { "non-Shared-Anonymous" "0x7d" \
+ $non_shared_anon_core "shared_anon" \
+ "private_anon" "0x11" }
+ { "DoNotDump" "0x33" \
+ $dont_dump_core "dont_dump" \
+ "shared_anon" "0x22" } }
+
+set core_supported [gdb_gcore_cmd "$non_private_anon_core" "save a corefile"]
+if { !$core_supported } {
+ untested "corefile generation is not supported"
+ return -1
+}
+
+# Getting the inferior's PID
+set infpid ""
+gdb_test_multiple "info inferiors" "getting inferior pid" {
+ -re "process \($decimal\).*\r\n$gdb_prompt $" {
+ set infpid $expect_out(1,string)
+ }
+}
+
+foreach item $all_corefiles {
+ foreach name [list [lindex $item 3] [lindex $item 4]] {
+ set test "print/x $name"
+ gdb_test_multiple $test $test {
+ -re " = \($hex\)\r\n$gdb_prompt $" {
+ set addr($name) $expect_out(1,string)
+ }
+ }
+ }
+}
+
+foreach item $all_corefiles {
+ with_test_prefix "saving corefile for [lindex $item 0]" {
+ do_save_core [lindex $item 1] [subst [lindex $item 2]] $infpid
+ }
+}
+
+clean_restart $testfile
+
+foreach item $all_corefiles {
+ with_test_prefix "loading and testing corefile for [lindex $item 0]" {
+ do_load_and_test_core [subst [lindex $item 2]] [lindex $item 3] \
+ [lindex $item 4] [lindex $item 5]
+ }
+}