Actually remove trailing whitespace for non-header files as well.
[0ad.git] / source / lib / sysdep / os / win / wdbg.cpp
blob210f8511d8ab7fd51e79f3b2eea0775edc35623b
1 /* Copyright (c) 2010 Wildfire Games
3 * Permission is hereby granted, free of charge, to any person obtaining
4 * a copy of this software and associated documentation files (the
5 * "Software"), to deal in the Software without restriction, including
6 * without limitation the rights to use, copy, modify, merge, publish,
7 * distribute, sublicense, and/or sell copies of the Software, and to
8 * permit persons to whom the Software is furnished to do so, subject to
9 * the following conditions:
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 * Win32 debug support code.
27 #include "precompiled.h"
28 #include "lib/debug.h"
30 #include "lib/bits.h"
31 #include "lib/sysdep/os/win/win.h"
32 #include "lib/sysdep/os/win/wutil.h"
35 // return 1 if the pointer appears to be totally bogus, otherwise 0.
36 // this check is not authoritative (the pointer may be "valid" but incorrect)
37 // but can be used to filter out obviously wrong values in a portable manner.
38 int debug_IsPointerBogus(const void* p)
40 if(p < (void*)0x10000)
41 return true;
42 #if ARCH_AMD64
43 if(p == (const void*)(uintptr_t)0xCCCCCCCCCCCCCCCCull)
44 return true;
45 #elif ARCH_IA32
46 if(p == (const void*)(uintptr_t)0xCCCCCCCCul)
47 return true;
48 #endif
50 // notes:
51 // - we don't check alignment because nothing can be assumed about a
52 // string pointer and we mustn't reject any actually valid pointers.
53 // - nor do we bother checking the address against known stack/heap areas
54 // because that doesn't cover everything (e.g. DLLs, VirtualAlloc).
55 // - cannot use IsBadReadPtr because it accesses the mem
56 // (false alarm for reserved address space).
58 return false;
62 bool debug_IsCodePointer(void* p)
64 uintptr_t addr = (uintptr_t)p;
65 // totally invalid pointer
66 if(debug_IsPointerBogus(p))
67 return false;
68 // comes before load address
69 static const HMODULE base = GetModuleHandle(0);
70 if(addr < (uintptr_t)base)
71 return false;
73 return true;
77 bool debug_IsStackPointer(void* p)
79 uintptr_t addr = (uintptr_t)p;
80 // totally invalid pointer
81 if(debug_IsPointerBogus(p))
82 return false;
83 // not aligned
84 if(addr % sizeof(void*))
85 return false;
86 // out of bounds (note: IA-32 stack grows downwards)
87 NT_TIB* tib = (NT_TIB*)NtCurrentTeb();
88 if(!(tib->StackLimit < p && p < tib->StackBase))
89 return false;
91 return true;
95 void debug_puts(const char* text)
97 OutputDebugStringW(wstring_from_utf8(text).c_str());
101 void wdbg_printf(const wchar_t* fmt, ...)
103 wchar_t buf[1024+1]; // wvsprintfW will truncate to this size
104 va_list ap;
105 va_start(ap, fmt);
106 wvsprintfW(buf, fmt, ap); // (return value doesn't indicate whether truncation occurred)
107 va_end(ap);
109 OutputDebugStringW(buf);
113 // inform the debugger of the current thread's description, which it then
114 // displays instead of just the thread handle.
116 // see "Setting a Thread Name (Unmanaged)": http://msdn2.microsoft.com/en-us/library/xcb2z8hs(vs.71).aspx
117 void debug_SetThreadName(const char* name)
119 // we pass information to the debugger via a special exception it
120 // swallows. if not running under one, bail now to avoid
121 // "first chance exception" warnings.
122 if(!IsDebuggerPresent())
123 return;
125 // presented by Jay Bazuzi (from the VC debugger team) at TechEd 1999.
126 const struct ThreadNameInfo
128 DWORD type;
129 const char* name;
130 DWORD thread_id; // any valid ID or -1 for current thread
131 DWORD flags;
133 info = { 0x1000, name, (DWORD)-1, 0 };
134 __try
136 RaiseException(0x406D1388, 0, sizeof(info)/sizeof(DWORD), (ULONG_PTR*)&info);
138 __except(EXCEPTION_EXECUTE_HANDLER)
140 // if we get here, the debugger didn't handle the exception.
141 // this happens if profiling with Dependency Walker; ENSURE
142 // must not be called because we may be in critical init.