1 /* Self tests for scoped_mmap for GDB, the GNU debugger. 2 3 Copyright (C) 2018-2019 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "defs.h" 21 22 #include "common/filestuff.h" 23 #include "common/scoped_mmap.h" 24 #include "config.h" 25 26 #if defined(HAVE_SYS_MMAN_H) 27 28 #include "common/selftest.h" 29 #include "common/gdb_unlinker.h" 30 31 #include <unistd.h> 32 33 namespace selftests { 34 namespace scoped_mmap { 35 36 /* Test that the file is unmapped. */ 37 static void 38 test_destroy () 39 { 40 void *mem; 41 42 errno = 0; 43 { 44 ::scoped_mmap smmap (nullptr, sysconf (_SC_PAGESIZE), PROT_WRITE, 45 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); 46 47 mem = smmap.get (); 48 SELF_CHECK (mem != nullptr); 49 } 50 51 SELF_CHECK (msync (mem, sysconf (_SC_PAGESIZE), 0) == -1 && errno == ENOMEM); 52 } 53 54 /* Test that the memory can be released. */ 55 static void 56 test_release () 57 { 58 void *mem; 59 60 errno = 0; 61 { 62 ::scoped_mmap smmap (nullptr, sysconf (_SC_PAGESIZE), PROT_WRITE, 63 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); 64 65 mem = smmap.release (); 66 SELF_CHECK (mem != nullptr); 67 } 68 69 SELF_CHECK (msync (mem, sysconf (_SC_PAGESIZE), 0) == 0 || errno != ENOMEM); 70 71 munmap (mem, sysconf (_SC_PAGESIZE)); 72 } 73 74 /* Run selftests. */ 75 static void 76 run_tests () 77 { 78 test_destroy (); 79 test_release (); 80 } 81 82 } /* namespace scoped_mmap */ 83 84 namespace mmap_file 85 { 86 87 /* Test the standard usage of mmap_file. */ 88 static void 89 test_normal () 90 { 91 char filename[] = "scoped_mmapped_file-selftest-XXXXXX"; 92 int fd = gdb_mkostemp_cloexec (filename); 93 SELF_CHECK (fd >= 0); 94 95 SELF_CHECK (write (fd, "Hello!", 7) == 7); 96 close (fd); 97 98 gdb::unlinker unlink_test_file (filename); 99 100 { 101 ::scoped_mmap m = ::mmap_file (filename); 102 103 SELF_CHECK (m.get () != MAP_FAILED); 104 SELF_CHECK (m.size () == 7); 105 SELF_CHECK (0 == strcmp ((char *) m.get (), "Hello!")); 106 } 107 } 108 109 /* Calling mmap_file with a non-existent file should throw an exception. */ 110 static void 111 test_invalid_filename () 112 { 113 bool threw = false; 114 115 try { 116 ::scoped_mmap m = ::mmap_file ("/this/file/should/not/exist"); 117 } catch (gdb_exception &e) { 118 threw = true; 119 } 120 121 SELF_CHECK (threw); 122 } 123 124 125 /* Run selftests. */ 126 static void 127 run_tests () 128 { 129 test_normal (); 130 test_invalid_filename (); 131 } 132 133 } /* namespace mmap_file */ 134 } /* namespace selftests */ 135 136 #endif /* !defined(HAVE_SYS_MMAN_H) */ 137 138 void 139 _initialize_scoped_mmap_selftests () 140 { 141 #if defined(HAVE_SYS_MMAN_H) 142 selftests::register_test ("scoped_mmap", 143 selftests::scoped_mmap::run_tests); 144 selftests::register_test ("mmap_file", 145 selftests::mmap_file::run_tests); 146 #endif 147 } 148