2005-05-12 00:44:20 +02:00
|
|
|
// 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/
|
|
|
|
|
2005-05-11 06:37:05 +02:00
|
|
|
#ifndef DEBUG_H_INCLUDED
|
|
|
|
#define DEBUG_H_INCLUDED
|
2005-01-23 19:07:34 +01:00
|
|
|
|
2005-01-25 19:27:00 +01:00
|
|
|
#ifdef _WIN32
|
|
|
|
# include "win/wdbg.h"
|
|
|
|
#else
|
|
|
|
# include "unix/udbg.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2005-05-12 04:58:40 +02:00
|
|
|
// check heap integrity (independently of mmgr).
|
|
|
|
// errors are reported by the CRT, e.g. via assert.
|
|
|
|
extern void debug_check_heap(void);
|
|
|
|
|
|
|
|
|
2005-06-16 23:52:35 +02:00
|
|
|
// user choices in the assert/unhandled exception dialog.
|
|
|
|
enum ErrorReaction
|
2005-05-12 00:44:20 +02:00
|
|
|
{
|
|
|
|
// ignore, continue as if nothing happened.
|
2005-06-16 23:52:35 +02:00
|
|
|
ER_CONTINUE = 1,
|
|
|
|
// note: don't start at 0 because that is interpreted as a
|
|
|
|
// DialogBoxParam failure.
|
2005-05-12 00:44:20 +02:00
|
|
|
|
2005-06-16 23:52:35 +02:00
|
|
|
// ignore and do not report again. only works with assert2.
|
|
|
|
ER_SUPPRESS,
|
2005-05-12 00:44:20 +02:00
|
|
|
// note: non-persistent; only applicable during this program run.
|
|
|
|
|
|
|
|
// trigger breakpoint, i.e. enter debugger.
|
2005-06-16 23:52:35 +02:00
|
|
|
ER_BREAK,
|
2005-05-12 00:44:20 +02:00
|
|
|
|
|
|
|
// exit the program immediately.
|
2005-06-16 23:52:35 +02:00
|
|
|
ER_EXIT,
|
|
|
|
// note: never returned; carried out immediately to disburden callers.
|
2005-05-12 00:44:20 +02:00
|
|
|
};
|
|
|
|
|
2005-06-16 23:52:35 +02:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// assert
|
|
|
|
//
|
|
|
|
|
2005-05-12 00:44:20 +02:00
|
|
|
// notify the user that an assertion failed; displays a
|
|
|
|
// stack trace with local variables.
|
2005-06-16 23:52:35 +02:00
|
|
|
// returns one of UserErrorReaction.
|
|
|
|
extern ErrorReaction debug_assert_failed(const char* source_file, int line, const char* assert_expr);
|
2005-05-11 06:37:05 +02:00
|
|
|
|
|
|
|
// recommended use: assert2(expr && "descriptive string")
|
|
|
|
#define assert2(expr)\
|
|
|
|
STMT(\
|
2005-06-16 23:52:35 +02:00
|
|
|
static unsigned char suppress__ = 0x55;\
|
|
|
|
if(suppress__ == 0x55 && !(expr))\
|
2005-05-11 06:37:05 +02:00
|
|
|
switch(debug_assert_failed(__FILE__, __LINE__, #expr))\
|
|
|
|
{\
|
2005-06-16 23:52:35 +02:00
|
|
|
case ER_SUPPRESS:\
|
|
|
|
suppress__ = 0xaa;\
|
2005-05-11 06:37:05 +02:00
|
|
|
break;\
|
2005-06-16 23:52:35 +02:00
|
|
|
case ER_BREAK:\
|
2005-05-11 06:37:05 +02:00
|
|
|
debug_break();\
|
|
|
|
break;\
|
|
|
|
}\
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2005-05-12 04:58:40 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
2005-05-11 06:37:05 +02:00
|
|
|
//
|
|
|
|
// output
|
2004-08-02 15:47:38 +02:00
|
|
|
//
|
|
|
|
|
2005-05-12 00:44:20 +02:00
|
|
|
// write to the debugger output window (may take ~1 ms!)
|
|
|
|
extern void debug_printf(const char* fmt, ...);
|
2004-08-02 15:47:38 +02:00
|
|
|
|
2005-05-12 00:44:20 +02:00
|
|
|
// write to memory buffer (fast)
|
2005-05-12 04:58:40 +02:00
|
|
|
// used for "last activity" reporting in the crashlog.
|
2005-05-12 00:44:20 +02:00
|
|
|
extern void debug_wprintf_mem(const wchar_t* fmt, ...);
|
2005-01-23 19:07:34 +01:00
|
|
|
|
2005-05-12 00:44:20 +02:00
|
|
|
// warn of unexpected state. less error-prone than assert(!"text");
|
2005-05-11 06:37:05 +02:00
|
|
|
#define debug_warn(str) assert2(0 && (str))
|
2005-01-23 19:07:34 +01:00
|
|
|
|
2005-05-12 04:58:40 +02:00
|
|
|
// TODO
|
2005-05-23 00:32:58 +02:00
|
|
|
extern int debug_write_crashlog(const wchar_t* description, const wchar_t* locus, const wchar_t* stack_trace);
|
2005-01-23 19:07:34 +01:00
|
|
|
|
2005-05-12 04:58:40 +02:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
2005-05-11 06:37:05 +02:00
|
|
|
//
|
|
|
|
// breakpoints
|
|
|
|
//
|
2005-01-23 19:07:34 +01:00
|
|
|
|
2005-05-12 00:44:20 +02:00
|
|
|
// 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.
|
2005-05-11 06:37:05 +02:00
|
|
|
//#define debug_break()
|
2005-01-23 19:07:34 +01:00
|
|
|
|
2005-01-25 19:27:00 +01:00
|
|
|
|
2005-05-11 06:37:05 +02:00
|
|
|
// 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.
|
2005-05-12 00:44:20 +02:00
|
|
|
// the VC++ IDE provides such 'breakpoints', but can only detect write access.
|
|
|
|
// additionally, it can't resolve symbols in Release mode (where this would
|
2005-05-12 04:58:40 +02:00
|
|
|
// be most useful), so we provide a breakpoint API.
|
2004-08-02 15:47:38 +02:00
|
|
|
|
2005-05-11 06:37:05 +02:00
|
|
|
// values chosen to match IA-32 bit defs, so compiler can optimize.
|
|
|
|
// this isn't required, it'll work regardless.
|
|
|
|
enum DbgBreakType
|
|
|
|
{
|
2005-05-12 00:44:20 +02:00
|
|
|
DBG_BREAK_CODE = 0, // execute
|
|
|
|
DBG_BREAK_DATA_WRITE = 1, // write
|
|
|
|
DBG_BREAK_DATA = 3 // read or write
|
2005-05-11 06:37:05 +02:00
|
|
|
};
|
2004-08-02 15:47:38 +02:00
|
|
|
|
2005-05-12 00:44:20 +02:00
|
|
|
// 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.
|
2005-05-12 04:58:40 +02:00
|
|
|
// breakpoints are a limited resource (4 on IA-32); abort and
|
|
|
|
// return ERR_LIMIT if none are available.
|
2005-05-11 06:37:05 +02:00
|
|
|
extern int debug_set_break(void* addr, DbgBreakType type);
|
2004-08-02 15:47:38 +02:00
|
|
|
|
2005-05-12 04:58:40 +02:00
|
|
|
// remove all breakpoints that were set by debug_set_break.
|
|
|
|
// important, since these are a limited resource.
|
|
|
|
extern int debug_remove_all_breaks();
|
2005-01-25 19:27:00 +01:00
|
|
|
|
|
|
|
|
2005-05-12 04:58:40 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
2005-05-11 06:37:05 +02:00
|
|
|
//
|
|
|
|
// symbol access
|
|
|
|
//
|
2005-02-02 04:35:25 +01:00
|
|
|
|
2005-05-12 04:58:40 +02:00
|
|
|
// TODO: rationale+comments
|
|
|
|
|
2005-05-11 06:37:05 +02:00
|
|
|
const size_t DBG_SYMBOL_LEN = 1000;
|
|
|
|
const size_t DBG_FILE_LEN = 100;
|
2005-02-02 04:35:25 +01:00
|
|
|
|
2005-05-11 06:37:05 +02:00
|
|
|
extern void* debug_get_nth_caller(uint n);
|
2005-02-02 04:35:25 +01:00
|
|
|
|
2005-05-11 06:37:05 +02:00
|
|
|
extern int debug_resolve_symbol(void* ptr_of_interest, char* sym_name, char* file, int* line);
|
2005-02-02 04:35:25 +01:00
|
|
|
|
|
|
|
|
2005-05-11 06:37:05 +02:00
|
|
|
#endif // #ifndef DEBUG_H_INCLUDED
|