From: Vadim Zeitlin Date: Tue, 21 Mar 2006 15:19:53 +0000 (+0000) Subject: show the function in which the assert failure occured if the compiler supports it X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/dfa0b52f4ac947d5e7566dabb81c39bbf881fac5 show the function in which the assert failure occured if the compiler supports it git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38251 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/changes.txt b/docs/changes.txt index 0c8b01160d..4f9a0716b9 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -47,6 +47,8 @@ All: - Overloaded Connect() and SetLocal() methods for binding to local address/port. - All GetCount() methods now return size_t and not int - Albanian translation added (Besnik Bleta) +- Assert messages now show the function in which assert failed +- wxApp::OnAssertFailure() should now be used instead the old wxApp::OnAssert() All (GUI): diff --git a/include/wx/debug.h b/include/wx/debug.h index e1d1f8a821..e783d5efac 100644 --- a/include/wx/debug.h +++ b/include/wx/debug.h @@ -47,6 +47,13 @@ #endif /* !WXDEBUG */ #endif /* __WXDEBUG__ */ +/* TODO: add more compilers supporting __FUNCTION__ */ +#if defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1300) + #define __TFUNC__ wxAPPLY_T(__FUNCTION__) +#else /* old compilers without __FUNCTION__ support */ + #define __TFUNC__ _T("") +#endif + /* ---------------------------------------------------------------------------- */ /* Debugging macros */ /* */ @@ -78,11 +85,13 @@ Parameters: szFile and nLine - file name and line number of the ASSERT + szFunc - function name of the ASSERT, may be empty szCond - text form of the condition which failed szMsg - optional message explaining the reason */ extern void WXDLLIMPEXP_BASE wxOnAssert(const wxChar *szFile, int nLine, + const wxChar *szFunc, const wxChar *szCond, const wxChar *szMsg = NULL); @@ -94,14 +103,18 @@ #define wxASSERT(cond) wxASSERT_MSG(cond, NULL) /* assert with additional message explaining it's cause */ - #define wxASSERT_MSG(cond, msg) \ - if (cond) ; else wxOnAssert(__TFILE__, __LINE__, _T(#cond), msg) + #define wxASSERT_MSG(cond, msg) \ + if ( cond ) \ + ; \ + else \ + wxOnAssert(__TFILE__, __LINE__, __TFUNC__, _T(#cond), msg) /* special form of assert: always triggers it (in debug mode) */ #define wxFAIL wxFAIL_MSG(NULL) /* FAIL with some message */ - #define wxFAIL_MSG(msg) wxOnAssert(__TFILE__, __LINE__, wxT("wxAssertFailure"), msg) + #define wxFAIL_MSG(msg) \ + wxOnAssert(__TFILE__, __LINE__, __TFUNC__, _T("wxAssertFailure"), msg) /* an assert helper used to avoid warning when testing constant expressions, */ /* i.e. wxASSERT( sizeof(int) == 4 ) can generate a compiler warning about */ @@ -117,7 +130,7 @@ /* nothing to do in release modes (hopefully at this moment there are */ /* no more bugs ;-) */ #define wxASSERT(cond) - #define wxASSERT_MSG(x, m) + #define wxASSERT_MSG(cond, msg) #define wxFAIL #define wxFAIL_MSG(msg) #endif /* __WXDEBUG__ */ @@ -140,16 +153,24 @@ */ /* check that expression is true, "return" if not (also FAILs in debug mode) */ -#define wxCHECK(x, rc) wxCHECK_MSG(x, rc, NULL) +#define wxCHECK(cond, rc) wxCHECK_MSG(cond, rc, NULL) /* as wxCHECK but with a message explaining why we fail */ -#define wxCHECK_MSG(x, rc, msg) wxCHECK2_MSG(x, return rc, msg) +#define wxCHECK_MSG(cond, rc, msg) wxCHECK2_MSG(cond, return rc, msg) /* check that expression is true, perform op if not */ -#define wxCHECK2(x, op) wxCHECK2_MSG(x, op, NULL) +#define wxCHECK2(cond, op) wxCHECK2_MSG(cond, op, NULL) /* as wxCHECK2 but with a message explaining why we fail */ -#define wxCHECK2_MSG(x, op, msg) if (x) ; else do { wxFAIL_MSG(msg); op; } while (0) +#define wxCHECK2_MSG(cond, op, msg) \ + if ( cond ) \ + ; \ + else \ + do \ + { \ + wxOnAssert(__TFILE__, __LINE__, __TFUNC__, _T(#cond), msg); \ + op; \ + } while ( 0 ) /* special form of wxCHECK2: as wxCHECK, but for use in void functions */ /* */ @@ -157,7 +178,7 @@ /* there is no other way to tell the caller what exactly went wrong */ /* from the void function (of course, the function shouldn't be void */ /* to begin with...) */ -#define wxCHECK_RET(x, msg) wxCHECK2_MSG(x, return, msg) +#define wxCHECK_RET(cond, msg) wxCHECK2_MSG(cond, return, msg) /* ---------------------------------------------------------------------------- */ /* Compile time asserts */ diff --git a/src/common/appbase.cpp b/src/common/appbase.cpp index 1c4d53b480..141502e820 100644 --- a/src/common/appbase.cpp +++ b/src/common/appbase.cpp @@ -93,6 +93,7 @@ static void ShowAssertDialog(const wxChar *szFile, int nLine, + const wxChar *szFunc, const wxChar *szCond, const wxChar *szMsg, wxAppTraits *traits = NULL); @@ -434,12 +435,21 @@ bool wxAppConsole::CheckBuildOptions(const char *optionsSignature, #ifdef __WXDEBUG__ +void wxAppConsole::OnAssertFailure(const wxChar *file, + int line, + const wxChar *func, + const wxChar *cond, + const wxChar *msg) +{ + ShowAssertDialog(file, line, func, cond, msg, GetTraits()); +} + void wxAppConsole::OnAssert(const wxChar *file, int line, const wxChar *cond, const wxChar *msg) { - ShowAssertDialog(file, line, cond, msg, GetTraits()); + OnAssertFailure(file, line, _T(""), cond, msg); } #endif // __WXDEBUG__ @@ -590,6 +600,7 @@ void wxTrap() // this function is called when an assert fails void wxOnAssert(const wxChar *szFile, int nLine, + const wxChar *szFunc, const wxChar *szCond, const wxChar *szMsg) { @@ -612,12 +623,12 @@ void wxOnAssert(const wxChar *szFile, { // by default, show the assert dialog box -- we can't customize this // behaviour - ShowAssertDialog(szFile, nLine, szCond, szMsg); + ShowAssertDialog(szFile, nLine, szFunc, szCond, szMsg); } else { // let the app process it as it wants - wxTheApp->OnAssert(szFile, nLine, szCond, szMsg); + wxTheApp->OnAssertFailure(szFile, nLine, szFunc, szCond, szMsg); } s_bInAssert = false; @@ -747,6 +758,7 @@ static wxString GetAssertStackTrace() static void ShowAssertDialog(const wxChar *szFile, int nLine, + const wxChar *szFunc, const wxChar *szCond, const wxChar *szMsg, wxAppTraits *traits) @@ -762,6 +774,11 @@ void ShowAssertDialog(const wxChar *szFile, // the failed assert msg.Printf(wxT("%s(%d): assert \"%s\" failed"), szFile, nLine, szCond); + // add the function name, if any + if ( szFunc && *szFunc ) + msg << _T(" in ") << szFunc << _T("()"); + + // and the message itself if ( szMsg ) { msg << _T(": ") << szMsg;