1
0
forked from 0ad/0ad

mmgr: remove random fill option (makes no sense, since we want to fill with unused and freed memory pattern only)

snd: better explain __try hack; avoid any updates if not initialized
ia32: no longer user declspec(naked) (unsafe)
wdbg_sym: also declspec(naked) and refactor display of libstdc++ objects
wdll: remove redundant #undef
wsdl: add comment

This was SVN commit r2487.
This commit is contained in:
janwas 2005-07-16 17:49:38 +00:00
parent c0b4abafb6
commit 2f5b116842
6 changed files with 78 additions and 73 deletions

View File

@ -99,12 +99,10 @@ static void unlock() throw()
// enable all checks (slow!)
#ifdef PARANOIA
static uint options = MMGR_ALL;
static bool random_fill = true;
static const size_t padding_size = 256 * sizeof(ulong);
// normal settings
#else
static uint options = 0;
static bool random_fill = true;
static const size_t padding_size = 1 * sizeof(ulong);
#endif
@ -384,32 +382,6 @@ static const ulong pattern_freed = 0xdeadbeef;
static void pattern_set(const Alloc* a, ulong pattern)
{
// For a serious test run, we use wipes of random a random value.
// However, if this causes a crash, we don't want it to crash in a
// different place each time, so we specifically DO NOT call srand.
// If, by chance your program calls srand(), you may wish to disable
// that when running with a random wipe test. This will make any
// crashes more consistent so they can be tracked down.
if(random_fill)
{
// note: rand typically returns 16 bits,
// so one call isn't enough.
pattern = 0;
for(size_t shift = 0; shift < sizeof(ulong)*8; shift += 8)
pattern |= (rand() & 0xff) << shift;
}
// We should wipe with zero if we're not in debug mode, so we can
// help hide bugs if possible when we release the product.
//
// Note that options & MMGR_FILL should be turned on for this to have
// any effect, otherwise it won't do much good. But we'll leave it
// this way (as an option) because this does slow things down.
#ifndef NDEBUG
pattern = 0;
#endif
// fill user's data (optional)
// note: don't use memset, because we want multi-byte patterns
if(options & MMGR_FILL && a->user_size() > 0)

View File

@ -200,6 +200,7 @@ static int alc_init()
// we hold a reference to prevent the actual unload,
// thus speeding up startup by 100..400 ms. everything works ATM;
// hopefully, OpenAL doesn't rely on them actually being unloaded.
#ifdef _WIN32
HMODULE dlls[3];
dlls[0] = LoadLibrary("wrap_oal.dll");
@ -208,9 +209,10 @@ static int alc_init()
#endif
// for reasons unknown, the NV native OpenAL implementation
// causes an invalid exception internally when loaded (it's not
// caused by the DLL load hack above). we need to catch it to
// prevent the unhandled exception filter from reporting it.
// causes an "invalid handle" exception internally when loaded
// (it's not caused by the DLL load hack above). everything works and
// we can continue normally; we just need to catch it to prevent the
// unhandled exception filter from reporting it.
#ifdef _WIN32
__try
{
@ -1725,6 +1727,14 @@ static int vm_update()
// (allow any and all of them to be 0 in case world isn't initialized yet).
int snd_update(const float* pos, const float* dir, const float* up)
{
// there's no sense in updating anything if we weren't initialized
// yet (most notably, if sound is disabled). we check for this to
// avoid confusing the code below. the caller should complain if
// this fails, so report success here (everything will work once
// sound is re-enabled).
if(!al_initialized)
return 0;
if(pos || dir || up)
al_listener_set_pos(pos, dir, up);

View File

@ -166,7 +166,7 @@ __asm
// (optimized for size)
static void __declspec(naked) cpuid()
static void cpuid()
{
__asm
{
@ -253,7 +253,6 @@ no_ext_funcs:
no_cpuid:
popad
ret
} // __asm
} // cpuid()
@ -266,7 +265,7 @@ bool ia32_cap(CpuCap cap)
debug_warn("cap invalid");
return false;
}
u32 bit = 1ul << (cap & 0x1f);
u32 bit = BIT(cap & 0x1f);
return (caps[idx] & bit) != 0;
}
@ -596,18 +595,17 @@ $no_lock:
}
__declspec(naked) void __cdecl atomic_add(intptr_t* location, intptr_t increment)
void atomic_add(intptr_t* location, intptr_t increment)
{
__asm
{
cmp byte ptr [cpus], 1
mov edx, [esp+4] // location
mov eax, [esp+8] // increment
mov edx, [location]
mov eax, [increment]
je $no_lock
_emit 0xf0 // LOCK prefix
$no_lock:
add [edx], eax
ret
}
}

View File

