- 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:
janwas 2005-06-22 03:23:22 +00:00
parent 064dd5699d
commit 8f9a3fc38f
19 changed files with 385 additions and 325 deletions

View File

@ -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

View File

@ -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
View 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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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()
{
}

View File

@ -1,6 +1,4 @@
#ifndef sysdep_unix_unix_h__
#define sysdep_unix_unix_h__
#include "udbg.h"
#endif

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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));

View File

@ -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

View File

@ -21,7 +21,7 @@
#include <string>
#include "sysdep/debug.h" // debug_printf
#include "debug.h" // debug_printf
#ifdef __cplusplus
extern "C" {