#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h> // APPLE LOCAL: must incl sys/time.h before resource.h
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/resource.h>
#include <stdio.h> // APPLE LOCAL: to output the pid
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#define printf do not use
const char digit[] = "0123456789abcdefghijklmnopqrstuvwxyz";
static void
print_char (char c)
{
write (1, &c, sizeof (c));
}
static void
print_unsigned (unsigned long long u)
{
if (u >= 10)
print_unsigned (u / 10);
print_char (digit[u % 10]);
}
static void
print_hex (unsigned long long u)
{
if (u >= 16)
print_hex (u / 16);
print_char (digit[u % 16]);
}
static void
print_string (const char *s)
{
for (; (*s) != '\0'; s++)
print_char ((*s));
}
static void
print_address (const void *a)
{
print_string ("0x");
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");
}
static void
print_rlimit (int resource)
{
struct rlimit rl;
getrlimit (resource, &rl);
print_string ("cur=0x");
print_hex (rl.rlim_cur);
print_string (" max=0x");
print_hex (rl.rlim_max);
}
static void
maximize_rlimit (int resource, const char *prefix)
{
struct rlimit rl;
print_string (" ");
print_string (prefix);
print_string (": ");
print_rlimit (resource);
getrlimit (resource, &rl);
rl.rlim_cur = rl.rlim_max;
setrlimit (resource, &rl);
print_string (" -> ");
print_rlimit (resource);
print_string ("\n");
}
struct list
{
struct list *next;
struct list *prev;
size_t size;
};
static struct list dummy;
static struct list heap = { &dummy, &dummy };
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;
fprintf (stdout, "PID: %d\n", getpid());
fflush (stdout);
print_string ("Maximize resource limits ...\n");
#ifdef RLIMIT_CORE
maximize_rlimit (RLIMIT_CORE, "core");
#endif
#ifdef RLIMIT_DATA
maximize_rlimit (RLIMIT_DATA, "data");
#endif
#ifdef RLIMIT_STACK
maximize_rlimit (RLIMIT_STACK, "stack");
#endif
#ifdef RLIMIT_AS
maximize_rlimit (RLIMIT_AS, "stack");
#endif
print_string ("Maximize allocation limits ...\n");
{
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);
}
{
size_t tmp;
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");
print_string ("Alocating the entire heap ...\n");
{
size_t chunk_size;
unsigned long chunks_allocated = 0;
for (chunk_size = max_chunk_size;
chunk_size >= sizeof (struct list);
chunk_size >>= 1)
{
unsigned long count = 0;
print_string (" ");
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)
break;
chunk->size = chunk_size;
chunk->next = NULL;
chunk->prev = heap.prev;
heap.prev->next = chunk;
heap.prev = chunk;
count++;
}
print_unsigned (count);
print_string (" chunks\n");
chunks_allocated += count;
bytes_allocated += chunk_size * count;
}
print_string ("Total of ");
print_byte_count (bytes_allocated);
print_string (" bytes ");
print_unsigned (chunks_allocated);
print_string (" chunks\n");
}
print_string ("Dump core ....\n");
*(char*)0 = 0;
}