@ -282,13 +282,24 @@ int debug_resolve_symbol(void* ptr_of_interest, char* sym_name, char* file, int*
#ifdef _M_IX86
// optimized for size.
static __declspec(naked) void __cdecl get_current_context(void* pcontext)
static void get_current_context(void* pcontext)
{
// for safety and future-proofing, we do not use __declspec(naked) and
// access the parameter ourselves. therefore, we need to grab it into
// a register before PUSHAD, which means we'd lose the register's
// previous contents. save it here to prevent that.
static u32 saved_eax;
__asm
{
;// don't write into edi directly so that the compiler (if clever)
;// doesn't need to generate register-save code.
mov [saved_eax], eax
mov eax, [pcontext]
pushad
pushfd
mov edi, [esp+4+32+4] ;// pcontext
xchg eax, edi ;// edi = (CONTEXT*)pcontext
;// ContextFlags
mov eax, 0x10007 ;// segs, int, control
@ -323,14 +334,16 @@ rep stosd
stosd
mov eax, [esp+4+32-8] ;// ecx
stosd
mov eax, [esp+4+32-4] ;// eax
mov eax, [saved_eax]
stosd
;// CONTEXT_CONTROL
xchg eax, ebp
mov eax, ebp ;// despite being smaller, don't use XCHG -
;// avoids silly "modifying ebp" warning
;// (we restore via POPAD, but VC is stupid)
stosd
mov eax, [esp+4+32] ;// eip
sub eax, 5 ;// back up to call site from ret addr
mov eax, [esp+4+32] ;// return address
sub eax, 5 ;// skip CALL instruction -> call site.
stosd
xor eax, eax
mov ax, cs
@ -1420,38 +1433,57 @@ static int udt_get_child_type(const wchar_t* child_name,
}
static int udt_dump_stl(const wchar_t* wtype_name, const u8* p, size_t size, DumpState state,
static int udt_dump_std(const wchar_t* wtype_name, const u8* p, size_t size, DumpState state,
ULONG num_children, const DWORD* children)
{
int err;
// not a C++ standard library object; can't handle it.
if(wcsncmp(wtype_name, L"std::", 5) != 0)
return 1;
// check for C++ objects that should be displayed via udt_dump_normal.
// STL containers are special-cased and the rest (apart from those here)
// are ignored, because for the most part they are spew.
if(!wcsncmp(wtype_name, L"std::pair", 9))
return 1;
// convert to char since debug_stl doesn't support wchar_t.
char ctype_name[DBG_SYMBOL_LEN];
snprintf(ctype_name, ARRAY_SIZE(ctype_name), "%ws", wtype_name);
// display contents of STL containers
// .. get element type
DWORD el_type_id;
size_t el_size;
err = udt_get_child_type(L"value_type", num_children, children, &el_type_id, &el_size);
if(err != 0)
return err;
// debug_stl doesn't support wchar_t.
char ctype_name[DBG_SYMBOL_LEN];
snprintf(ctype_name, ARRAY_SIZE(ctype_name), "%ws", wtype_name);
goto not_valid_container;
// .. get iterator and # elements
size_t el_count;
DebugIterator el_iterator;
u8 it_mem[DEBUG_STL_MAX_ITERATOR_SIZE];
err = stl_get_container_info(ctype_name, p, size, el_size, &el_count, &el_iterator, it_mem);
if(err != 0)
goto not_valid_container;
return dump_sequence(el_iterator, it_mem, el_count, el_type_id, el_size, state);
not_valid_container:
// type_name is unknown; can't handle it.
if(err == STL_CNT_UNKNOWN)
return 1;
// contents are invalid (uninitialized or corrupted)
else if(err == STL_CNT_INVALID)
{
out(L"(uninitialized/invalid %hs)", stl_simplify_name(ctype_name));
return 0;
}
// supported and valid: output each element.
// build and display detailed "error" message.
char buf[100];
const char* text = buf;
// .. C++ stdlib object that we didn't want to display
// (just output its simplified type)
if(err == STL_CNT_UNKNOWN || err == 1)
text = "";
// .. container of a known type but contents are invalid
if(err == STL_CNT_INVALID)
text = "uninitialized/invalid ";
// .. some other error encountered
else
return dump_sequence(el_iterator, it_mem, el_count, el_type_id, el_size, state);
snprintf(buf, ARRAY_SIZE(buf), "error %d while analyzing ", err);
out(L"(%hs%hs)", text, stl_simplify_name(ctype_name));
return 0;
}
@ -1507,15 +1539,6 @@ not_handle:
static int udt_dump_suppressed(const wchar_t* type_name, const u8* p, size_t size,
DumpState state, ULONG num_children, const DWORD* children)
{
// avoid C++ library objects, since they result in serious spew.
if(!wcsncmp(type_name, L"std::pair", 9)) // allow
return 1;
if(!wcsncmp(type_name, L"std::", 5))
{
out(L"(%s)", type_name);
return 0;
}
if(!udt_should_suppress(type_name))
return 1;
@ -1660,7 +1683,7 @@ static int dump_sym_udt(DWORD type_id, const u8* p, DumpState state)
// note: order is important (e.g. STL special-case must come before
// suppressing UDTs, which tosses out most other C++ stdlib classes)
ret = udt_dump_stl (type_name, p, size, state, num_children, children);
ret = udt_dump_std (type_name, p, size, state, num_children, children);
if(ret <= 0)
goto done;

View File

@ -1,7 +1,6 @@
// modified from VC7 DelayHlp.cpp and DelayImp.h
#include "precompiled.h"
#undef new // because it conflicts with some other uses of new
#include "win_internal.h"

View File

@ -882,6 +882,9 @@ SDL_VideoInfo* SDL_GetVideoInfo()
// For very [very] basic memory-usage information.
// Should be replaced by a decent memory profiler.
//
// copied from SDL_GetVideoInfo but cannot be implemented in terms of it:
// SDL_VideoInfo doesn't provide for returning "remaining video memory".
int GetVRAMInfo(int& remaining, int& total)
{
int ok = 0;