From patchwork Wed Mar 18 20:18:30 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: 5689 Received: (qmail 109426 invoked by alias); 18 Mar 2015 20:18:42 -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 109061 invoked by uid 89); 18 Mar 2015 20:18:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No 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; Wed, 18 Mar 2015 20:18:34 +0000 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2IKIVtR014562 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 18 Mar 2015 16:18:31 -0400 Received: from localhost (unused-10-15-17-126.yyz.redhat.com [10.15.17.126]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2IKIUaB016278 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Wed, 18 Mar 2015 16:18:31 -0400 From: Sergio Durigan Junior To: Eli Zaretskii Cc: gdb-patches@sourceware.org, palves@redhat.com Subject: Re: [PATCH 4/4] Documentation and testcase References: <1426707523-6499-1-git-send-email-sergiodj@redhat.com> <1426707523-6499-5-git-send-email-sergiodj@redhat.com> <83wq2evzkv.fsf@gnu.org> X-URL: http://blog.sergiodj.net Date: Wed, 18 Mar 2015 16:18:30 -0400 In-Reply-To: <83wq2evzkv.fsf@gnu.org> (Eli Zaretskii's message of "Wed, 18 Mar 2015 22:08:00 +0200") Message-ID: <874mpi3vqh.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes On Wednesday, March 18 2015, Eli Zaretskii wrote: >> From: Sergio Durigan Junior >> Cc: Pedro Alves , Sergio Durigan Junior >> 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, 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] + } +}