mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-08 16:36:21 +00:00
152 lines
5.5 KiB
C
152 lines
5.5 KiB
C
|
|
/* This test case was originally written by Nicholas Nethercote. */
|
|
|
|
// This test covers all the different sources of values, both defined and
|
|
// undefined. It only involves undefined condition errors.
|
|
//
|
|
// Nb: a stack frame is allocated when a signal is delivered. But it
|
|
// immediately get written with stuff, so there's no significant possibility
|
|
// of undefined values originating there. So we ignore it. (On platforms
|
|
// like AMD64 that have a redzone just beyond the stack pointer there is a
|
|
// possibility, but it's so slim we ignore it.)
|
|
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include "tests/sys_mman.h"
|
|
#include <unistd.h>
|
|
#include "../memcheck.h"
|
|
|
|
int x = 0;
|
|
|
|
int main(void)
|
|
{
|
|
assert(1 == sizeof(char));
|
|
assert(2 == sizeof(short));
|
|
assert(4 == sizeof(int));
|
|
assert(8 == sizeof(long long));
|
|
|
|
//------------------------------------------------------------------------
|
|
// Sources of undefined values
|
|
//------------------------------------------------------------------------
|
|
|
|
// Stack, 32-bit
|
|
{
|
|
volatile int undef_stack_int;
|
|
fprintf(stderr, "\nUndef 1 of 8 (stack, 32 bit)\n");
|
|
x += (undef_stack_int == 0x12345678 ? 10 : 21);
|
|
}
|
|
|
|
// Stack, 32-bit, recently modified. Nb: we have to do the register
|
|
// mucking about to make sure that the modification isn't fenced by a
|
|
// store/load pair and thus not seen (see origin-not-quite.c).
|
|
{
|
|
volatile int undef_stack_int;
|
|
register int modified_undef_stack_int;
|
|
fprintf(stderr, "\nUndef 2 of 8 (stack, 32 bit)\n");
|
|
modified_undef_stack_int = undef_stack_int;
|
|
modified_undef_stack_int++;
|
|
x += (modified_undef_stack_int == 0x1234 ? 11 : 22);
|
|
}
|
|
|
|
// Stack, 64-bit. XXX: gets reported with two identical origins.
|
|
{
|
|
volatile long long undef_stack_longlong;
|
|
fprintf(stderr, "\nUndef 3 of 8 (stack, 64 bit)\n");
|
|
x += (undef_stack_longlong == 0x1234567812345678LL ? 11 : 22);
|
|
}
|
|
|
|
// Malloc block, uninitialised, 32-bit
|
|
{
|
|
int* ptr_to_undef_malloc_int = malloc(sizeof(int));
|
|
int undef_malloc_int = *ptr_to_undef_malloc_int;
|
|
fprintf(stderr, "\nUndef 4 of 8 (mallocd, 32-bit)\n");
|
|
x += (undef_malloc_int == 0x12345678 ? 12 : 23);
|
|
}
|
|
|
|
// Realloc block, uninitialised
|
|
{
|
|
int* ptr_to_undef_malloc_int2 = malloc(sizeof(int));
|
|
// Allocate a big chunk to ensure that a new block is allocated.
|
|
int* ptr_to_undef_realloc_int = realloc(ptr_to_undef_malloc_int2, 4096);
|
|
// Have to move past the first 4 bytes, which were copied from the
|
|
// malloc'd block.
|
|
int undef_realloc_int = *(ptr_to_undef_realloc_int+1);
|
|
fprintf(stderr, "\nUndef 5 of 8 (realloc)\n");
|
|
x += (undef_realloc_int == 0x12345678 ? 13 : 24);
|
|
}
|
|
|
|
// Custom-allocated block, non-zeroed
|
|
{
|
|
int undef_custom_alloc_int;
|
|
VALGRIND_MALLOCLIKE_BLOCK(&undef_custom_alloc_int, sizeof(int),
|
|
/*rzB*/0, /*is_zeroed*/0);
|
|
fprintf(stderr, "\nUndef 6 of 8 (MALLOCLIKE_BLOCK)\n");
|
|
x += (undef_custom_alloc_int == 0x12345678 ? 14 : 25);
|
|
}
|
|
|
|
// Heap segment (brk), uninitialised
|
|
// CURRENTLY DISABLED. Why?
|
|
// - On Darwin, sbrk() is implemented via vm_allocate() which always zeroes
|
|
// its allocated memory. For a while we used use a separate .exp file
|
|
// for Darwin, but we add an extra printf on Darwin only so that it
|
|
// cannot be successfully matched on non-Darwin platforms.
|
|
// - On Ubuntu 9.04 configured with --enable-only32bit, the brk symbol
|
|
// shows up as "???"
|
|
// - Our current treatment of brk is suspect; whole new pages allocated
|
|
// with brk should arguably be marked defined -- see the big comment
|
|
// above track_new_mem_brk() in memcheck/mc_main.c.
|
|
//#if defined(VGO_darwin)
|
|
fprintf(stderr, "\nUndef 7 of 8 (brk)\n");
|
|
// fprintf(stderr, "\n(no complaint; sbrk initialises memory on Darwin)\n");
|
|
fprintf(stderr, "\n(currently disabled)\n");
|
|
//#else
|
|
// {
|
|
// int* ptr_to_new_brk_limit = sbrk(4096);
|
|
// int undef_brk_int = *ptr_to_new_brk_limit;
|
|
// fprintf(stderr, "\nUndef 7 of 8 (brk)\n");
|
|
// x += (undef_brk_int == 0x12345678 ? 15 : 26);
|
|
// }
|
|
//#endif
|
|
|
|
// User block, marked as undefined
|
|
{
|
|
int undef_user_int = 0;
|
|
(void) VALGRIND_MAKE_MEM_UNDEFINED(&undef_user_int, sizeof(int));
|
|
fprintf(stderr, "\nUndef 8 of 8 (MAKE_MEM_UNDEFINED)\n");
|
|
x += (undef_user_int == 0x12345678 ? 16 : 27);
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// Sources of defined values
|
|
//------------------------------------------------------------------------
|
|
|
|
// Heap block (calloc), initialised
|
|
{
|
|
int* ptr_to_def_calloc_int = calloc(1, sizeof(int));
|
|
int def_calloc_int = *ptr_to_def_calloc_int;
|
|
fprintf(stderr, "\nDef 1 of 3\n");
|
|
x += (def_calloc_int == 0x12345678 ? 17 : 28);
|
|
}
|
|
|
|
// Custom-allocated block, non-zeroed
|
|
{
|
|
int def_custom_alloc_int = 0;
|
|
fprintf(stderr, "\nDef 2 of 3\n");
|
|
VALGRIND_MALLOCLIKE_BLOCK(&def_custom_alloc_int, sizeof(int),
|
|
/*rzB*/0, /*is_zeroed*/1);
|
|
x += (def_custom_alloc_int == 0x12345678 ? 18 : 29);
|
|
}
|
|
|
|
// mmap block, initialised
|
|
{
|
|
int* ptr_to_def_mmap_int =
|
|
mmap(0, 4096, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
|
int def_mmap_int = *ptr_to_def_mmap_int;
|
|
fprintf(stderr, "\nDef 3 of 3\n");
|
|
x += (def_mmap_int == 0x12345678 ? 19 : 30);
|
|
}
|
|
|
|
return x;
|
|
}
|