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:
parent
c0b4abafb6
commit
2f5b116842
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
// 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.
|
||||
else
|
||||
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:
|
||||
|
||||
// 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
|
||||
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;
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user