/* This testcase is part of GDB, the GNU debugger.
- Copyright 2004 Free Software Foundation, Inc.
+ Copyright 2004, 2007, 2008, 2009, 2010, 2011 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 2 of the License, or
+ 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, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
- Please email any bugs, comments, and/or additions to this file to:
- bug-gdb@prep.ai.mit.edu */
+/* Get 64-bit stuff if on a GNU system. */
+#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
+/* This test was written for >2GB core files on 32-bit systems. On
+ current 64-bit systems, generating a >4EB (2 ** 63) core file is
+ not practical, and getting as close as we can takes a lot of
+ useless CPU time. So limit ourselves to a bit bigger than
+ 32-bit, which is still a useful test. */
+#define RLIMIT_CAP (1ULL << 34)
+
/* Print routines:
The following are so that printf et.al. can be avoided. Those
}
static void
-print_unsigned (unsigned long u)
+print_unsigned (unsigned long long u)
{
if (u >= 10)
print_unsigned (u / 10);
}
static void
-print_hex (unsigned long u)
+print_hex (unsigned long long u)
{
if (u >= 16)
print_hex (u / 16);
print_hex ((unsigned long) a);
}
+static void
+print_byte_count (unsigned long long u)
+{
+ print_unsigned (u);
+ print_string (" (");
+ print_string ("0x");
+ print_hex (u);
+ print_string (") bytes");
+}
+
/* Print the current values of RESOURCE. */
static void
print_rlimit (resource);
getrlimit (resource, &rl);
rl.rlim_cur = rl.rlim_max;
+ if (sizeof (rl.rlim_cur) >= sizeof (RLIMIT_CAP))
+ rl.rlim_cur = (rlim_t) RLIMIT_CAP;
setrlimit (resource, &rl);
print_string (" -> ");
print_rlimit (resource);
static unsigned long bytes_allocated;
+#ifdef O_LARGEFILE
+#define large_off_t off64_t
+#define large_lseek lseek64
+#else
+#define large_off_t off_t
+#define O_LARGEFILE 0
+#define large_lseek lseek
+#endif
+
int
main ()
{
size_t max_chunk_size;
+ large_off_t max_core_size;
/* Try to expand all the resource limits beyond the point of sanity
- we're after the biggest possible core file. */
maximize_rlimit (RLIMIT_AS, "stack");
#endif
+ print_string ("Maximize allocation limits ...\n");
+
+ /* Compute the largest possible corefile size. No point in trying
+ to create a corefile larger than the largest file supported by
+ the file system. What about 64-bit lseek64? */
+ {
+ int fd;
+ large_off_t tmp;
+ unlink ("bigcore.corefile");
+ fd = open ("bigcore.corefile", O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE,
+ 0666);
+ for (tmp = 1; tmp > 0; tmp <<= 1)
+ {
+ if (large_lseek (fd, tmp, SEEK_SET) > 0)
+ max_core_size = tmp;
+ }
+ close (fd);
+ }
+
/* Compute an initial chunk size. The math is dodgy but it works
- for the moment. Perhaphs there's a constant around somewhere. */
+ for the moment. Perhaphs there's a constant around somewhere.
+ Limit this to max_core_size bytes - no point in trying to
+ allocate more than can be written to the corefile. */
{
size_t tmp;
- for (tmp = 1; tmp > 0; tmp <<= 1)
+ for (tmp = 1; tmp > 0 && tmp < max_core_size; tmp <<= 1)
max_chunk_size = tmp;
}
+ print_string (" core: ");
+ print_byte_count (max_core_size);
+ print_string ("\n");
+ print_string (" chunk: ");
+ print_byte_count (max_chunk_size);
+ print_string ("\n");
+ print_string (" large? ");
+ if (O_LARGEFILE)
+ print_string ("yes\n");
+ else
+ print_string ("no\n");
+
/* Allocate as much memory as possible creating a linked list of
each section. The linking ensures that some, but not all, the
memory is allocated. NB: Some kernels handle this efficiently -
{
unsigned long count = 0;
print_string (" ");
- print_unsigned (chunk_size);
- print_string (" bytes ... ");
- while (1)
+ print_byte_count (chunk_size);
+ print_string (" ... ");
+ while (bytes_allocated + (1 + count) * chunk_size
+ < max_core_size)
{
struct list *chunk = malloc (chunk_size);
if (chunk == NULL)
bytes_allocated += chunk_size * count;
}
print_string ("Total of ");
- print_unsigned (bytes_allocated);
+ print_byte_count (bytes_allocated);
print_string (" bytes ");
print_unsigned (chunks_allocated);
print_string (" chunks\n");