Cleaned up the debugging infrastructure on Windows (we stopped using the strsafe functions so there's no useful failure case anymore) and implemented the new one.

This commit is contained in:
Pietro Gagliardi 2016-05-13 22:05:02 -04:00
parent 15b370bc36
commit 6d2d977363
5 changed files with 36 additions and 106 deletions

View File

@ -76,7 +76,7 @@ void *uiRealloc(void *p, size_t new, const char *type)
void uiFree(void *p) void uiFree(void *p)
{ {
if (p == NULL) if (p == NULL)
implbug("attempt to uiFree(NULL); there's a bug somewhere"); implbug("attempt to uiFree(NULL)");
p = BASE(p); p = BASE(p);
g_free(p); g_free(p);
if (g_ptr_array_remove(allocations, p) == FALSE) if (g_ptr_array_remove(allocations, p) == FALSE)

View File

@ -60,7 +60,7 @@ void uiFree(void *_p)
uint8_t *p = (uint8_t *) _p; uint8_t *p = (uint8_t *) _p;
if (p == NULL) if (p == NULL)
complain("attempt to uiFree(NULL); there's a bug somewhere"); implbug("attempt to uiFree(NULL)");
types.erase(heap[p]); types.erase(heap[p]);
delete heap[p]; delete heap[p];
heap.erase(p); heap.erase(p);

View File

@ -1,14 +1,6 @@
// 25 february 2015 // 25 february 2015
#include "uipriv_windows.hpp" #include "uipriv_windows.hpp"
// TODO
void complain(const char *format, ...)
{
OutputDebugStringA(format);
DebugBreak();
abort();
}
// TODO disable logging and stopping on no-debug builds // TODO disable logging and stopping on no-debug builds
// TODO are the newlines needed? // TODO are the newlines needed?
@ -17,8 +9,6 @@ static void printDebug(const WCHAR *msg)
OutputDebugStringW(msg); OutputDebugStringW(msg);
} }
#define debugfmt L"%s:%s:%s()"
HRESULT _logLastError(debugargs, const WCHAR *s) HRESULT _logLastError(debugargs, const WCHAR *s)
{ {
DWORD le; DWORD le;
@ -31,21 +21,13 @@ HRESULT _logLastError(debugargs, const WCHAR *s)
useFormatted = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, le, 0, (LPWSTR) (&formatted), 0, NULL) != 0; useFormatted = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, le, 0, (LPWSTR) (&formatted), 0, NULL) != 0;
if (!useFormatted) if (!useFormatted)
formatted = L"\n"; formatted = L"\n";
msg = debugstrf(L"[libui] " debugfmt L" %s: GetLastError() == %I32u %s", msg = strf(L"[libui] %s:%s:%s() %s: GetLastError() == %I32u %s",
file, line, func, file, line, func,
s, le, formatted); s, le, formatted);
if (useFormatted) if (useFormatted)
LocalFree(formatted); // ignore error LocalFree(formatted); // ignore error
if (msg == NULL) {
printDebug(L"[libui] (debugstrf() failed; printing raw) ");
printDebug(file);
printDebug(func);
printDebug(s);
printDebug(L"\n");
} else {
printDebug(msg); printDebug(msg);
uiFree(msg); uiFree(msg);
}
DebugBreak(); DebugBreak();
SetLastError(le); SetLastError(le);
@ -67,65 +49,38 @@ HRESULT _logHRESULT(debugargs, const WCHAR *s, HRESULT hr)
useFormatted = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr, 0, (LPWSTR) (&formatted), 0, NULL) != 0; useFormatted = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr, 0, (LPWSTR) (&formatted), 0, NULL) != 0;
if (!useFormatted) if (!useFormatted)
formatted = L"\n"; formatted = L"\n";
msg = debugstrf(L"[libui] " debugfmt L" %s: HRESULT == 0x%08I32X %s", msg = strf(L"[libui] %s:%s:%s() %s: HRESULT == 0x%08I32X %s",
file, line, func, file, line, func,
s, hr, formatted); s, hr, formatted);
if (useFormatted) if (useFormatted)
LocalFree(formatted); // ignore error LocalFree(formatted); // ignore error
if (msg == NULL) {
printDebug(L"[libui] (debugstrf() failed; printing raw) ");
printDebug(file);
printDebug(func);
printDebug(s);
printDebug(L"\n");
} else {
printDebug(msg); printDebug(msg);
uiFree(msg); uiFree(msg);
}
DebugBreak(); DebugBreak();
return hr; return hr;
} }
#define implbugmsg L"either you have or libui has a bug in a control implementation; if libui does, contact andlabs" void realbug(const char *file, const char *line, const char *func, const char *prefix, const char *format, va_list ap)
void _implbug(debugargs, const WCHAR *format, ...)
{ {
va_list ap; va_list ap2;
WCHAR *formatted; char *msg;
WCHAR *full; size_t n;
const WCHAR *onerr; WCHAR *final;
va_start(ap, format); va_copy(ap2, ap);
formatted = debugvstrf(format, ap); n = _vscprintf(format, ap2);
va_end(ap); va_end(ap2);
if (formatted == NULL) { n++; // terminating L'\0'
onerr = format;
goto bad;
}
full = debugstrf(L"[libui] " debugfmt L" " implbugmsg L" — %s\n", buf = (char *) uiAlloc(n * sizeof (char), "char[]");
file, line, func, // includes terminating L'\0' according to example in https://msdn.microsoft.com/en-us/library/xa1a1a6z.aspx
formatted); vsprintf_s(msg, n, format, ap);
if (full == NULL) {
onerr = formatted;
goto bad;
}
printDebug(full); final = strf(L"[libui] %hs:%hs:%hs() %hs%hs\n", file, line, func, prefix, msg);
uiFree(full); uiFree(msg);
uiFree(formatted); printDebug(final);
goto after; uiFree(final);
bad:
printDebug(L"[libui] (debugstrf() failed; printing raw) ");
printDebug(implbugmsg);
printDebug(file);
printDebug(func);
printDebug(onerr);
printDebug(L"\n");
after:
DebugBreak(); DebugBreak();
abort();
} }

