1
0
mirror of https://github.com/ioacademy-jikim/debugging synced 2026-08-30 09:19:28 +00:00

first commit

This commit is contained in:
jikim
2015-12-13 22:34:58 +09:00
commit 0b589c7986
9455 changed files with 4350134 additions and 0 deletions
@@ -0,0 +1 @@
# dummy
@@ -0,0 +1 @@
# dummy
@@ -0,0 +1 @@
# dummy
@@ -0,0 +1 @@
# dummy
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,69 @@
include $(top_srcdir)/Makefile.tool-tests.am
dist_noinst_SCRIPTS = filter_stderr filter_add filter_suppgen
EXTRA_DIST = \
is_arch_supported \
bad_percentify.vgtest bad_percentify.c \
bad_percentify.stdout.exp bad_percentify.stderr.exp-glibc28-amd64 \
globalerr.vgtest globalerr.stdout.exp \
globalerr.stderr.exp-glibc28-amd64 \
globalerr.stderr.exp-gcc491-amd64 \
hackedbz2.vgtest hackedbz2.stdout.exp \
hackedbz2.stderr.exp-glibc28-amd64 \
hsg.vgtest hsg.stdout.exp hsg.stderr.exp \
preen_invars.vgtest preen_invars.stdout.exp \
preen_invars.stderr.exp-glibc28-amd64 \
stackerr.vgtest stackerr.stdout.exp \
stackerr.stderr.exp-glibc28-amd64 stackerr.stderr.exp-glibc27-x86
check_PROGRAMS = \
bad_percentify \
globalerr hackedbz2 \
hsg \
preen_invars preen_invars_so.so \
stackerr
# DDD: not sure if these ones should work on Darwin or not... if not, should
# be moved into x86-linux/.
#if ! VGCONF_OS_IS_DARWIN
# check_PROGRAMS += \
# ccc
#endif
AM_CFLAGS += $(AM_FLAG_M3264_PRI)
AM_CXXFLAGS += $(AM_FLAG_M3264_PRI)
# To make it a bit more realistic, build hackedbz2.c with at
# least some optimisation.
hackedbz2_CFLAGS = $(AM_CFLAGS) -O -Wno-inline
globalerr_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@
# C ones
#pth_create_LDADD = -lpthread
# C++ ones
#ccc_SOURCES = ccc.cpp
# Build shared object for preen_invars
preen_invars_DEPENDENCIES = preen_invars_so.so
if VGCONF_OS_IS_DARWIN
preen_invars_LDADD = -ldl
preen_invars_LDFLAGS = $(AM_FLAG_M3264_PRI)
else
preen_invars_LDADD = -ldl
preen_invars_LDFLAGS = $(AM_FLAG_M3264_PRI) \
-Wl,-rpath,$(top_builddir)/memcheck/tests
endif
preen_invars_so_so_CFLAGS = $(AM_CFLAGS) -fpic
if VGCONF_OS_IS_DARWIN
preen_invars_so_so_LDFLAGS = -fpic $(AM_FLAG_M3264_PRI) -dynamic \
-dynamiclib -all_load
else
preen_invars_so_so_LDFLAGS = -fpic $(AM_FLAG_M3264_PRI) -shared \
-Wl,-soname -Wl,preen_invars_so.so
endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,647 @@
/* This demonstrates a stack overrun bug that exp-ptrcheck found while
running Valgrind itself (self hosting). As at 12 Sept 08 this bug
is still in Valgrind. */
#include <stdio.h>
#include <assert.h>
#include <stdarg.h>
typedef unsigned long long int ULong;
typedef signed long long int Long;
typedef unsigned int UInt;
typedef signed int Int;
typedef signed char Char;
typedef char HChar;
typedef unsigned long UWord;
typedef signed long Word;
typedef unsigned char Bool;
#define True ((Bool)1)
#define False ((Bool)0)
#define VG_(_str) VG_##_str
/* ---------------------------------------------------------------------
vg_sprintf, copied from m_libcprint.c
------------------------------------------------------------------ */
UInt
VG_(debugLog_vprintf) (
void(*send)(HChar,void*),
void* send_arg2,
const HChar* format,
va_list vargs
);
/* ---------------------------------------------------------------------
printf() and friends
------------------------------------------------------------------ */
typedef
struct { Int fd; Bool is_socket; }
OutputSink;
OutputSink VG_(log_output_sink) = { 2, False }; /* 2 = stderr */
/* Do the low-level send of a message to the logging sink. */
static
void send_bytes_to_logging_sink ( OutputSink* sink, HChar* msg, Int nbytes )
{
fwrite(msg, 1, nbytes, stdout);
fflush(stdout);
}
/* --------- printf --------- */
typedef
struct {
HChar buf[512];
Int buf_used;
OutputSink* sink;
}
printf_buf_t;
// Adds a single char to the buffer. When the buffer gets sufficiently
// full, we write its contents to the logging sink.
static void add_to__printf_buf ( HChar c, void *p )
{
printf_buf_t *b = (printf_buf_t *)p;
if (b->buf_used > sizeof(b->buf) - 2 ) {
send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
b->buf_used = 0;
}
b->buf[b->buf_used++] = c;
b->buf[b->buf_used] = 0;
assert(b->buf_used < sizeof(b->buf));
}
__attribute__((noinline))
static UInt vprintf_to_buf ( printf_buf_t* b,
const HChar *format, va_list vargs )
{
UInt ret = 0;
if (b->sink->fd >= 0 || b->sink->fd == -2) {
ret = VG_(debugLog_vprintf)
( add_to__printf_buf, b, format, vargs );
}
return ret;
}
__attribute__((noinline))
static UInt vprintf_WRK ( OutputSink* sink,
const HChar *format, va_list vargs )
{
printf_buf_t myprintf_buf
= { "", 0, sink };
UInt ret;
ret = vprintf_to_buf(&myprintf_buf, format, vargs);
// Write out any chars left in the buffer.
if (myprintf_buf.buf_used > 0) {
send_bytes_to_logging_sink( myprintf_buf.sink,
myprintf_buf.buf,
myprintf_buf.buf_used );
}
return ret;
}
__attribute__((noinline))
UInt VG_(vprintf) ( const HChar *format, va_list vargs )
{
return vprintf_WRK( &VG_(log_output_sink), format, vargs );
}
__attribute__((noinline))
UInt VG_(printf) ( const HChar *format, ... )
{
UInt ret;
va_list vargs;
va_start(vargs, format);
ret = VG_(vprintf)(format, vargs);
va_end(vargs);
return ret;
}
static Bool toBool ( Int x ) {
Int r = (x == 0) ? False : True;
return (Bool)r;
}
__attribute__((noinline))
static Int local_strlen ( const HChar* str )
{
Int i = 0;
while (str[i] != 0) i++;
return i;
}
__attribute__((noinline))
static HChar local_toupper ( HChar c )
{
if (c >= 'a' && c <= 'z')
return c + ('A' - 'a');
else
return c;
}
/*------------------------------------------------------------*/
/*--- A simple, generic, vprintf implementation. ---*/
/*------------------------------------------------------------*/
/* -----------------------------------------------
Distantly derived from:
vprintf replacement for Checker.
Copyright 1993, 1994, 1995 Tristan Gingold
Written September 1993 Tristan Gingold
Tristan Gingold, 8 rue Parmentier, F-91120 PALAISEAU, FRANCE
(Checker itself was GPL'd.)
----------------------------------------------- */
/* Some flags. */
#define VG_MSG_SIGNED 1 /* The value is signed. */
#define VG_MSG_ZJUSTIFY 2 /* Must justify with '0'. */
#define VG_MSG_LJUSTIFY 4 /* Must justify on the left. */
#define VG_MSG_PAREN 8 /* Parenthesize if present (for %y) */
#define VG_MSG_COMMA 16 /* Add commas to numbers (for %d, %u) */
#define VG_MSG_ALTFORMAT 32 /* Convert the value to alternate format */
/* Copy a string into the buffer. */
static __attribute__((noinline))
UInt myvprintf_str ( void(*send)(HChar,void*),
void* send_arg2,
Int flags,
Int width,
HChar* str,
Bool capitalise )
{
# define MAYBE_TOUPPER(ch) (capitalise ? local_toupper(ch) : (ch))
UInt ret = 0;
Int i, extra;
Int len = local_strlen(str);
if (width == 0) {
ret += len;
for (i = 0; i < len; i++)
send(MAYBE_TOUPPER(str[i]), send_arg2);
return ret;
}
if (len > width) {
ret += width;
for (i = 0; i < width; i++)
send(MAYBE_TOUPPER(str[i]), send_arg2);
return ret;
}
extra = width - len;
if (flags & VG_MSG_LJUSTIFY) {
ret += extra;
for (i = 0; i < extra; i++)
send(' ', send_arg2);
}
ret += len;
for (i = 0; i < len; i++)
send(MAYBE_TOUPPER(str[i]), send_arg2);
if (!(flags & VG_MSG_LJUSTIFY)) {
ret += extra;
for (i = 0; i < extra; i++)
send(' ', send_arg2);
}
# undef MAYBE_TOUPPER
return ret;
}
/* Copy a string into the buffer, escaping bad XML chars. */
static
UInt myvprintf_str_XML_simplistic ( void(*send)(HChar,void*),
void* send_arg2,
HChar* str )
{
UInt ret = 0;
Int i;
Int len = local_strlen(str);
HChar* alt;
for (i = 0; i < len; i++) {
switch (str[i]) {
case '&': alt = "&amp;"; break;
case '<': alt = "&lt;"; break;
case '>': alt = "&gt;"; break;
default: alt = NULL;
}
if (alt) {
while (*alt) {
send(*alt, send_arg2);
ret++;
alt++;
}
} else {
send(str[i], send_arg2);
ret++;
}
}
return ret;
}
/* Write P into the buffer according to these args:
* If SIGN is true, p is a signed.
* BASE is the base.
* If WITH_ZERO is true, '0' must be added.
* WIDTH is the width of the field.
*/
static
UInt myvprintf_int64 ( void(*send)(HChar,void*),
void* send_arg2,
Int flags,
Int base,
Int width,
Bool capitalised,
ULong p )
{
HChar buf[40];
Int ind = 0;
Int i, nc = 0;
Bool neg = False;
HChar* digits = capitalised ? "0123456789ABCDEF" : "0123456789abcdef";
UInt ret = 0;
if (base < 2 || base > 16)
return ret;
if ((flags & VG_MSG_SIGNED) && (Long)p < 0) {
p = - (Long)p;
neg = True;
}
if (p == 0)
buf[ind++] = '0';
else {
while (p > 0) {
if (flags & VG_MSG_COMMA && 10 == base &&
0 == (ind-nc) % 3 && 0 != ind)
{
buf[ind++] = ',';
nc++;
}
buf[ind++] = digits[p % base];
p /= base;
}
}
if (neg)
buf[ind++] = '-';
if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) {
for(; ind < width; ind++) {
/* assert(ind < 39); */
if (ind > 39) {
buf[39] = 0;
break;
}
buf[ind] = (flags & VG_MSG_ZJUSTIFY) ? '0': ' ';
}
}
/* Reverse copy to buffer. */
ret += ind;
for (i = ind -1; i >= 0; i--) {
send(buf[i], send_arg2);
}
if (width > 0 && (flags & VG_MSG_LJUSTIFY)) {
for(; ind < width; ind++) {
ret++;
/* Never pad with zeroes on RHS -- changes the value! */
send(' ', send_arg2);
}
}
return ret;
}
/* A simple vprintf(). */
/* EXPORTED */
__attribute__((noinline))
UInt
VG_(debugLog_vprintf) (
void(*send)(HChar,void*),
void* send_arg2,
const HChar* format,
va_list vargs
)
{
UInt ret = 0;
Int i;
Int flags;
Int width;
Int n_ls = 0;
Bool is_long, caps;
/* We assume that vargs has already been initialised by the
caller, using va_start, and that the caller will similarly
clean up with va_end.
*/
for (i = 0; format[i] != 0; i++) {
if (format[i] != '%') {
send(format[i], send_arg2);
ret++;
continue;
}
i++;
/* A '%' has been found. Ignore a trailing %. */
if (format[i] == 0)
break;
if (format[i] == '%') {
/* '%%' is replaced by '%'. */
send('%', send_arg2);
ret++;
continue;
}
flags = 0;
n_ls = 0;
width = 0; /* length of the field. */
while (1) {
switch (format[i]) {
case '(':
flags |= VG_MSG_PAREN;
break;
case ',':
case '\'':
/* If ',' or '\'' follows '%', commas will be inserted. */
flags |= VG_MSG_COMMA;
break;
case '-':
/* If '-' follows '%', justify on the left. */
flags |= VG_MSG_LJUSTIFY;
break;
case '0':
/* If '0' follows '%', pads will be inserted. */
flags |= VG_MSG_ZJUSTIFY;
break;
case '#':
/* If '#' follows '%', alternative format will be used. */
flags |= VG_MSG_ALTFORMAT;
break;
default:
goto parse_fieldwidth;
}
i++;
}
parse_fieldwidth:
/* Compute the field length. */
while (format[i] >= '0' && format[i] <= '9') {
width *= 10;
width += format[i++] - '0';
}
while (format[i] == 'l') {
i++;
n_ls++;
}
// %d means print a 32-bit integer.
// %ld means print a word-size integer.
// %lld means print a 64-bit integer.
if (0 == n_ls) { is_long = False; }
else if (1 == n_ls) { is_long = ( sizeof(void*) == sizeof(Long) ); }
else { is_long = True; }
switch (format[i]) {
case 'o': /* %o */
if (flags & VG_MSG_ALTFORMAT) {
ret += 2;
send('0',send_arg2);
}
if (is_long)
ret += myvprintf_int64(send, send_arg2, flags, 8, width, False,
(ULong)(va_arg (vargs, ULong)));
else
ret += myvprintf_int64(send, send_arg2, flags, 8, width, False,
(ULong)(va_arg (vargs, UInt)));
break;
case 'd': /* %d */
flags |= VG_MSG_SIGNED;
if (is_long)
ret += myvprintf_int64(send, send_arg2, flags, 10, width, False,
(ULong)(va_arg (vargs, Long)));
else
ret += myvprintf_int64(send, send_arg2, flags, 10, width, False,
(ULong)(va_arg (vargs, Int)));
break;
case 'u': /* %u */
if (is_long)
ret += myvprintf_int64(send, send_arg2, flags, 10, width, False,
(ULong)(va_arg (vargs, ULong)));
else
ret += myvprintf_int64(send, send_arg2, flags, 10, width, False,
(ULong)(va_arg (vargs, UInt)));
break;
case 'p':
if (format[i+1] == 'S') {
i++;
/* %pS, like %s but escaping chars for XML safety */
/* Note: simplistic; ignores field width and flags */
char *str = va_arg (vargs, char *);
if (str == (char*) 0)
str = "(null)";
ret += myvprintf_str_XML_simplistic(send, send_arg2, str);
} else {
/* %p */
ret += 2;
send('0',send_arg2);
send('x',send_arg2);
ret += myvprintf_int64(send, send_arg2, flags, 16, width, True,
(ULong)((UWord)va_arg (vargs, void *)));
}
break;
case 'x': /* %x */
case 'X': /* %X */
caps = toBool(format[i] == 'X');
if (flags & VG_MSG_ALTFORMAT) {
ret += 2;
send('0',send_arg2);
send('x',send_arg2);
}
if (is_long)
ret += myvprintf_int64(send, send_arg2, flags, 16, width, caps,
(ULong)(va_arg (vargs, ULong)));
else
ret += myvprintf_int64(send, send_arg2, flags, 16, width, caps,
(ULong)(va_arg (vargs, UInt)));
break;
case 'c': /* %c */
ret++;
send(va_arg (vargs, int), send_arg2);
break;
case 's': case 'S': { /* %s */
char *str = va_arg (vargs, char *);
if (str == (char*) 0) str = "(null)";
ret += myvprintf_str(send, send_arg2,
flags, width, str, format[i]=='S');
break;
}
// case 'y': { /* %y - print symbol */
// Addr a = va_arg(vargs, Addr);
//
//
//
// HChar *name;
// if (VG_(get_fnname_w_offset)(a, &name)) {
// HChar buf[1 + VG_strlen(name) + 1 + 1];
// if (flags & VG_MSG_PAREN) {
// VG_(sprintf)(str, "(%s)", name):
// } else {
// VG_(sprintf)(str, "%s", name):
// }
// ret += myvprintf_str(send, flags, width, buf, 0);
// }
// break;
// }
default:
break;
}
}
return ret;
}
static void add_to__sprintf_buf ( HChar c, void *p )
{
HChar** b = p;
*(*b)++ = c;
}
UInt VG_(vsprintf) ( HChar* buf, const HChar *format, va_list vargs )
{
Int ret;
HChar* sprintf_ptr = buf;
ret = VG_(debugLog_vprintf)
( add_to__sprintf_buf, &sprintf_ptr, format, vargs );
add_to__sprintf_buf('\0', &sprintf_ptr);
assert(local_strlen(buf) == ret);
return ret;
}
UInt VG_(sprintf) ( HChar* buf, const HChar *format, ... )
{
UInt ret;
va_list vargs;
va_start(vargs,format);
ret = VG_(vsprintf)(buf, format, vargs);
va_end(vargs);
return ret;
}
/* ---------------------------------------------------------------------
percentify()
------------------------------------------------------------------ */
/* This part excerpted from coregrind/m_libcbase.c */
// Percentify n/m with d decimal places. Includes the '%' symbol at the end.
// Right justifies in 'buf'.
__attribute__((noinline))
void VG_percentify(ULong n, ULong m, UInt d, Int n_buf, HChar buf[])
{
Int i, len, space;
ULong p1;
HChar fmt[32];
if (m == 0) {
// Have to generate the format string in order to be flexible about
// the width of the field.
VG_(sprintf)(fmt, "%%-%ds", n_buf);
// fmt is now "%<n_buf>s" where <d> is 1,2,3...
VG_(sprintf)(buf, fmt, "--%");
return;
}
p1 = (100*n) / m;
if (d == 0) {
VG_(sprintf)(buf, "%lld%%", p1);
} else {
ULong p2;
UInt ex;
switch (d) {
case 1: ex = 10; break;
case 2: ex = 100; break;
case 3: ex = 1000; break;
default: assert(0);
/* was: VG_(tool_panic)("Currently can only handle 3 decimal places"); */
}
p2 = ((100*n*ex) / m) % ex;
// Have to generate the format string in order to be flexible about
// the width of the post-decimal-point part.
VG_(sprintf)(fmt, "%%lld.%%0%dlld%%%%", d);
// fmt is now "%lld.%0<d>lld%%" where <d> is 1,2,3...
VG_(sprintf)(buf, fmt, p1, p2);
}
len = local_strlen(buf);
space = n_buf - len;
if (space < 0) space = 0; /* Allow for v. small field_width */
i = len;
/* Right justify in field */
for ( ; i >= 0; i--) buf[i + space] = buf[i];
for (i = 0; i < space; i++) buf[i] = ' ';
}
/*------------------------------------------------------------*/
/*--- Stats ---*/
/*------------------------------------------------------------*/
/* This part excerpted from coregrind/m_translate.c */
static UInt n_SP_updates_fast = 0;
static UInt n_SP_updates_generic_known = 0;
static UInt n_SP_updates_generic_unknown = 0;
__attribute__((noinline))
void VG_print_translation_stats ( void )
{
HChar buf[6];
UInt n_SP_updates = n_SP_updates_fast + n_SP_updates_generic_known
+ n_SP_updates_generic_unknown;
VG_percentify(n_SP_updates_fast, n_SP_updates, 1, 6, buf);
VG_(printf)(
"translate: fast SP updates identified: %'u (%s)\n",
n_SP_updates_fast, buf );
VG_percentify(n_SP_updates_generic_known, n_SP_updates, 1, 6, buf);
VG_(printf)(
"translate: generic_known SP updates identified: %'u (%s)\n",
n_SP_updates_generic_known, buf );
VG_percentify(n_SP_updates_generic_unknown, n_SP_updates, 1, 6, buf);
VG_(printf)(
"translate: generic_unknown SP updates identified: %'u (%s)\n",
n_SP_updates_generic_unknown, buf );
}
int main ( void )
{
VG_print_translation_stats();
return 0;
}
@@ -0,0 +1,30 @@
Invalid read of size 1
at 0x........: local_strlen (bad_percentify.c:138)
by 0x........: VG_vsprintf (bad_percentify.c:535)
by 0x........: VG_sprintf (bad_percentify.c:545)
by 0x........: VG_percentify (bad_percentify.c:572)
by 0x........: VG_print_translation_stats (bad_percentify.c:625)
by 0x........: main (bad_percentify.c:645)
Address 0x........ expected vs actual:
Expected: stack array "buf" of size 6 in frame 4 back from here
Actual: unknown
Actual: is 0 after Expected
Invalid read of size 1
at 0x........: local_strlen (bad_percentify.c:138)
by 0x........: myvprintf_str (bad_percentify.c:187)
by 0x........: VG_debugLog_vprintf (bad_percentify.c:490)
by 0x........: vprintf_to_buf (bad_percentify.c:89)
by 0x........: vprintf_WRK (bad_percentify.c:102)
by 0x........: VG_vprintf (bad_percentify.c:115)
by 0x........: VG_printf (bad_percentify.c:124)
by 0x........: VG_print_translation_stats (bad_percentify.c:626)
by 0x........: main (bad_percentify.c:645)
Address 0x........ expected vs actual:
Expected: stack array "buf" of size 6 in frame 7 back from here
Actual: unknown
Actual: is 0 after Expected
ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 0 from 0)
@@ -0,0 +1,3 @@
translate: fast SP updates identified: 0 ( --%)
translate: generic_known SP updates identified: 0 ( --%)
translate: generic_unknown SP updates identified: 0 ( --%)
@@ -0,0 +1,2 @@
prereq: ./is_arch_supported && (../../tests/os_test linux || ../../tests/os_test solaris)
prog: bad_percentify
@@ -0,0 +1,8 @@
#! /bin/sh
dir=`dirname $0`
$dir/filter_stderr |
# Anonymise "before" distances (if greater than 9 bytes)
sed "s/Address 0x........ is [0-9][0-9]\+ bytes /Address 0x........ is ... bytes /"
@@ -0,0 +1,38 @@
#! /bin/sh
dir=`dirname $0`
$dir/../../tests/filter_stderr_basic |
# Anonymise addresses
$dir/../../tests/filter_addresses |
# Anonymise paths like "(in /foo/bar/libc-baz.so)"
sed "s/(in \/.*libc.*)$/(in \/...libc...)/" |
sed "s/(in \/.*libpthread.*)$/(in \/...libpthread...)/" |
# Anonymise paths like "__libc_start_main (../foo/bar/libc-quux.c:129)"
sed "s/__libc_\(.*\) (.*)$/__libc_\1 (...libc...)/" |
# Remove preambly stuff; also postambly stuff
sed \
-e "/^exp-sgcheck, a stack and global array overrun detector$/d" \
-e "/^NOTE: This is an Experimental-Class Valgrind Tool$/d" \
-e "/^Copyright (C) 2003-201., and GNU GPL'd, by OpenWorks Ltd et al.$/d" \
-e "/^For counts of detected and suppressed errors, rerun with: -v$/d" |
# Tidy up in cases where glibc (+ libdl + libpthread + ld) have
# been built with debugging information, hence source locs are present.
sed \
-e "s/ vfprintf (.*)/ .../" \
-e "s/ vsprintf (.*)/ .../" \
-e "s/ sprintf (.*)/ .../" \
-e "s/ printf (.*)/ .../" \
-e "s/ strdup (.*)/ .../" \
-e "s/(pthread_key_create.c:[0-9]*)/(in \/...libpthread...)/" \
-e "s/(genops.c:[0-9]*)/(in \/...libc...)/" \
-e "s/(syscall-template.S:[0-9]*)/(in \/...libc...)/" |
# Anonymise line numbers in h_intercepts.c.
sed "s/h_intercepts.c:[0-9]*/h_intercepts.c:.../"
@@ -0,0 +1,11 @@
#! /bin/sh
dir=`dirname $0`
$dir/filter_stderr |
# Anonymise "obj:" path
sed "s/obj:.*\/annelid\/tests\/supp/obj:*\/annelid\/tests\/supp/"
@@ -0,0 +1,15 @@
#include <stdio.h>
short a[7];
static short b[7];
int main ( void )
{
int i;
short sum;
for (i = 0; i < 7+1; i++) {
sum += a[i] * b[i];
}
return 1 & ((unsigned int)sum / 1000000);
}
@@ -0,0 +1,17 @@
Invalid read of size 2
at 0x........: main (globalerr.c:12)
Address 0x........ expected vs actual:
Expected: global array "a" of size 14 in object with soname "NONE"
Actual: unknown
Actual: is 0 after Expected
Invalid read of size 2
at 0x........: main (globalerr.c:12)
Address 0x........ expected vs actual:
Expected: global array "b" of size 14 in object with soname "NONE"
Actual: global array "a" of size 14 in object with soname "NONE"
Actual: is 0 after Expected
ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
@@ -0,0 +1,17 @@
Invalid read of size 2
at 0x........: main (globalerr.c:12)
Address 0x........ expected vs actual:
Expected: global array "a" of size 14 in object with soname "NONE"
Actual: unknown
Actual: is 0 after Expected
Invalid read of size 2
at 0x........: main (globalerr.c:12)
Address 0x........ expected vs actual:
Expected: global array "b" of size 14 in object with soname "NONE"
Actual: unknown
Actual: is 0 after Expected
ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
@@ -0,0 +1,2 @@
prereq: ./is_arch_supported && (../../tests/os_test linux || ../../tests/os_test solaris)
prog: globalerr
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,17 @@
Invalid read of size 1
at 0x........: vex_strlen (hackedbz2.c:1006)
by 0x........: add_to_myprintf_buf (hackedbz2.c:1284)
by 0x........: vex_printf (hackedbz2.c:1155)
by 0x........: BZ2_compressBlock (hackedbz2.c:4039)
by 0x........: handle_compress (hackedbz2.c:4761)
by 0x........: BZ2_bzCompress (hackedbz2.c:4831)
by 0x........: BZ2_bzBuffToBuffCompress (hackedbz2.c:5638)
by 0x........: main (hackedbz2.c:6484)
Address 0x........ expected vs actual:
Expected: global array "myprintf_buf" of size 70 in object with soname "NONE"
Actual: unknown
Actual: is 0 after Expected
ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
@@ -0,0 +1,70 @@
22323 bytes read
block 1: crc = 0xA212ABF8, combined CRC = 0xA212ABF8, size = 22373
too repetitive; using fallback sorting algorithm
22373 in block, 13504 after MTF & 1-2 coding, 79+2 syms in use
pass 1: size is 17143, grp uses are 38 62 2 92 6 71
pass 2: size is 6506, grp uses are 28 71 0 86 9 77
pass 3: size is 6479, grp uses are 26 70 0 81 11 83
pass 4: size is 6469, grp uses are 26 69 0 74 17 85
bytes: mapping 19, selectors 66, code lengths 134, codes 6465
final combined CRC = 0xA212ABF8
6710 after compression
bit 0 -5 DATA_ERROR_MAGIC
bit 1 -5 DATA_ERROR_MAGIC
bit 2 -5 DATA_ERROR_MAGIC
bit 3 -5 DATA_ERROR_MAGIC
bit 4 -5 DATA_ERROR_MAGIC
bit 5 -5 DATA_ERROR_MAGIC
bit 6 -5 DATA_ERROR_MAGIC
bit 7 -5 DATA_ERROR_MAGIC
bit 8 -5 DATA_ERROR_MAGIC
bit 9 -5 DATA_ERROR_MAGIC
bit 10 -5 DATA_ERROR_MAGIC
bit 11 -5 DATA_ERROR_MAGIC
bit 12 -5 DATA_ERROR_MAGIC
bit 13 -5 DATA_ERROR_MAGIC
bit 14 -5 DATA_ERROR_MAGIC
bit 15 -5 DATA_ERROR_MAGIC
bit 16 -5 DATA_ERROR_MAGIC
bit 17 -5 DATA_ERROR_MAGIC
bit 18 -5 DATA_ERROR_MAGIC
bit 19 -5 DATA_ERROR_MAGIC
bit 20 -5 DATA_ERROR_MAGIC
bit 21 -5 DATA_ERROR_MAGIC
bit 22 -5 DATA_ERROR_MAGIC
bit 23 -5 DATA_ERROR_MAGIC
bit 24 0 OK really ok!
bit 25 -5 DATA_ERROR_MAGIC
bit 26 -5 DATA_ERROR_MAGIC
bit 27 0 OK really ok!
bit 28 -5 DATA_ERROR_MAGIC
bit 29 -5 DATA_ERROR_MAGIC
bit 30 -5 DATA_ERROR_MAGIC
bit 31 -5 DATA_ERROR_MAGIC
bit 32 -4 DATA_ERROR
bit 33 -4 DATA_ERROR
bit 34 -4 DATA_ERROR
bit 35 -4 DATA_ERROR
bit 2412 -4 DATA_ERROR
bit 4789 -4 DATA_ERROR
bit 7166 -4 DATA_ERROR
bit 9543 -4 DATA_ERROR
bit 11920 -4 DATA_ERROR
bit 14297 -4 DATA_ERROR
bit 16674 -4 DATA_ERROR
bit 19051 -4 DATA_ERROR
bit 21428 -4 DATA_ERROR
bit 23805 -4 DATA_ERROR
bit 26182 -4 DATA_ERROR
bit 28559 -4 DATA_ERROR
bit 30936 -4 DATA_ERROR
bit 33313 -4 DATA_ERROR
bit 35690 -4 DATA_ERROR
bit 38067 -4 DATA_ERROR
bit 40444 -4 DATA_ERROR
bit 42821 -4 DATA_ERROR
bit 45198 -4 DATA_ERROR
bit 47575 -4 DATA_ERROR
bit 49952 -4 DATA_ERROR
bit 52329 -4 DATA_ERROR
all ok
@@ -0,0 +1,2 @@
prereq: ./is_arch_supported && (../../tests/os_test linux || ../../tests/os_test solaris)
prog: hackedbz2
@@ -0,0 +1,48 @@
/* A simple test to demonstrate heap, stack, and global overrun
detection. */
#include <stdio.h>
#include <stdlib.h>
short ga[100];
__attribute__((noinline))
int addup_wrongly ( short* arr )
{
int sum = 0, i;
for (i = 0; i <= 100; i++)
sum += (int)arr[i];
return sum;
}
__attribute__((noinline))
int do_other_stuff ( void )
{
short la[100];
return 123 + addup_wrongly(la);
}
__attribute__((noinline))
int do_stupid_malloc_stuff ( void )
{
int sum = 0;
unsigned char* duh = malloc(100 * sizeof(char));
sum += duh[-1];
free(duh);
sum += duh[50];
return sum;
}
int main ( void )
{
long s = addup_wrongly(ga);
s += do_other_stuff();
s += do_stupid_malloc_stuff();
if (s == 123456789) {
fprintf(stdout, "well, i never!\n");
} else {
fprintf(stdout, "boringly as expected\n");
}
return 0;
}
@@ -0,0 +1,116 @@
<?xml version="1.0"?>
<valgrindoutput>
<protocolversion>4</protocolversion>
<protocoltool>exp-sgcheck</protocoltool>
<preamble>
<line>...</line>
<line>...</line>
<line>...</line>
<line>...</line>
<line>...</line>
</preamble>
<pid>...</pid>
<ppid>...</ppid>
<tool>exp-sgcheck</tool>
<args>
<vargv>...</vargv>
<argv>
<exe>./hsg</exe>
</argv>
</args>
<status>
<state>RUNNING</state>
<time>...</time>
</status>
<error>
<unique>0x........</unique>
<tid>...</tid>
<kind>SorG</kind>
<what>Invalid read of size 2</what>
<stack>
<frame>
<ip>0x........</ip>
<obj>...</obj>
<fn>addup_wrongly</fn>
<dir>...</dir>
<file>hsg.c</file>
<line>...</line>
</frame>
<frame>
<ip>0x........</ip>
<obj>...</obj>
<fn>main</fn>
<dir>...</dir>
<file>hsg.c</file>
<line>...</line>
</frame>
</stack>
<auxwhat>Address 0x........ expected vs actual:</auxwhat>
<auxwhat>Expected: global array "ga" of size 200 in object with soname "NONE"</auxwhat>
<auxwhat>Actual: unknown</auxwhat>
</error>
<error>
<unique>0x........</unique>
<tid>...</tid>
<kind>SorG</kind>
<what>Invalid read of size 2</what>
<stack>
<frame>
<ip>0x........</ip>
<obj>...</obj>
<fn>addup_wrongly</fn>
<dir>...</dir>
<file>hsg.c</file>
<line>...</line>
</frame>
<frame>
<ip>0x........</ip>
<obj>...</obj>
<fn>do_other_stuff</fn>
<dir>...</dir>
<file>hsg.c</file>
<line>...</line>
</frame>
<frame>
<ip>0x........</ip>
<obj>...</obj>
<fn>main</fn>
<dir>...</dir>
<file>hsg.c</file>
<line>...</line>
</frame>
</stack>
<auxwhat>Address 0x........ expected vs actual:</auxwhat>
<auxwhat>Expected: stack array "la" of size 200 in frame 1 back from here</auxwhat>
<auxwhat>Actual: unknown</auxwhat>
</error>
<status>
<state>FINISHED</state>
<time>...</time>
</status>
<errorcounts>
<pair>
<count>...</count>
<unique>0x........</unique>
</pair>
<pair>
<count>...</count>
<unique>0x........</unique>
</pair>
</errorcounts>
<suppcounts>...</suppcounts>
</valgrindoutput>
@@ -0,0 +1 @@
boringly as expected
@@ -0,0 +1,4 @@
prereq: ./is_arch_supported && (../../tests/os_test linux || ../../tests/os_test solaris)
prog: hsg
vgopts: --xml=yes --xml-fd=2 --log-file=/dev/null
stderr_filter: ../../memcheck/tests/filter_xml
@@ -0,0 +1,15 @@
#!/bin/sh
#
# Not all architectures are supported by exp-ptr. Currently, PowerPC, s390x,
# MIPS and ARM are not supported and will fail these tests as follows:
# WARNING: exp-ptrcheck on <blah> platforms: stack and global array
# WARNING: checking is not currently supported. Only heap checking is
# WARNING: supported.
#
# So we use this script to prevent these tests from running on unsupported
# architectures.
case `uname -m` in
ppc*|arm*|s390x|mips*|tilegx) exit 1;;
*) exit 0;;
esac
@@ -0,0 +1,52 @@
#include <stdio.h>
#include <assert.h>
#include <dlfcn.h>
/* see comments in preen_invar_so.c for explanation of this */
int main ( void )
{
int i, r, sum = 0;
char* im_a_global_array;
void* hdl = dlopen("./preen_invars_so.so", RTLD_NOW);
assert(hdl);
im_a_global_array = dlsym(hdl, "im_a_global_array");
assert(im_a_global_array);
/* printf("%p %p\n", im_a_global_array, me_too_me_too); */
/* poke around in the global array, so as to cause exp-ptrcheck
to generate an Inv_Global invar for it. */
for (i = 10/*ERROR*/; i >= 0; i--) {
sum += im_a_global_array[i];
}
/* iterating 10 .. 0 causes an Unknown->Global transition at i = 9.
We do it this way in order that at the end of a loop, there is a
Global invar in place for the memory read in the loop, so that
the subsequent dlclose (hence munmap) causes it to get preened.
Unfortunately there's nothing to show that the preen was
successful or happened at all. The only way to see is from the
-v output:
--686-- sg_: 251 Invars preened, of which 1 changed
It's the "1 changed" bit which is significant.
*/
/* let's hope gcc is not clever enough to optimise this away, since
if it does, then it will also nuke the preceding loop, and
thereby render this test program useless. */
if (sum & 1) printf("%s bar %d\n", "foo", sum & 1); else
printf("foo %s %d\n", "bar", 1 - (sum & 1));
/* Now close (== unmap) the array, so that exp-ptrcheck has to check
its collection of Inv_Global invars, and remove this one from
it. */
r = dlclose(hdl);
assert(r == 0);
return 0;
}
@@ -0,0 +1,9 @@
Invalid read of size 1
at 0x........: main (preen_invars.c:22)
Address 0x........ expected vs actual:
Expected: unknown
Actual: global array "im_a_global_arr" of size 10 in object with soname "preen_invars_so"
ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
@@ -0,0 +1 @@
foo bar 1
@@ -0,0 +1,2 @@
prereq: ./is_arch_supported && (../../tests/os_test linux || ../../tests/os_test solaris)
prog: preen_invars
@@ -0,0 +1,12 @@
/* This file contains a global array. It is compiled into a .so,
which is dlopened by preen_invar.c. That then accesses the global
array, hence generating Inv_Global invariants in sg_main.c.
preen_invar.c then dlcloses this object, causing it to get
unmapped; and we then need to be sure that the Inv_Global is
removed by preen_Invars (or, at least, that the system doesn't
crash..). */
char im_a_global_array[10];
@@ -0,0 +1,53 @@
/* Check basic stack overflow detection.
It's difficult to get consistent behaviour across all platforms.
For example, x86 w/ gcc-4.3.1 gives
Expected: stack array "a" in frame 2 back from here
Actual: stack array "beforea" in frame 2 back from here
whereas amd64 w/ gcc-4.3.1 gives
Expected: stack array "a" in frame 2 back from here
Actual: unknown
This happens because on x86 the arrays are placed on the
stack without holes in between, but not so for amd64. I don't
know why.
*/
#include <stdio.h>
__attribute__((noinline)) void foo ( long* sa, int n )
{
int i;
for (i = 0; i < n; i++)
sa[i] = 0;
}
__attribute__((noinline)) void bar ( long* sa, int n )
{
foo(sa, n);
}
int main ( void )
{
int i;
long beforea[3];
long a[7];
long aftera[3];
bar(a, 7+1); /* generates error */
bar(a, 7+0); /* generates no error */
for (i = 0; i < 7+1; i++) {
a[i] = 0;
}
{char beforebuf[8];
char buf[8];
char afterbuf[8];
sprintf(buf, "%d", 123456789);
return 1 & ((a[4] + beforea[1] + aftera[1] + beforebuf[1]
+ buf[2] + afterbuf[3]) / 100000) ;
}
}
@@ -0,0 +1,28 @@
Invalid write of size 4
at 0x........: foo (stackerr.c:27)
by 0x........: bar (stackerr.c:32)
by 0x........: main (stackerr.c:41)
Address 0x........ expected vs actual:
Expected: stack array "a" of size 28 in frame 2 back from here
Actual: stack array "beforea" of size 12 in frame 2 back from here
Actual: is 0 after Expected
Invalid write of size 4
at 0x........: main (stackerr.c:44)
Address 0x........ expected vs actual:
Expected: stack array "a" of size 28 in this frame
Actual: stack array "beforea" of size 12 in this frame
Actual: is 0 after Expected
Invalid write of size 1
at 0x........: _IO_default_xsputn (in /...libc...)
by 0x........: ...
by 0x........: ...
Address 0x........ expected vs actual:
Expected: stack array "buf" of size 8 in frame 4 back from here
Actual: stack array "beforebuf" of size 8 in frame 4 back from here
Actual: is 0 after Expected
ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
@@ -0,0 +1,28 @@
Invalid write of size 8
at 0x........: foo (stackerr.c:27)
by 0x........: bar (stackerr.c:32)
by 0x........: main (stackerr.c:41)
Address 0x........ expected vs actual:
Expected: stack array "a" of size 56 in frame 2 back from here
Actual: unknown
Actual: is 0 after Expected
Invalid write of size 8
at 0x........: main (stackerr.c:44)
Address 0x........ expected vs actual:
Expected: stack array "a" of size 56 in this frame
Actual: unknown
Actual: is 0 after Expected
Invalid write of size 1
at 0x........: _IO_default_xsputn (in /...libc...)
by 0x........: ...
by 0x........: ...
Address 0x........ expected vs actual:
Expected: stack array "buf" of size 8 in frame 4 back from here
Actual: unknown
Actual: is 0 after Expected
ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
@@ -0,0 +1,3 @@
prereq: ./is_arch_supported && (../../tests/os_test linux || ../../tests/os_test solaris)
vgopts: --num-callers=3
prog: stackerr