Add support for poison=overwrite

This commit is contained in:
Kp 2015-01-03 23:44:32 +00:00
parent 2cc77d647f
commit 4be02cd9c5
3 changed files with 41 additions and 7 deletions

View file

@ -817,8 +817,11 @@ static void a(){{
raise SCons.Errors.StopError("Compiler cannot handle tuples of 2 elements.")
@_implicit_test
def check_poison_valgrind(self,context):
context.Display('%s: checking %s...' % (self.msgprefix, 'whether to use Valgrind poisoning'))
r = self.user_settings.poison == 'valgrind'
'''
help:add Valgrind annotations; wipe certain freed memory when running under Valgrind
'''
context.Message('%s: checking %s...' % (self.msgprefix, 'whether to use Valgrind poisoning'))
r = 'valgrind' in self.user_settings.poison
context.Result(r)
if not r:
return
@ -831,9 +834,27 @@ static void a(){{
if self.Compile(context, text=text, main=main, msg='whether Valgrind memcheck header works', successflags={'CPPDEFINES' : ['DXX_HAVE_POISON_VALGRIND']}):
return True
raise SCons.Errors.StopError("Valgrind poison requested, but <valgrind/memcheck.h> does not work.")
@_implicit_test
def check_poison_overwrite(self,context):
'''
help:always wipe certain freed memory
'''
context.Message('%s: checking %s...' % (self.msgprefix, 'whether to use overwrite poisoning'))
r = 'overwrite' in self.user_settings.poison
context.Result(r)
if r:
context.sconf.Define('DXX_HAVE_POISON_OVERWRITE')
return r
@_custom_test
def _check_poison_method(self,context):
if self.check_poison_valgrind(context):
poison = None
for f in (
self.check_poison_valgrind,
self.check_poison_overwrite,
):
if f(context):
poison = True
if poison:
context.sconf.Define('DXX_HAVE_POISON')
class LazyObjectConstructor:
@ -1029,7 +1050,12 @@ class DXXCommon(LazyObjectConstructor):
'variable': self._enum_variable,
'arguments': (
('host_platform', 'linux' if sys.platform == 'linux2' else sys.platform, 'cross-compile to specified platform', {'allowed_values' : ['win32', 'darwin', 'linux']}),
('poison', 'none', 'method for poisoning free memory', {'allowed_values' : ('none', 'valgrind')}),
),
},
{
'variable': ListVariable,
'arguments': (
('poison', 'none', 'method for poisoning free memory', {'names' : ('valgrind', 'overwrite')}),
),
},
{

View file

@ -16,7 +16,8 @@ static inline void DXX_MAKE_MEM_UNDEFINED(T *b, unsigned long l)
template <typename T>
static inline void DXX_MAKE_MEM_UNDEFINED(T *b, T *e)
{
DXX_MAKE_MEM_UNDEFINED(b, e - b);
unsigned char *bc = reinterpret_cast<unsigned char *>(b);
DXX_MAKE_MEM_UNDEFINED(bc, reinterpret_cast<unsigned char *>(e) - bc);
}
template <typename T, typename V>
@ -24,8 +25,12 @@ static inline void _DXX_POISON_MEMORY_RANGE(T b, T e, const V &v)
{
#ifdef DXX_HAVE_POISON
int store = 0;
#ifdef DXX_HAVE_POISON_OVERWRITE
store |= 1;
#endif
#ifdef DXX_HAVE_POISON_VALGRIND
store |= RUNNING_ON_VALGRIND;
if (!store)
store |= RUNNING_ON_VALGRIND;
#endif
if (!store)
return;

View file

@ -83,6 +83,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
#include "compiler-range_for.h"
#include "highest_valid.h"
#include "partial_range.h"
#include "poison.h"
using std::min;
using std::max;
@ -1109,6 +1110,8 @@ objptridx_t obj_create(object_type_t type, ubyte id,vsegptridx_t segnum,const vm
// Zero out object structure to keep weird bugs from happening
// in uninitialized fields.
*obj = {};
// Tell Valgrind to warn on any uninitialized fields.
DXX_MAKE_MEM_UNDEFINED(&*obj, sizeof(*obj));
obj->signature = obj_get_signature();
obj->type = type;
@ -1252,7 +1255,7 @@ void obj_delete(const vobjptridx_t obj)
obj_unlink(obj);
Assert(Objects[0].next != 0);
DXX_MAKE_MEM_UNDEFINED(&*obj, sizeof(*obj));
obj->type = OBJ_NONE; //unused!
obj->signature = -1;