Add support for poison=overwrite
This commit is contained in:
parent
2cc77d647f
commit
4be02cd9c5
34
SConstruct
34
SConstruct
|
@ -817,8 +817,11 @@ static void a(){{
|
||||||
raise SCons.Errors.StopError("Compiler cannot handle tuples of 2 elements.")
|
raise SCons.Errors.StopError("Compiler cannot handle tuples of 2 elements.")
|
||||||
@_implicit_test
|
@_implicit_test
|
||||||
def check_poison_valgrind(self,context):
|
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)
|
context.Result(r)
|
||||||
if not r:
|
if not r:
|
||||||
return
|
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']}):
|
if self.Compile(context, text=text, main=main, msg='whether Valgrind memcheck header works', successflags={'CPPDEFINES' : ['DXX_HAVE_POISON_VALGRIND']}):
|
||||||
return True
|
return True
|
||||||
raise SCons.Errors.StopError("Valgrind poison requested, but <valgrind/memcheck.h> does not work.")
|
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
|
@_custom_test
|
||||||
def _check_poison_method(self,context):
|
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')
|
context.sconf.Define('DXX_HAVE_POISON')
|
||||||
|
|
||||||
class LazyObjectConstructor:
|
class LazyObjectConstructor:
|
||||||
|
@ -1029,7 +1050,12 @@ class DXXCommon(LazyObjectConstructor):
|
||||||
'variable': self._enum_variable,
|
'variable': self._enum_variable,
|
||||||
'arguments': (
|
'arguments': (
|
||||||
('host_platform', 'linux' if sys.platform == 'linux2' else sys.platform, 'cross-compile to specified platform', {'allowed_values' : ['win32', 'darwin', 'linux']}),
|
('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')}),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,7 +16,8 @@ static inline void DXX_MAKE_MEM_UNDEFINED(T *b, unsigned long l)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static inline void DXX_MAKE_MEM_UNDEFINED(T *b, T *e)
|
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>
|
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
|
#ifdef DXX_HAVE_POISON
|
||||||
int store = 0;
|
int store = 0;
|
||||||
|
#ifdef DXX_HAVE_POISON_OVERWRITE
|
||||||
|
store |= 1;
|
||||||
|
#endif
|
||||||
#ifdef DXX_HAVE_POISON_VALGRIND
|
#ifdef DXX_HAVE_POISON_VALGRIND
|
||||||
store |= RUNNING_ON_VALGRIND;
|
if (!store)
|
||||||
|
store |= RUNNING_ON_VALGRIND;
|
||||||
#endif
|
#endif
|
||||||
if (!store)
|
if (!store)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -83,6 +83,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
||||||
#include "compiler-range_for.h"
|
#include "compiler-range_for.h"
|
||||||
#include "highest_valid.h"
|
#include "highest_valid.h"
|
||||||
#include "partial_range.h"
|
#include "partial_range.h"
|
||||||
|
#include "poison.h"
|
||||||
|
|
||||||
using std::min;
|
using std::min;
|
||||||
using std::max;
|
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
|
// Zero out object structure to keep weird bugs from happening
|
||||||
// in uninitialized fields.
|
// in uninitialized fields.
|
||||||
*obj = {};
|
*obj = {};
|
||||||
|
// Tell Valgrind to warn on any uninitialized fields.
|
||||||
|
DXX_MAKE_MEM_UNDEFINED(&*obj, sizeof(*obj));
|
||||||
|
|
||||||
obj->signature = obj_get_signature();
|
obj->signature = obj_get_signature();
|
||||||
obj->type = type;
|
obj->type = type;
|
||||||
|
@ -1252,7 +1255,7 @@ void obj_delete(const vobjptridx_t obj)
|
||||||
obj_unlink(obj);
|
obj_unlink(obj);
|
||||||
|
|
||||||
Assert(Objects[0].next != 0);
|
Assert(Objects[0].next != 0);
|
||||||
|
DXX_MAKE_MEM_UNDEFINED(&*obj, sizeof(*obj));
|
||||||
obj->type = OBJ_NONE; //unused!
|
obj->type = OBJ_NONE; //unused!
|
||||||
obj->signature = -1;
|
obj->signature = -1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue