From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 130989 invoked by alias); 25 Jul 2018 22:47:26 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 130882 invoked by uid 89); 25 Jul 2018 22:47:25 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.1 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT,SPF_PASS autolearn=ham version=3.3.2 spammy=threw X-HELO: sesbmg23.ericsson.net Received: from sesbmg23.ericsson.net (HELO sesbmg23.ericsson.net) (193.180.251.37) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 25 Jul 2018 22:47:23 +0000 DKIM-Signature: v=1; a=rsa-sha256; d=ericsson.com; s=mailgw201801; c=relaxed/simple; q=dns/txt; i=@ericsson.com; t=1532558840; h=From:Sender:Reply-To:Subject:Date:Message-Id:To:CC:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=w5AZ8hIjXBC7XIw73JBltXPZSFuGHnHXZJZQmqxJMTY=; b=TgvGS8nsjxJDB7dAKMj5nBarhtdG+DCW8gRd++aV/VK6woVqGwOMHXbBlj0/AMKd WHydhtlGW+x38x19h3sBHJveDME53HN0AI1B9sAeKiDqfqpXRxfbW3fICEi92TZA pHJXZm73juipIYo99eK8/rNUopU0aq7puDzsnSozuOc=; Received: from ESESSMB504.ericsson.se (Unknown_Domain [153.88.183.122]) by sesbmg23.ericsson.net (Symantec Mail Security) with SMTP id F8.6A.27833.8FDF85B5; Thu, 26 Jul 2018 00:47:20 +0200 (CEST) Received: from ESESBMR502.ericsson.se (153.88.183.134) by ESESSMB504.ericsson.se (153.88.183.122) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Thu, 26 Jul 2018 00:47:20 +0200 Received: from ESESSMB502.ericsson.se (153.88.183.163) by ESESBMR502.ericsson.se (153.88.183.134) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Thu, 26 Jul 2018 00:47:20 +0200 Received: from NAM01-SN1-obe.outbound.protection.outlook.com (153.88.183.157) by ESESSMB502.ericsson.se (153.88.183.163) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3 via Frontend Transport; Thu, 26 Jul 2018 00:47:19 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ericsson.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=8M37knLiwKex1kq9fIj799TEeW1HQH++uSUJ3+eeHIM=; b=HWfZevxb8GFoymB9C4lCu4Dg/ZNaDl2R0Ob9/8NxGRHIqodgpl+3eTB7MWYZhCvnUyP5OkxY5lmpbUJaWkXUEk1EigYV5RBd5dZpIC+OdMcTcOP1v8pYsXEIk/ZC8RwUziGhP8slBJ9dRBBbCFthHlCcj/9BOazCN25Dqcn0I5k= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=simon.marchi@ericsson.com; Received: from elxacz23q12.ericsson.se (129.192.64.65) by DM6PR15MB2396.namprd15.prod.outlook.com (2603:10b6:5:8d::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.973.21; Wed, 25 Jul 2018 22:47:18 +0000 From: Simon Marchi To: CC: Simon Marchi Subject: [PATCH v2 2/4] Introduce mmap_file function Date: Wed, 25 Jul 2018 22:47:00 -0000 Message-Id: <1532558824-829-3-git-send-email-simon.marchi@ericsson.com> In-Reply-To: <1532558824-829-1-git-send-email-simon.marchi@ericsson.com> References: <1532558824-829-1-git-send-email-simon.marchi@ericsson.com> MIME-Version: 1.0 Content-Type: text/plain Return-Path: simon.marchi@ericsson.com Received-SPF: None (protection.outlook.com: ericsson.com does not designate permitted sender hosts) X-IsSubscribed: yes X-SW-Source: 2018-07/txt/msg00715.txt.bz2 New in v2: - As Tom pointed out, we don't need to keep the fd around after mmapping. This simplifies things quite a bit, since we don't need a new class. It's now just a function that returns a scoped_mmap. We already have scoped_mmap, which is a thin RAII layer over mmap. If one simply wants to mmap an entire file for reading, it takes a bit of boilerplate. This patch introduces the mmap_file function to make this easier. gdb/ChangeLog: * Makefile.in (COMMON_SFILES): Add common/scoped_mmap.c. * common/scoped_mmap.c: New file. * common/scoped_mmap.h (destroy): New method. (~scoped_mmap, reset): Use destroy. (scoped_mmap): New move constructor. (mmap_file): New declaration. * unittests/scoped_mmap-selftests.c (test_normal, test_invalid_filename, run_tests): New functions. (_initialize_scoped_mmap_selftests): Register selftest. --- gdb/Makefile.in | 1 + gdb/common/scoped_mmap.c | 44 ++++++++++++++++++++++++++++ gdb/common/scoped_mmap.h | 26 ++++++++++++++--- gdb/unittests/scoped_mmap-selftests.c | 54 +++++++++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 gdb/common/scoped_mmap.c diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 8c744d7..915e88c 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -965,6 +965,7 @@ COMMON_SFILES = \ common/ptid.c \ common/rsp-low.c \ common/run-time-clock.c \ + common/scoped_mmap.c \ common/signals.c \ common/signals-state-save-restore.c \ common/tdesc.c \ diff --git a/gdb/common/scoped_mmap.c b/gdb/common/scoped_mmap.c new file mode 100644 index 0000000..50ea576 --- /dev/null +++ b/gdb/common/scoped_mmap.c @@ -0,0 +1,44 @@ +/* scoped_mmap, automatically unmap files + + Copyright (C) 2018 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 . */ + +#include "defs.h" +#include "scoped_mmap.h" +#include "scoped_fd.h" + +scoped_mmap +mmap_file (const char *filename) +{ + scoped_fd fd (open (filename, O_RDONLY)); + if (fd.get () < 0) + perror_with_name ("open"); + + off_t size = lseek (fd.get (), 0, SEEK_END); + if (size < 0) + perror_with_name ("lseek"); + + /* We can't map an empty file. */ + if (size == 0) + error (_("file to mmap is empty")); + + scoped_mmap mmapped_file (nullptr, size, PROT_READ, MAP_PRIVATE, fd.get (), 0); + if (mmapped_file.get () == MAP_FAILED) + perror_with_name ("mmap"); + + return mmapped_file; +} diff --git a/gdb/common/scoped_mmap.h b/gdb/common/scoped_mmap.h index 6070c37..b446163 100644 --- a/gdb/common/scoped_mmap.h +++ b/gdb/common/scoped_mmap.h @@ -41,8 +41,18 @@ public: ~scoped_mmap () { - if (m_mem != MAP_FAILED) - munmap (m_mem, m_length); + destroy (); + } + + scoped_mmap (scoped_mmap &&rhs) + { + destroy (); + + m_mem = rhs.m_mem; + m_length = rhs.m_length; + + rhs.m_mem = MAP_FAILED; + rhs.m_length = 0; } DISABLE_COPY_AND_ASSIGN (scoped_mmap); @@ -58,8 +68,7 @@ public: void reset (void *addr, size_t length, int prot, int flags, int fd, off_t offset) noexcept { - if (m_mem != MAP_FAILED) - munmap (m_mem, m_length); + destroy (); m_length = length; m_mem = mmap (addr, m_length, prot, flags, fd, offset); @@ -69,9 +78,18 @@ public: void *get () const noexcept { return m_mem; } private: + void destroy () + { + if (m_mem != MAP_FAILED) + munmap (m_mem, m_length); + } + void *m_mem; size_t m_length; }; +/* Map FILENAME in memory. Throw an error if anything goes wrong. */ +scoped_mmap mmap_file (const char *filename); + #endif /* HAVE_SYS_MMAN_H */ #endif /* SCOPED_MMAP_H */ diff --git a/gdb/unittests/scoped_mmap-selftests.c b/gdb/unittests/scoped_mmap-selftests.c index ece3d7a..d70a56a 100644 --- a/gdb/unittests/scoped_mmap-selftests.c +++ b/gdb/unittests/scoped_mmap-selftests.c @@ -25,6 +25,7 @@ #if defined(HAVE_SYS_MMAN_H) && defined(HAVE_UNISTD_H) #include "selftest.h" +#include "common/gdb_unlinker.h" #include @@ -78,6 +79,57 @@ run_tests () } } /* namespace scoped_mmap */ + +namespace mmap_file +{ + +/* Test the standard usage of mmap_file. */ +static void +test_normal () +{ + char filename[] = "scoped_mmapped_file-selftest-XXXXXX"; + int fd = mkstemp (filename); + SELF_CHECK (fd >= 0); + + write (fd, "Hello!", 7); + close (fd); + + gdb::unlinker unlink_test_file (filename); + + { + ::scoped_mmap m = ::mmap_file (filename); + + SELF_CHECK (m.get () != MAP_FAILED); + SELF_CHECK (m.size () == 7); + SELF_CHECK (0 == strcmp ((char *) m.get (), "Hello!")); + } +} + +/* Calling mmap_file with a non-existent file should throw an exception. */ +static void +test_invalid_filename () +{ + bool threw = false; + + try { + ::scoped_mmap m = ::mmap_file ("/this/file/should/not/exist"); + } catch (gdb_exception &e) { + threw = true; + } + + SELF_CHECK (threw); +} + + +/* Run selftests. */ +static void +run_tests () +{ + test_normal (); + test_invalid_filename (); +} + +} /* namespace mmap_file */ } /* namespace selftests */ #endif /* !defined(HAVE_SYS_MMAN_H) || !defined(HAVE_UNISTD_H) */ @@ -88,5 +140,7 @@ _initialize_scoped_mmap_selftests () #if defined(HAVE_SYS_MMAN_H) && defined(HAVE_UNISTD_H) selftests::register_test ("scoped_mmap", selftests::scoped_mmap::run_tests); + selftests::register_test ("mmap_file", + selftests::mmap_file::run_tests); #endif } -- 2.7.4