From patchwork Thu Mar 19 23:22:38 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergio Durigan Junior X-Patchwork-Id: 5709 Received: (qmail 47014 invoked by alias); 19 Mar 2015 23:22:50 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 46910 invoked by uid 89); 19 Mar 2015 23:22:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 19 Mar 2015 23:22:47 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2JNMkGx010766 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Thu, 19 Mar 2015 19:22:46 -0400 Received: from psique.yyz.redhat.com (unused-10-15-17-126.yyz.redhat.com [10.15.17.126]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2JNMigR009833; Thu, 19 Mar 2015 19:22:45 -0400 From: Sergio Durigan Junior To: GDB Patches Cc: Pedro Alves , Sergio Durigan Junior Subject: [PATCH 2/2] Documentation and testcase Date: Thu, 19 Mar 2015 19:22:38 -0400 Message-Id: <1426807358-18295-3-git-send-email-sergiodj@redhat.com> In-Reply-To: <1426807358-18295-1-git-send-email-sergiodj@redhat.com> References: <1426807358-18295-1-git-send-email-sergiodj@redhat.com> X-IsSubscribed: yes This patch extends the documentation to include the new feature, and implements a new testcase for it. Changes from v3: - Included 'bit 5' when mentioning the default value of /proc/PID/coredump_filter. gdb/doc/ChangeLog: 2015-03-19 Sergio Durigan Junior 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-19 Sergio Durigan Junior PR corefiles/16092 * gdb.base/coredump-filter.c: New file. * gdb.base/coredump-filter.exp: Likewise. --- gdb/doc/gdb.texinfo | 33 ++++++++ gdb/testsuite/gdb.base/coredump-filter.c | 61 ++++++++++++++ gdb/testsuite/gdb.base/coredump-filter.exp | 128 +++++++++++++++++++++++++++++ 3 files changed, 222 insertions(+) create mode 100644 gdb/testsuite/gdb.base/coredump-filter.c create mode 100644 gdb/testsuite/gdb.base/coredump-filter.exp 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 . */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +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 . + +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 = \)?" \ + "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] + } +}