Index: gdb/testsuite/gdb.base/find-unmapped.c |
diff --git a/gdb/testsuite/gdb.base/find-unmapped.c b/gdb/testsuite/gdb.base/find-unmapped.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9d549513b6a49428bea39284fa6fd8f2d63d2ad2 |
--- /dev/null |
+++ b/gdb/testsuite/gdb.base/find-unmapped.c |
@@ -0,0 +1,106 @@ |
+/* This testcase is part of GDB, the GNU debugger. |
+ |
+ Copyright 2012-2013 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/>. */ |
+ |
+#include <stdlib.h> |
+#include <stdio.h> |
+#include <sys/mman.h> |
+#include <unistd.h> |
+#include <string.h> |
+ |
+#define CHUNK_SIZE 16000 /* same as findcmd.c's */ |
+ |
+void *global_var_0; |
+void *global_var_1; |
+void *global_var_2; |
+ |
+void |
+breakpt () |
+{ |
+ /* Nothing. */ |
+} |
+ |
+int |
+main (void) |
+{ |
+ void *p; |
+ size_t pg_size; |
+ int pg_count; |
+ void *unmapped_page, *last_mapped_page, *first_mapped_page; |
+ |
+ /* |
+ Map enough pages to cover at least CHUNK_SIZE, and one extra page. We |
+ then unmap the last page. |
+ |
+ From gdb we can then perform find commands into unmapped region, gdb |
+ should give an error. |
+ |
+ .-- global_var_0 .-- global_var_1 |
+ | | .-- global_var_2 |
+ | | | |
+ .----.----.----.----.----. |
+ | | | | | | |
+ '----'----'----'----'----' |
+ |<- CHUNK_SIZE ->| |
+ |
+ If CHUNK_SIZE equals page size then we'll get 3 pages, and if |
+ CHUNK_SIZE is less than page size we'll get 2 pages. The test will |
+ still work in these cases. |
+ |
+ (1) We do a find from global_var_0 to global_var_2, this will fail when |
+ loading the second chunk, as we know at least CHUNK_SIZE bytes are in |
+ mapped space. |
+ |
+ (2) We do a find from global_var_1 to global_var_2, this will fail when |
+ loading the first chunk, assuming the CHUNK_SIZE is at least 16 bytes. |
+ |
+ (3) We do a find from global_var_2 to (global_var_2 + 16), this too |
+ will fail when loading the first chunk regardless of the chunk size. |
+ */ |
+ |
+ pg_size = getpagesize (); |
+ /* The +2 ensures the extra page. */ |
+ pg_count = CHUNK_SIZE / pg_size + 2; |
+ |
+ p = mmap (0, pg_count * pg_size, PROT_READ|PROT_WRITE, |
+ MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); |
+ if (p == MAP_FAILED) |
+ { |
+ perror ("mmap"); |
+ return EXIT_FAILURE; |
+ } |
+ |
+ memset (p, 0, pg_count * pg_size); |
+ |
+ if (munmap (p + (pg_count - 1) * pg_size, pg_size) == -1) |
+ { |
+ perror ("munmap"); |
+ return EXIT_FAILURE; |
+ } |
+ |
+ first_mapped_page = p; |
+ last_mapped_page = p + (pg_count - 2) * pg_size; |
+ unmapped_page = last_mapped_page + pg_size; |
+ |
+ /* Setup global variables we reference from gdb. */ |
+ global_var_0 = first_mapped_page; |
+ global_var_1 = unmapped_page - 16; |
+ global_var_2 = unmapped_page + 16; |
+ |
+ breakpt (); |
+ |
+ return EXIT_SUCCESS; |
+} |