- config.h: massive improvements, much clearer.
- tentatively activate PCH if gcc > 3.4. remove XP_ defines (which were undocumented; now in scripting/spidermonkey.h) - rename some config defines - move sysdep/debug.h to lib/debug.h (it's portable; was wrong all along) - grouped all debug heap related stuff to debug.h:debug_heap_* - sysdep: fix circular include issue with debug.h This was SVN commit r2427.
This commit is contained in:
parent
064dd5699d
commit
8f9a3fc38f
@ -1,98 +1,136 @@
|
||||
#ifndef CONFIG_H_INCLUDED
|
||||
#define CONFIG_H_INCLUDED
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// user-specified configuration choices
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#undef CONFIG_DISABLE_EXCEPTIONS
|
||||
|
||||
#undef CONFIG_USE_MMGR
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// auto-detect OS and platform via predefined macros
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// get compiler versions with consistent names + format:
|
||||
// (major*100 + minor), or 0 if not present. note that more than
|
||||
// one *_VERSION may be non-zero due to interoperability (e.g. ICC with MSC).
|
||||
// .. ICC
|
||||
#if defined(__INTEL_COMPILER)
|
||||
# define ICC_VERSION __INTEL_COMPILER
|
||||
#else
|
||||
# define ICC_VERSION 0
|
||||
#endif
|
||||
// .. VC
|
||||
#ifdef _MSC_VER
|
||||
# define MSC_VERSION _MSC_VER
|
||||
#else
|
||||
# define MSC_VERSION 0
|
||||
#endif
|
||||
// .. GCC
|
||||
#ifdef __GNUC__
|
||||
# define GCC_VERSION (__GNUC__*100 + __GNUC_MINOR__)
|
||||
#else
|
||||
# define GCC_VERSION 0
|
||||
#endif
|
||||
|
||||
//
|
||||
// OS
|
||||
//
|
||||
|
||||
// Windows
|
||||
// .. Windows
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
# define OS_WIN
|
||||
# define XP_WIN
|
||||
// Linux
|
||||
// .. Linux
|
||||
#elif defined(linux) || defined(__linux) || defined(__linux__)
|
||||
# define OS_LINUX
|
||||
# define OS_UNIX
|
||||
# ifndef XP_UNIX
|
||||
# define XP_UNIX
|
||||
# endif
|
||||
// Mac OS X
|
||||
// .. Mac OS X
|
||||
#elif defined(MAC_OS_X
|
||||
# define OS_MACOSX
|
||||
# define OS_UNIX
|
||||
# define XP_UNIX
|
||||
// Mac OS 9 or below
|
||||
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
|
||||
# define OS_MACOS
|
||||
# define XP_MAC
|
||||
// BSD
|
||||
// .. BSD
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
# define OS_BSD
|
||||
// Solaris
|
||||
# define OS_UNIX
|
||||
// .. Solaris
|
||||
#elif defined(SOLARIS)
|
||||
# define OS_SOLARIS
|
||||
// BeOS
|
||||
# define OS_UNIX
|
||||
// .. BeOS
|
||||
#elif defined(__BEOS__)
|
||||
# define OS_BEOS
|
||||
# define XP_BEOS
|
||||
// Amiga
|
||||
// .. Mac OS 9 or below
|
||||
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
|
||||
# define OS_MAC
|
||||
// .. Amiga
|
||||
#elif defined(__amigaos__)
|
||||
# define OS_AMIGA
|
||||
// Unix-based
|
||||
// .. Unix-based
|
||||
#elif defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE)
|
||||
# define OS_UNIX
|
||||
# define XP_UNIX
|
||||
// .. unknown
|
||||
#else
|
||||
# error "unknown OS - add define here"
|
||||
#endif
|
||||
|
||||
|
||||
#undef HAVE_C99 // compiler advertises support for C99
|
||||
|
||||
#undef HAVE_ASM
|
||||
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
#undef HAVE_X
|
||||
|
||||
#undef HAVE_PCH
|
||||
|
||||
#undef HAVE_DEBUGALLOC
|
||||
|
||||
#undef CONFIG_DISABLE_EXCEPTIONS
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// auto-detect platform features, given the above information
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// compiler support for C99
|
||||
// (this is more convenient than testing __STDC_VERSION__ directly)
|
||||
#undef HAVE_C99
|
||||
#ifdef __STDC_VERSION__ // nested #if to avoid ICC warning if not defined
|
||||
# if __STDC_VERSION__ >= 199901L
|
||||
# define HAVE_C99
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define HAVE_ASM
|
||||
# define HAVE_PCH
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(HAVE_PCH) && !( defined(NDEBUG) || defined(TESTING) )
|
||||
# ifdef SCED
|
||||
# define HAVE_DEBUGALLOC
|
||||
# else
|
||||
# ifndef USE_MMGR
|
||||
# define HAVE_DEBUGALLOC
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// gettimeofday()
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
#ifdef OS_UNIX
|
||||
# define HAVE_GETTIMEOFDAY
|
||||
#endif
|
||||
|
||||
// X server
|
||||
#undef HAVE_X
|
||||
#ifdef OS_LINUX
|
||||
# define HAVE_X
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// HACK: (please remove when this is no longer necessary)
|
||||
// The ICC 9.0.006 beta seems to generate buggy code when we redefine new,
|
||||
// so don't redefine new:
|
||||
#if defined(__INTEL_COMPILER) && __INTEL_COMPILER == 900
|
||||
# undef HAVE_DEBUGALLOC
|
||||
// __asm{} blocks (Intel syntax)
|
||||
#undef HAVE_ASM
|
||||
#if (MSC_VERSION != 0)
|
||||
# define HAVE_ASM
|
||||
#endif
|
||||
|
||||
// precompiled headers (affects what precompiled.h pulls in; see there)
|
||||
#undef HAVE_PCH
|
||||
#if (MSC_VERSION != 0) || (GCC_VERSION > 304)
|
||||
# define HAVE_PCH
|
||||
#endif
|
||||
|
||||
// VC debug memory allocator / leak detector
|
||||
#undef HAVE_VC_DEBUG_ALLOC
|
||||
#if (MSC_VERSION != 0)
|
||||
# define HAVE_VC_DEBUG_ALLOC
|
||||
#endif
|
||||
// .. only in full-debug mode;
|
||||
#if defined(NDEBUG) || defined(TESTING)
|
||||
# undef HAVE_VC_DEBUG_ALLOC
|
||||
#endif
|
||||
// .. require PCH, because it makes sure system headers are included before
|
||||
// redefining new (otherwise, tons of errors result);
|
||||
#if !defined(HAVE_PCH)
|
||||
# undef HAVE_VC_DEBUG_ALLOC
|
||||
#endif
|
||||
// .. disable on ICC9, because the ICC 9.0.006 beta appears to generate
|
||||
// incorrect code when we redefine new.
|
||||
// TODO: remove when no longer necessary
|
||||
#if ICC_VERSION == 900
|
||||
# undef HAVE_VC_DEBUG_ALLOC
|
||||
#endif
|
||||
|
||||
#endif // #ifndef CONFIG_H_INCLUDED
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "lib.h"
|
||||
#include "sysdep/debug.h"
|
||||
#include "debug.h"
|
||||
#include "nommgr.h"
|
||||
// some functions here are called from within mmgr; disable its hooks
|
||||
// so that our allocations don't cause infinite recursion.
|
||||
@ -507,8 +507,8 @@ ErrorReaction display_error(const wchar_t* description, int flags,
|
||||
{
|
||||
// disable memory-leak reporting to avoid a flood of warnings
|
||||
// (lots of stuff will leak since we exit abnormally).
|
||||
debug_disable_leak_reporting();
|
||||
#ifdef HAVE_MMGR
|
||||
debug_heap_enable(DEBUG_HEAP_NONE);
|
||||
#ifdef CONFIG_USE_MMGR
|
||||
mmgr_set_options(0);
|
||||
#endif
|
||||
|
||||
|
297
source/lib/sysdep/debug.h → source/lib/debug.h
Executable file → Normal file
297
source/lib/sysdep/debug.h → source/lib/debug.h
Executable file → Normal file
@ -1,142 +1,155 @@
|
||||
// platform-independent debug interface
|
||||
// Copyright (c) 2002-2005 Jan Wassenberg
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// Contact info:
|
||||
// Jan.Wassenberg@stud.uni-karlsruhe.de
|
||||
// http://www.stud.uni-karlsruhe.de/~urkt/
|
||||
|
||||
#ifndef DEBUG_H_INCLUDED
|
||||
#define DEBUG_H_INCLUDED
|
||||
|
||||
#include "sysdep.h" // ErrorReaction
|
||||
#ifdef _WIN32
|
||||
# include "win/wdbg.h"
|
||||
#else
|
||||
# include "unix/udbg.h"
|
||||
#endif
|
||||
|
||||
|
||||
// check heap integrity (independently of mmgr).
|
||||
// errors are reported by the CRT, e.g. via assert.
|
||||
extern void debug_check_heap(void);
|
||||
|
||||
extern void debug_disable_leak_reporting();
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// assert
|
||||
//
|
||||
|
||||
// notify the user that an assertion failed; displays a
|
||||
// stack trace with local variables.
|
||||
// returns one of UserErrorReaction.
|
||||
extern enum ErrorReaction debug_assert_failed(const char* source_file, int line, const char* assert_expr);
|
||||
|
||||
// recommended use: assert2(expr && "descriptive string")
|
||||
#define assert2(expr)\
|
||||
STMT(\
|
||||
static unsigned char suppress__ = 0x55;\
|
||||
if(suppress__ == 0x55 && !(expr))\
|
||||
switch(debug_assert_failed(__FILE__, __LINE__, #expr))\
|
||||
{\
|
||||
case ER_SUPPRESS:\
|
||||
suppress__ = 0xaa;\
|
||||
break;\
|
||||
case ER_BREAK:\
|
||||
debug_break();\
|
||||
break;\
|
||||
}\
|
||||
)
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// output
|
||||
//
|
||||
|
||||
// write to the debugger output window (may take ~1 ms!)
|
||||
extern void debug_printf(const char* fmt, ...);
|
||||
extern void debug_wprintf(const wchar_t* fmt, ...);
|
||||
|
||||
// write to memory buffer (fast)
|
||||
// used for "last activity" reporting in the crashlog.
|
||||
extern void debug_wprintf_mem(const wchar_t* fmt, ...);
|
||||
|
||||
// warn of unexpected state. less error-prone than assert(!"text");
|
||||
#define debug_warn(str) assert2(0 && (str))
|
||||
|
||||
// TODO
|
||||
extern int debug_write_crashlog(const wchar_t* text);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// breakpoints
|
||||
//
|
||||
|
||||
// trigger a breakpoint when reached/"called".
|
||||
// defined as a macro by the platform-specific header above; this allows
|
||||
// breaking directly into the target function, instead of one frame
|
||||
// below it as with a conventional call-based implementation.
|
||||
//#define debug_break()
|
||||
|
||||
|
||||
// sometimes mmgr's 'fences' (making sure padding before and after the
|
||||
// allocation remains intact) aren't enough to catch hard-to-find
|
||||
// memory corruption bugs. another tool is to trigger a debug exception
|
||||
// when the later to be corrupted variable is accessed; the problem should
|
||||
// then become apparent.
|
||||
// the VC++ IDE provides such 'breakpoints', but can only detect write access.
|
||||
// additionally, it can't resolve symbols in Release mode (where this would
|
||||
// be most useful), so we provide a breakpoint API.
|
||||
|
||||
// values chosen to match IA-32 bit defs, so compiler can optimize.
|
||||
// this isn't required, it'll work regardless.
|
||||
enum DbgBreakType
|
||||
{
|
||||
DBG_BREAK_CODE = 0, // execute
|
||||
DBG_BREAK_DATA_WRITE = 1, // write
|
||||
DBG_BREAK_DATA = 3 // read or write
|
||||
};
|
||||
|
||||
// arrange for a debug exception to be raised when <addr> is accessed
|
||||
// according to <type>.
|
||||
// for simplicity, the length (range of bytes to be checked) is derived
|
||||
// from addr's alignment, and is typically 1 machine word.
|
||||
// breakpoints are a limited resource (4 on IA-32); abort and
|
||||
// return ERR_LIMIT if none are available.
|
||||
extern int debug_set_break(void* addr, DbgBreakType type);
|
||||
|
||||
// remove all breakpoints that were set by debug_set_break.
|
||||
// important, since these are a limited resource.
|
||||
extern int debug_remove_all_breaks();
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// symbol access
|
||||
//
|
||||
|
||||
// TODO: rationale+comments
|
||||
|
||||
const size_t DBG_SYMBOL_LEN = 1000;
|
||||
const size_t DBG_FILE_LEN = 100;
|
||||
|
||||
extern void* debug_get_nth_caller(uint n);
|
||||
|
||||
extern int debug_resolve_symbol(void* ptr_of_interest, char* sym_name, char* file, int* line);
|
||||
|
||||
extern const wchar_t* debug_dump_stack(wchar_t* buf, size_t max_chars, uint skip, void* context);
|
||||
|
||||
#endif // #ifndef DEBUG_H_INCLUDED
|
||||
// platform-independent debug interface
|
||||
// Copyright (c) 2002-2005 Jan Wassenberg
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// Contact info:
|
||||
// Jan.Wassenberg@stud.uni-karlsruhe.de
|
||||
// http://www.stud.uni-karlsruhe.de/~urkt/
|
||||
|
||||
#ifndef DEBUG_H_INCLUDED
|
||||
#define DEBUG_H_INCLUDED
|
||||
|
||||
#include "sysdep/sysdep.h" // ErrorReaction
|
||||
#ifdef _WIN32
|
||||
# include "sysdep/win/wdbg.h"
|
||||
#else
|
||||
# include "sysdep/unix/udbg.h"
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// debug memory allocator
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// check heap integrity (independently of mmgr).
|
||||
// errors are reported by the CRT, e.g. via assert.
|
||||
extern void debug_heap_check(void);
|
||||
|
||||
enum DebugHeapChecks
|
||||
{
|
||||
// no automatic checks
|
||||
DEBUG_HEAP_NONE = 0,
|
||||
|
||||
// default automatic checks when deallocating
|
||||
DEBUG_HEAP_NORMAL = 1,
|
||||
|
||||
// all automatic checks on every memory API call. this is really
|
||||
// slow (x100), but reports errors closer to where they occurred.
|
||||
DEBUG_HEAP_ALL = 2
|
||||
};
|
||||
|
||||
extern void debug_heap_enable(DebugHeapChecks what);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// assert
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// notify the user that an assertion failed; displays a
|
||||
// stack trace with local variables.
|
||||
// returns one of UserErrorReaction.
|
||||
extern enum ErrorReaction debug_assert_failed(const char* source_file, int line, const char* assert_expr);
|
||||
|
||||
// recommended use: assert2(expr && "descriptive string")
|
||||
#define assert2(expr)\
|
||||
STMT(\
|
||||
static unsigned char suppress__ = 0x55;\
|
||||
if(suppress__ == 0x55 && !(expr))\
|
||||
switch(debug_assert_failed(__FILE__, __LINE__, #expr))\
|
||||
{\
|
||||
case ER_SUPPRESS:\
|
||||
suppress__ = 0xaa;\
|
||||
break;\
|
||||
case ER_BREAK:\
|
||||
debug_break();\
|
||||
break;\
|
||||
}\
|
||||
)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// output
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// write to the debugger output window (may take ~1 ms!)
|
||||
extern void debug_printf(const char* fmt, ...);
|
||||
extern void debug_wprintf(const wchar_t* fmt, ...);
|
||||
|
||||
// write to memory buffer (fast)
|
||||
// used for "last activity" reporting in the crashlog.
|
||||
extern void debug_wprintf_mem(const wchar_t* fmt, ...);
|
||||
|
||||
// warn of unexpected state. less error-prone than assert(!"text");
|
||||
#define debug_warn(str) assert2(0 && (str))
|
||||
|
||||
// TODO
|
||||
extern int debug_write_crashlog(const wchar_t* text);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// breakpoints
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// trigger a breakpoint when reached/"called".
|
||||
// defined as a macro by the platform-specific header above; this allows
|
||||
// breaking directly into the target function, instead of one frame
|
||||
// below it as with a conventional call-based implementation.
|
||||
//#define debug_break()
|
||||
|
||||
|
||||
// sometimes mmgr's 'fences' (making sure padding before and after the
|
||||
// allocation remains intact) aren't enough to catch hard-to-find
|
||||
// memory corruption bugs. another tool is to trigger a debug exception
|
||||
// when the later to be corrupted variable is accessed; the problem should
|
||||
// then become apparent.
|
||||
// the VC++ IDE provides such 'breakpoints', but can only detect write access.
|
||||
// additionally, it can't resolve symbols in Release mode (where this would
|
||||
// be most useful), so we provide a breakpoint API.
|
||||
|
||||
// values chosen to match IA-32 bit defs, so compiler can optimize.
|
||||
// this isn't required, it'll work regardless.
|
||||
enum DbgBreakType
|
||||
{
|
||||
DBG_BREAK_CODE = 0, // execute
|
||||
DBG_BREAK_DATA_WRITE = 1, // write
|
||||
DBG_BREAK_DATA = 3 // read or write
|
||||
};
|
||||
|
||||
// arrange for a debug exception to be raised when <addr> is accessed
|
||||
// according to <type>.
|
||||
// for simplicity, the length (range of bytes to be checked) is derived
|
||||
// from addr's alignment, and is typically 1 machine word.
|
||||
// breakpoints are a limited resource (4 on IA-32); abort and
|
||||
// return ERR_LIMIT if none are available.
|
||||
extern int debug_set_break(void* addr, DbgBreakType type);
|
||||
|
||||
// remove all breakpoints that were set by debug_set_break.
|
||||
// important, since these are a limited resource.
|
||||
extern int debug_remove_all_breaks();
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// symbol access
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// TODO: rationale+comments
|
||||
|
||||
const size_t DBG_SYMBOL_LEN = 1000;
|
||||
const size_t DBG_FILE_LEN = 100;
|
||||
|
||||
extern void* debug_get_nth_caller(uint n);
|
||||
|
||||
extern int debug_resolve_symbol(void* ptr_of_interest, char* sym_name, char* file, int* line);
|
||||
|
||||
extern const wchar_t* debug_dump_stack(wchar_t* buf, size_t max_chars, uint skip, void* context);
|
||||
|
||||
#endif // #ifndef DEBUG_H_INCLUDED
|
@ -16,13 +16,13 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "lib/types.h"
|
||||
#include "lib.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/types.h"
|
||||
#include "lib.h"
|
||||
|
||||
#include "sysdep/sysdep.h"
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
// for easy removal in release builds, so that we don't cause any overhead.
|
||||
// note that any application calls to our functions must be removed also,
|
||||
// but this is preferable to stubbing them out here ("least surprise").
|
||||
#ifdef USE_MMGR
|
||||
#ifdef CONFIG_USE_MMGR
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -880,7 +880,7 @@ bool mmgr_are_all_valid()
|
||||
// do our check first, because it fails more cleanly
|
||||
// (=> better chance to see where it happened in the debugger)
|
||||
bool all_valid = validate_all();
|
||||
debug_check_heap();
|
||||
debug_heap_check();
|
||||
unlock();
|
||||
return all_valid;
|
||||
}
|
||||
@ -1408,4 +1408,4 @@ void operator delete[](void* p, const char* file, int line, const char* func) th
|
||||
free_dbg(p, AT_DELETE_ARRAY, file,line,func, 1);
|
||||
}
|
||||
|
||||
#endif // #ifdef USE_MMGR
|
||||
#endif // #ifdef CONFIG_USE_MMGR
|
||||
|
@ -25,7 +25,7 @@
|
||||
//
|
||||
// note: checking here messes up include guard detection, but we need to
|
||||
// cover both the guarded part (constants+externs) and the macros.
|
||||
#ifdef USE_MMGR
|
||||
#ifdef CONFIG_USE_MMGR
|
||||
|
||||
#ifndef MMGR_H__
|
||||
#define MMGR_H__
|
||||
@ -154,7 +154,7 @@ extern void operator delete[](void* p, const char* file, int line, const char* f
|
||||
#define wcsdup(p) mmgr_wcsdup_dbg(p, __FILE__,__LINE__,__FUNCTION__)
|
||||
#define getcwd(p,size) mmgr_getcwd_dbg(p, size, __FILE__,__LINE__,__FUNCTION__)
|
||||
|
||||
#endif // #ifdef USE_MMGR
|
||||
#endif // #ifdef CONFIG_USE_MMGR
|
||||
|
||||
|
||||
// purpose and history
|
||||
|
@ -18,16 +18,17 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "lib.h"
|
||||
#include "sdl.h"
|
||||
#include "ogl.h"
|
||||
#include "detect.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "lib.h"
|
||||
#include "sdl.h"
|
||||
#include "ogl.h"
|
||||
#include "detect.h"
|
||||
#include "debug.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "opengl32.lib")
|
||||
#pragma comment(lib, "glu32.lib")
|
||||
|
@ -8,19 +8,18 @@
|
||||
//
|
||||
// this policy yields the best compile performance with or without PCH.
|
||||
|
||||
#include "config.h"
|
||||
#include "lib/types.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4996) // function is deprecated
|
||||
#pragma warning(disable:4786) // identifier truncated to 255 chars
|
||||
#endif
|
||||
|
||||
// make string_s (secure CRT string functions) available everywhere
|
||||
#include "lib/string_s.h"
|
||||
// make these available everywhere for convenience:
|
||||
#include "lib/config.h"
|
||||
#include "lib/types.h"
|
||||
#include "lib/string_s.h" // CRT secure string
|
||||
#include "lib/debug.h"
|
||||
#include "ps/Pyrogenesis.h" // MICROLOG and old error system
|
||||
|
||||
// make MICROLOG and the old error system available everywhere
|
||||
#include "Pyrogenesis.h"
|
||||
|
||||
//
|
||||
// memory headers
|
||||
@ -100,7 +99,7 @@
|
||||
#include "ps/CStr.h"
|
||||
|
||||
// Some other external libraries that are used in several places:
|
||||
#include "jsapi.h"
|
||||
#include "scripting/SpiderMonkey.h"
|
||||
#include "boost/shared_ptr.hpp"
|
||||
#include "boost/weak_ptr.hpp"
|
||||
|
||||
@ -118,8 +117,11 @@
|
||||
// manually #including from every file, but requires that all system
|
||||
// headers containing "new", "malloc" etc. come before this (see above).
|
||||
|
||||
// use custom memory tracker (lib/mmgr.cpp)
|
||||
#if defined(CONFIG_USE_MMGR)
|
||||
# include "mmgr.h"
|
||||
// use VC debug heap (superceded by mmgr; it remains for completeness)
|
||||
#ifdef HAVE_DEBUGALLOC
|
||||
#elif defined(HAVE_VC_DEBUG_ALLOC)
|
||||
// can't define _CRTDBG_MAP_ALLOC because crtdbg.h has a broken 'new',
|
||||
// so manually redefine the appropriate functions.
|
||||
# define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
@ -127,9 +129,4 @@
|
||||
# define calloc(c, s) _calloc_dbg(c, s, _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
# define realloc(p, s) _realloc_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
# define free(p) _free_dbg(p, _NORMAL_BLOCK)
|
||||
#endif // #ifdef HAVE_DEBUGALLOC
|
||||
|
||||
// use custom memory tracker (lib/mmgr.cpp)
|
||||
#ifdef USE_MMGR
|
||||
# include "mmgr.h"
|
||||
#endif
|
||||
|
@ -179,7 +179,7 @@ static HDATA* h_data_from_idx(const i32 idx)
|
||||
{
|
||||
// makes things *crawl*!
|
||||
#ifdef PARANOIA
|
||||
debug_check_heap();
|
||||
debug_heap_check();
|
||||
#endif
|
||||
|
||||
// don't compare against last_in_use - this is called before allocating
|
||||
|
@ -18,11 +18,11 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lib.h"
|
||||
#include "posix.h" // SIZE_MAX
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef PERFORM_SELF_TEST
|
||||
#define PERFORM_SELF_TEST 0
|
||||
#endif
|
||||
|
@ -3,13 +3,10 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysdep/debug.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "win/win.h"
|
||||
#include "win/wdbg.h"
|
||||
#if defined(OS_WIN)
|
||||
# include "win/win.h"
|
||||
#elif defined(OS_UNIX)
|
||||
#include "unix/unix.h"
|
||||
# include "unix/unix.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -26,8 +23,6 @@ extern int vsnprintf2(char* buffer, size_t count, const char* format, va_list ar
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
enum DisplayErrorFlags
|
||||
{
|
||||
DE_ALLOW_SUPPRESS = 1,
|
||||
@ -58,14 +53,16 @@ enum ErrorReaction
|
||||
ER_EXIT
|
||||
};
|
||||
|
||||
|
||||
extern ErrorReaction display_error_impl(const wchar_t* text, int flags);
|
||||
|
||||
#define DISPLAY_ERROR(text) display_error(text, 0, 0, 0, __FILE__, __LINE__)
|
||||
|
||||
extern ErrorReaction display_error(const wchar_t* text, int flags,
|
||||
uint skip, void* context, const char* file, int line);
|
||||
|
||||
// convenience version, in case the advanced parameters aren't needed.
|
||||
// done this way instead of with default values so that it also works in C.
|
||||
#define DISPLAY_ERROR(text) display_error(text, 0, 0, 0, __FILE__, __LINE__)
|
||||
|
||||
|
||||
extern void display_msg(const char* caption, const char* msg);
|
||||
extern void wdisplay_msg(const wchar_t* caption, const wchar_t* msg);
|
||||
|
||||
|
@ -338,23 +338,6 @@ int debug_resolve_symbol(void* ptr_of_interest, char* sym_name, char* file, int*
|
||||
}
|
||||
#include "mmgr.h"
|
||||
|
||||
int debug_write_crashlog(const char* file, wchar_t* header, void* context)
|
||||
{
|
||||
// TODO: Do this properly. (I don't know what I'm doing; I just
|
||||
// know that this function is required in order to compile...)
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
void debug_check_heap()
|
||||
{
|
||||
// TODO: Do this properly. (I don't know what I'm doing; I just
|
||||
// know that this function is required in order to compile...)
|
||||
}
|
||||
|
||||
|
||||
|
||||
void debug_printf(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
@ -364,8 +347,34 @@ void debug_printf(const char* fmt, ...)
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
// TODO: Do these properly. (I don't know what I'm doing; I just
|
||||
// know that these functions are required in order to compile...)
|
||||
|
||||
void debug_disable_leak_reporting()
|
||||
int debug_write_crashlog(const char* file, wchar_t* header, void* context)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void debug_heap_check()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// if <full_monty> is true or PARANOIA #defined, all possible checks are
|
||||
// performed as often as possible. this is really slow (we are talking x100),
|
||||
// but reports errors closer to where they occurred.
|
||||
void debug_heap_enable(bool full_monty)
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
full_monty = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// disable all automatic checks until the next debug_heap_enable.
|
||||
void debug_heap_disable()
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
#ifndef sysdep_unix_unix_h__
|
||||
#define sysdep_unix_unix_h__
|
||||
|
||||
#include "udbg.h"
|
||||
|
||||
#endif
|
||||
|
@ -138,7 +138,11 @@ void debug_wprintf(const wchar_t* fmt, ...)
|
||||
}
|
||||
|
||||
|
||||
void debug_check_heap()
|
||||
//-----------------------------------------------------------------------------
|
||||
// debug memory allocator
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void debug_heap_check()
|
||||
{
|
||||
__try
|
||||
{
|
||||
@ -149,16 +153,33 @@ void debug_check_heap()
|
||||
}
|
||||
}
|
||||
|
||||
void debug_disable_leak_reporting()
|
||||
|
||||
void debug_heap_enable(DebugHeapChecks what)
|
||||
{
|
||||
#ifdef HAVE_DEBUGALLOC
|
||||
#ifdef HAVE_VC_DEBUG_ALLOC
|
||||
uint flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
|
||||
_CrtSetDbgFlag(flags & ~_CRTDBG_LEAK_CHECK_DF);
|
||||
#endif
|
||||
switch(what)
|
||||
{
|
||||
case DEBUG_HEAP_NONE:
|
||||
flags = 0;
|
||||
break;
|
||||
case DEBUG_HEAP_NORMAL:
|
||||
flags |= _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF;
|
||||
break;
|
||||
case DEBUG_HEAP_ALL:
|
||||
flags |= _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_DELAY_FREE_MEM_DF |
|
||||
_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF;
|
||||
break;
|
||||
default:
|
||||
assert2("debug_heap_enable: invalid what");
|
||||
}
|
||||
_CrtSetDbgFlag(flags);
|
||||
#endif // HAVE_DEBUGALLOC
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// to avoid deadlock, be VERY CAREFUL to avoid anything that may block,
|
||||
|
@ -34,25 +34,10 @@
|
||||
#pragma comment(lib, "shell32.lib") // for pick_directory SH* calls
|
||||
#endif
|
||||
|
||||
void sle(int x)
|
||||
{
|
||||
SetLastError((DWORD)x);
|
||||
}
|
||||
|
||||
char win_sys_dir[MAX_PATH+1];
|
||||
char win_exe_dir[MAX_PATH+1];
|
||||
|
||||
#ifdef HAVE_DEBUGALLOC
|
||||
// Enable heap corruption checking after every allocation. Has the same
|
||||
// effect as PARANOIA in pre_main_init, but lets you switch it on anywhere
|
||||
// so that you can skip checking the whole of the initialisation code.
|
||||
// The debugger will break in the allocation just after the one that
|
||||
// corrupted the heap, so check its ID and then _CrtSetBreakAlloc(...)
|
||||
// on the previous one and try again.
|
||||
// Warning: This makes things rather slow.
|
||||
void memory_debug_extreme_turbo_plus()
|
||||
{
|
||||
_CrtSetDbgFlag( _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_DELAY_FREE_MEM_DF );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// we need to know the app's main window for the error dialog, so that
|
||||
@ -92,6 +77,7 @@ HWND win_get_app_main_window()
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// safe allocator that may be used independently of libc malloc
|
||||
@ -112,9 +98,7 @@ void win_free(void* p)
|
||||
}
|
||||
|
||||
|
||||
char win_sys_dir[MAX_PATH+1];
|
||||
char win_exe_dir[MAX_PATH+1];
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// these override the portable versions in sysdep.cpp
|
||||
@ -201,16 +185,12 @@ int pick_directory(char* path, size_t buf_size)
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// "program error" dialog (triggered by assert and exception)
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// support for resizing the dialog / its controls
|
||||
// (have to do this manually - grr)
|
||||
//
|
||||
|
||||
static POINTS dlg_client_origin;
|
||||
static POINTS dlg_prev_client_size;
|
||||
@ -411,11 +391,9 @@ ErrorReaction display_error_impl(const wchar_t* text, int flags)
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// clipboard
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int clipboard_set(const wchar_t* text)
|
||||
{
|
||||
@ -566,11 +544,9 @@ static void call_func_tbl(_PIFV* begin, _PIFV* end)
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// locking for win-specific code
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// several init functions are before called before _cinit.
|
||||
// POSIX static mutex init may not have been done by then,
|
||||
@ -623,11 +599,9 @@ static void cs_shutdown()
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// startup
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// entry -> pre_libc -> WinMainCRTStartup -> WinMain -> pre_main -> main
|
||||
// at_exit is called as the last of the atexit handlers
|
||||
@ -652,17 +626,13 @@ static
|
||||
#endif
|
||||
void win_pre_main_init()
|
||||
{
|
||||
#ifdef HAVE_DEBUGALLOC
|
||||
uint flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
|
||||
// Always enable leak detection in debug builds
|
||||
flags |= _CRTDBG_LEAK_CHECK_DF;
|
||||
// enable memory tracking and leak detection;
|
||||
// no effect if !defined(HAVE_VC_DEBUG_ALLOC).
|
||||
#ifdef PARANOIA
|
||||
// force malloc et al. to check the heap every call.
|
||||
// slower, but reports errors closer to where they occur.
|
||||
flags |= _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_DELAY_FREE_MEM_DF;
|
||||
#endif // PARANOIA
|
||||
_CrtSetDbgFlag(flags);
|
||||
#endif // HAVE_DEBUGALLOC
|
||||
debug_heap_enable(DEBUG_HEAP_ALL);
|
||||
#else
|
||||
debug_heap_enable(DEBUG_HEAP_NORMAL);
|
||||
#endif
|
||||
|
||||
call_func_tbl(pre_main_begin, pre_main_end);
|
||||
|
||||
|
@ -346,6 +346,8 @@ extern "C" {
|
||||
extern _CRTIMP intptr_t _get_osfhandle(int);
|
||||
extern _CRTIMP int _open_osfhandle(intptr_t, int);
|
||||
extern _CRTIMP int _open(const char* fn, int mode, ...);
|
||||
extern _CRTIMP int _read (int fd, void* buf, size_t nbytes);
|
||||
extern _CRTIMP int _write(int fd, void* buf, size_t nbytes);
|
||||
extern _CRTIMP int _close(int);
|
||||
|
||||
extern _CRTIMP char* _getcwd(char*, size_t);
|
||||
|
@ -125,6 +125,22 @@ debug_printf("close %d\n", fd);
|
||||
}
|
||||
|
||||
|
||||
// we don't want to #define read to _read, since that's a fairly common
|
||||
// identifier. therefore, translate from MS CRT names via thunk functions.
|
||||
// efficiency is less important, and the overhead could be optimized away.
|
||||
|
||||
int read(int fd, void* buf, size_t nbytes)
|
||||
{
|
||||
return _read(fd, buf, nbytes);
|
||||
}
|
||||
|
||||
int write(int fd, void* buf, size_t nbytes)
|
||||
{
|
||||
return _write(fd, buf, nbytes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ioctl(int fd, int op, int* data)
|
||||
{
|
||||
const HANDLE h = cast_to_HANDLE(_get_osfhandle(fd));
|
||||
|
@ -257,11 +257,9 @@ extern int open(const char* fn, int mode, ...);
|
||||
// MS implementation doesn't support this distinction.
|
||||
// hence, the file is reported executable if it exists.
|
||||
|
||||
#define read _read
|
||||
#define write _write
|
||||
_CRTIMP int read(int, void*, size_t);
|
||||
_CRTIMP int write(int, void*, size_t);
|
||||
_CRTIMP off_t lseek(int fd, off_t ofs, int whence);
|
||||
extern int read (int fd, void* buf, size_t nbytes); // thunk
|
||||
extern int write(int fd, void* buf, size_t nbytes); // thunk
|
||||
extern _CRTIMP off_t lseek(int fd, off_t ofs, int whence);
|
||||
|
||||
|
||||
// redefinition error here => io.h is getting included somewhere.
|
||||
@ -269,7 +267,7 @@ _CRTIMP off_t lseek(int fd, off_t ofs, int whence);
|
||||
// compiling against the DLL CRT. either rename the io.h def
|
||||
// (as with vc_stat), or don't include io.h.
|
||||
extern int close(int);
|
||||
_CRTIMP int access(const char*, int);
|
||||
extern _CRTIMP int access(const char*, int);
|
||||
|
||||
extern int chdir(const char*);
|
||||
#undef getcwd
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "sysdep/debug.h" // debug_printf
|
||||
#include "debug.h" // debug_printf
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
Loading…
Reference in New Issue
Block a user