View File

@ -35,8 +35,6 @@ extern char *toUTF8(const WCHAR *wstr);
extern WCHAR *utf16dup(const WCHAR *orig); extern WCHAR *utf16dup(const WCHAR *orig);
extern WCHAR *strf(const WCHAR *format, ...); extern WCHAR *strf(const WCHAR *format, ...);
extern WCHAR *vstrf(const WCHAR *format, va_list ap); extern WCHAR *vstrf(const WCHAR *format, va_list ap);
extern WCHAR *debugstrf(const WCHAR *format, ...);
extern WCHAR *debugvstrf(const WCHAR *format, va_list ap);
extern char *LFtoCRLF(const char *lfonly); extern char *LFtoCRLF(const char *lfonly);
extern void CRLFtoLF(const char *s); extern void CRLFtoLF(const char *s);

View File

@ -60,13 +60,22 @@ WCHAR *utf16dup(const WCHAR *orig)
return out; return out;
} }
// if recursing is TRUE, do NOT recursively call wstrf() in logHRESULT() WCHAR *strf(const WCHAR *format, ...)
static WCHAR *strfcore(BOOL recursing, const WCHAR *format, va_list ap) {
va_list ap;
WCHAR *str;
va_start(ap, format);
str = vstrf(format, ap);
va_end(ap);
return str;
}
WCHAR *vstrf(const WCHAR *format, va_list ap)
{ {
va_list ap2; va_list ap2;
WCHAR *buf; WCHAR *buf;
size_t n; size_t n;
HRESULT hr;
if (*format == L'\0') if (*format == L'\0')
return emptyUTF16(); return emptyUTF16();
@ -83,38 +92,6 @@ static WCHAR *strfcore(BOOL recursing, const WCHAR *format, va_list ap)
return buf; return buf;
} }
WCHAR *strf(const WCHAR *format, ...)
{
va_list ap;
WCHAR *str;
va_start(ap, format);
str = vstrf(format, ap);
va_end(ap);
return str;
}
WCHAR *vstrf(const WCHAR *format, va_list ap)
{
return strfcore(FALSE, format, ap);
}
WCHAR *debugstrf(const WCHAR *format, ...)
{
va_list ap;
WCHAR *str;
va_start(ap, format);
str = debugvstrf(format, ap);
va_end(ap);
return str;
}
WCHAR *debugvstrf(const WCHAR *format, va_list ap)
{
return strfcore(TRUE, format, ap);
}
// Let's shove these utility routines here too. // Let's shove these utility routines here too.
// Prerequisite: lfonly is UTF-8. // Prerequisite: lfonly is UTF-8.
char *LFtoCRLF(const char *lfonly) char *LFtoCRLF(const char *lfonly)