起動時にデバグ用コンソールをオープンできるようにした
- デバグ用 ttdebug.h,cpp を追加
- 例外発生時の処理を ttdebug.cpp に移動
@@ -60,6 +60,8 @@ | ||
60 | 60 | teraterml.h |
61 | 61 | ttdde.c |
62 | 62 | ttdde.h |
63 | + ttdebug.cpp | |
64 | + ttdebug.h | |
63 | 65 | ttdialog.c |
64 | 66 | ttdialog.h |
65 | 67 | ttfileio.c |
@@ -259,6 +261,7 @@ | ||
259 | 261 | |
260 | 262 | target_link_libraries( |
261 | 263 | teraterm |
264 | + PRIVATE | |
262 | 265 | common_static |
263 | 266 | ttpcmn |
264 | 267 | #ttpfile |
@@ -34,7 +34,7 @@ | ||
34 | 34 | #include "tt_res.h" |
35 | 35 | #include "debug_pp.h" |
36 | 36 | #include "../common/tt_res.h" |
37 | -#include "unicode_test.h" | |
37 | +#include "ttdebug.h" | |
38 | 38 | #include "dlglib.h" |
39 | 39 | #include "compat_win.h" |
40 | 40 | #include "setting.h" |
@@ -93,14 +93,8 @@ | ||
93 | 93 | const char *caption; |
94 | 94 | HWND hWnd = pGetConsoleWindow(); |
95 | 95 | if (hWnd == NULL) { |
96 | - FILE *fp; | |
97 | - AllocConsole(); | |
98 | - freopen_s(&fp, "CONOUT$", "w", stdout); | |
99 | - freopen_s(&fp, "CONOUT$", "w", stderr); | |
96 | + DebugConsoleOpen(); | |
100 | 97 | caption = "Hide console window"; |
101 | - hWnd = pGetConsoleWindow(); | |
102 | - HMENU hmenu = GetSystemMenu(hWnd, FALSE); | |
103 | - RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND); | |
104 | 98 | } |
105 | 99 | else { |
106 | 100 | if (::IsWindowVisible(hWnd)) { |
@@ -57,6 +57,7 @@ | ||
57 | 57 | #include "teraterml.h" |
58 | 58 | #include "sendmem.h" |
59 | 59 | #include "layer_for_unicode.h" |
60 | +#include "ttdebug.h" | |
60 | 61 | |
61 | 62 | #if defined(_DEBUG) && defined(_MSC_VER) |
62 | 63 | #define new ::new(_NORMAL_BLOCK, __FILE__, __LINE__) |
@@ -110,7 +111,11 @@ | ||
110 | 111 | { |
111 | 112 | DLLInit(); |
112 | 113 | WinCompatInit(); |
114 | + DebugSetException(); | |
113 | 115 | LoadSpecialFont(); |
116 | +#if defined(DEBUG_OPEN_CONSOLE_AT_STARTUP) | |
117 | + DebugConsoleOpen(); | |
118 | +#endif | |
114 | 119 | } |
115 | 120 | |
116 | 121 | // Tera Term main engine |
@@ -0,0 +1,271 @@ | ||
1 | +/* | |
2 | + * (C) 2020- TeraTerm Project | |
3 | + * All rights reserved. | |
4 | + * | |
5 | + * Redistribution and use in source and binary forms, with or without | |
6 | + * modification, are permitted provided that the following conditions | |
7 | + * are met: | |
8 | + * | |
9 | + * 1. Redistributions of source code must retain the above copyright | |
10 | + * notice, this list of conditions and the following disclaimer. | |
11 | + * 2. Redistributions in binary form must reproduce the above copyright | |
12 | + * notice, this list of conditions and the following disclaimer in the | |
13 | + * documentation and/or other materials provided with the distribution. | |
14 | + * 3. The name of the author may not be used to endorse or promote products | |
15 | + * derived from this software without specific prior written permission. | |
16 | + * | |
17 | + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR | |
18 | + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
19 | + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
20 | + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
21 | + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
22 | + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 | + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 | + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
26 | + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | + */ | |
28 | + | |
29 | +#include <windows.h> | |
30 | +#include <stdio.h> | |
31 | +#include <imagehlp.h> | |
32 | + | |
33 | +#include "compat_win.h" | |
34 | + | |
35 | +#include "ttdebug.h" | |
36 | + | |
37 | +/** | |
38 | + * コンソールウィンドウを表示するデバグ用 | |
39 | + * デバグ用に埋め込んだprintf()系を表示することができるようになる | |
40 | + * | |
41 | + * @retval コンソールのWindow Handle | |
42 | + */ | |
43 | +HWND DebugConsoleOpen(void) | |
44 | +{ | |
45 | + FILE *fp; | |
46 | + HWND hWnd = pGetConsoleWindow(); | |
47 | + if (hWnd != NULL) { | |
48 | + return hWnd; | |
49 | + } | |
50 | + AllocConsole(); | |
51 | + freopen_s(&fp, "CONOUT$", "w", stdout); | |
52 | + freopen_s(&fp, "CONOUT$", "w", stderr); | |
53 | + | |
54 | + // 閉じるボタンを無効化 | |
55 | + hWnd = pGetConsoleWindow(); | |
56 | + HMENU hmenu = GetSystemMenu(hWnd, FALSE); | |
57 | + RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND); | |
58 | + | |
59 | + return hWnd; | |
60 | +} | |
61 | + | |
62 | +// | |
63 | +// 例外ハンドラのフック(スタックトレースのダンプ) | |
64 | +// | |
65 | +// cf. http://svn.collab.net/repos/svn/trunk/subversion/libsvn_subr/win32_crashrpt.c | |
66 | +// (2007.9.30 yutaka) | |
67 | +// | |
68 | +// 例外コードを文字列へ変換する | |
69 | +#if !defined(_M_X64) | |
70 | +static const char *GetExceptionString(DWORD exception) | |
71 | +{ | |
72 | +#define EXCEPTION(x) case EXCEPTION_##x: return (#x); | |
73 | + static char buf[16]; | |
74 | + | |
75 | + switch (exception) | |
76 | + { | |
77 | + EXCEPTION(ACCESS_VIOLATION) | |
78 | + EXCEPTION(DATATYPE_MISALIGNMENT) | |
79 | + EXCEPTION(BREAKPOINT) | |
80 | + EXCEPTION(SINGLE_STEP) | |
81 | + EXCEPTION(ARRAY_BOUNDS_EXCEEDED) | |
82 | + EXCEPTION(FLT_DENORMAL_OPERAND) | |
83 | + EXCEPTION(FLT_DIVIDE_BY_ZERO) | |
84 | + EXCEPTION(FLT_INEXACT_RESULT) | |
85 | + EXCEPTION(FLT_INVALID_OPERATION) | |
86 | + EXCEPTION(FLT_OVERFLOW) | |
87 | + EXCEPTION(FLT_STACK_CHECK) | |
88 | + EXCEPTION(FLT_UNDERFLOW) | |
89 | + EXCEPTION(INT_DIVIDE_BY_ZERO) | |
90 | + EXCEPTION(INT_OVERFLOW) | |
91 | + EXCEPTION(PRIV_INSTRUCTION) | |
92 | + EXCEPTION(IN_PAGE_ERROR) | |
93 | + EXCEPTION(ILLEGAL_INSTRUCTION) | |
94 | + EXCEPTION(NONCONTINUABLE_EXCEPTION) | |
95 | + EXCEPTION(STACK_OVERFLOW) | |
96 | + EXCEPTION(INVALID_DISPOSITION) | |
97 | + EXCEPTION(GUARD_PAGE) | |
98 | + EXCEPTION(INVALID_HANDLE) | |
99 | + | |
100 | + default: | |
101 | + _snprintf_s(buf, sizeof(buf), _TRUNCATE, "0x%x", exception); | |
102 | + return buf; | |
103 | + //return "UNKNOWN_ERROR"; | |
104 | + } | |
105 | +#undef EXCEPTION | |
106 | +} | |
107 | + | |
108 | +/* 例外発生時に関数の呼び出し履歴を表示する、例外フィルタ関数 */ | |
109 | +static LONG CALLBACK ApplicationFaultHandler(EXCEPTION_POINTERS *ExInfo) | |
110 | +{ | |
111 | + HGLOBAL gptr; | |
112 | + STACKFRAME sf; | |
113 | + BOOL bResult; | |
114 | + PIMAGEHLP_SYMBOL pSym; | |
115 | + DWORD Disp; | |
116 | + HANDLE hProcess = GetCurrentProcess(); | |
117 | + HANDLE hThread = GetCurrentThread(); | |
118 | + IMAGEHLP_MODULE ih_module; | |
119 | + IMAGEHLP_LINE ih_line; | |
120 | + int frame; | |
121 | + char msg[3072], buf[256]; | |
122 | + HMODULE h, h2; | |
123 | + char imagehlp_dll[MAX_PATH]; | |
124 | + | |
125 | + // Windows98/Me/NT4では動かないためスキップする。(2007.10.9 yutaka) | |
126 | + GetSystemDirectory(imagehlp_dll, sizeof(imagehlp_dll)); | |
127 | + strncat_s(imagehlp_dll, sizeof(imagehlp_dll), "\\imagehlp.dll", _TRUNCATE); | |
128 | + h2 = LoadLibrary(imagehlp_dll); | |
129 | + if (((h = GetModuleHandle(imagehlp_dll)) == NULL) || | |
130 | + (GetProcAddress(h, "SymGetLineFromAddr") == NULL)) { | |
131 | + FreeLibrary(h2); | |
132 | + goto error; | |
133 | + } | |
134 | + FreeLibrary(h2); | |
135 | + | |
136 | + /* シンボル情報格納用バッファの初期化 */ | |
137 | + gptr = GlobalAlloc(GMEM_FIXED, 10000); | |
138 | + if (gptr == NULL) { | |
139 | + goto error; | |
140 | + } | |
141 | + pSym = (PIMAGEHLP_SYMBOL)GlobalLock(gptr); | |
142 | + ZeroMemory(pSym, sizeof(IMAGEHLP_SYMBOL)); | |
143 | + pSym->SizeOfStruct = 10000; | |
144 | + pSym->MaxNameLength = 10000 - sizeof(IMAGEHLP_SYMBOL); | |
145 | + | |
146 | + /* スタックフレームの初期化 */ | |
147 | + ZeroMemory(&sf, sizeof(sf)); | |
148 | + sf.AddrPC.Offset = ExInfo->ContextRecord->Eip; | |
149 | + sf.AddrStack.Offset = ExInfo->ContextRecord->Esp; | |
150 | + sf.AddrFrame.Offset = ExInfo->ContextRecord->Ebp; | |
151 | + sf.AddrPC.Mode = AddrModeFlat; | |
152 | + sf.AddrStack.Mode = AddrModeFlat; | |
153 | + sf.AddrFrame.Mode = AddrModeFlat; | |
154 | + | |
155 | + /* シンボルハンドラの初期化 */ | |
156 | + SymInitialize(hProcess, NULL, TRUE); | |
157 | + | |
158 | + // レジスタダンプ | |
159 | + msg[0] = '\0'; | |
160 | + _snprintf_s(buf, sizeof(buf), _TRUNCATE, "eax=%08X ebx=%08X ecx=%08X edx=%08X esi=%08X edi=%08X\r\n" | |
161 | + "ebp=%08X esp=%08X eip=%08X efl=%08X\r\n" | |
162 | + "cs=%04X ss=%04X ds=%04X es=%04X fs=%04X gs=%04X\r\n", | |
163 | + ExInfo->ContextRecord->Eax, | |
164 | + ExInfo->ContextRecord->Ebx, | |
165 | + ExInfo->ContextRecord->Ecx, | |
166 | + ExInfo->ContextRecord->Edx, | |
167 | + ExInfo->ContextRecord->Esi, | |
168 | + ExInfo->ContextRecord->Edi, | |
169 | + ExInfo->ContextRecord->Ebp, | |
170 | + ExInfo->ContextRecord->Esp, | |
171 | + ExInfo->ContextRecord->Eip, | |
172 | + ExInfo->ContextRecord->EFlags, | |
173 | + ExInfo->ContextRecord->SegCs, | |
174 | + ExInfo->ContextRecord->SegSs, | |
175 | + ExInfo->ContextRecord->SegDs, | |
176 | + ExInfo->ContextRecord->SegEs, | |
177 | + ExInfo->ContextRecord->SegFs, | |
178 | + ExInfo->ContextRecord->SegGs | |
179 | + ); | |
180 | + strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
181 | + | |
182 | + if (ExInfo->ExceptionRecord != NULL) { | |
183 | + _snprintf_s(buf, sizeof(buf), _TRUNCATE, "Exception: %s\r\n", GetExceptionString(ExInfo->ExceptionRecord->ExceptionCode)); | |
184 | + strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
185 | + } | |
186 | + | |
187 | + /* スタックフレームを順に表示していく */ | |
188 | + frame = 0; | |
189 | + for (;;) { | |
190 | + /* 次のスタックフレームの取得 */ | |
191 | + bResult = StackWalk( | |
192 | + IMAGE_FILE_MACHINE_I386, | |
193 | + hProcess, | |
194 | + hThread, | |
195 | + &sf, | |
196 | + NULL, | |
197 | + NULL, | |
198 | + SymFunctionTableAccess, | |
199 | + SymGetModuleBase, | |
200 | + NULL); | |
201 | + | |
202 | + /* 失敗ならば、ループを抜ける */ | |
203 | + if (!bResult || sf.AddrFrame.Offset == 0) | |
204 | + break; | |
205 | + | |
206 | + frame++; | |
207 | + | |
208 | + /* プログラムカウンタ(仮想アドレス)から関数名とオフセットを取得 */ | |
209 | + bResult = SymGetSymFromAddr(hProcess, sf.AddrPC.Offset, &Disp, pSym); | |
210 | + | |
211 | + /* 取得結果を表示 */ | |
212 | + _snprintf_s(buf, sizeof(buf), _TRUNCATE, "#%d 0x%08x in ", frame, sf.AddrPC.Offset); | |
213 | + strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
214 | + if (bResult) { | |
215 | + _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s() + 0x%x ", pSym->Name, Disp); | |
216 | + strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
217 | + } else { | |
218 | + _snprintf_s(buf, sizeof(buf), _TRUNCATE, " --- "); | |
219 | + strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
220 | + } | |
221 | + | |
222 | + // 実行ファイル名の取得 | |
223 | + ZeroMemory( &(ih_module), sizeof(ih_module) ); | |
224 | + ih_module.SizeOfStruct = sizeof(ih_module); | |
225 | + bResult = SymGetModuleInfo( hProcess, sf.AddrPC.Offset, &(ih_module) ); | |
226 | + strncat_s(msg, sizeof(msg), "at ", _TRUNCATE); | |
227 | + if (bResult) { | |
228 | + _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s ", ih_module.ImageName ); | |
229 | + strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
230 | + } else { | |
231 | + _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s ", "<Unknown Module>" ); | |
232 | + strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
233 | + } | |
234 | + | |
235 | + // ファイル名と行番号の取得 | |
236 | + ZeroMemory( &(ih_line), sizeof(ih_line) ); | |
237 | + ih_line.SizeOfStruct = sizeof(ih_line); | |
238 | + bResult = SymGetLineFromAddr( hProcess, sf.AddrPC.Offset, &Disp, &ih_line ); | |
239 | + if (bResult) | |
240 | + { | |
241 | + _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s:%lu", ih_line.FileName, ih_line.LineNumber ); | |
242 | + strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
243 | + } | |
244 | + | |
245 | + strncat_s(msg, sizeof(msg), "\n", _TRUNCATE); | |
246 | + } | |
247 | + | |
248 | + /* 後処理 */ | |
249 | + SymCleanup(hProcess); | |
250 | + GlobalUnlock(pSym); | |
251 | + GlobalFree(pSym); | |
252 | + | |
253 | + // 例外処理中なので、APIを直接呼び出す | |
254 | + ::MessageBoxA(NULL, msg, "Tera Term: Application fault", MB_OK | MB_ICONEXCLAMATION); | |
255 | + | |
256 | +error: | |
257 | +// return (EXCEPTION_EXECUTE_HANDLER); /* そのままプロセスを終了させる */ | |
258 | + return (EXCEPTION_CONTINUE_SEARCH); /* 引き続き[アプリケーションエラー]ポップアップメッセージボックスを呼び出す */ | |
259 | +} | |
260 | +#endif // !defined(_M_X64 ) | |
261 | + | |
262 | + | |
263 | +/** | |
264 | + * 例外ハンドラのフック | |
265 | + */ | |
266 | +void DebugSetException(void) | |
267 | +{ | |
268 | +#if !defined(_M_X64) | |
269 | + SetUnhandledExceptionFilter(ApplicationFaultHandler); | |
270 | +#endif | |
271 | +} |
@@ -0,0 +1,46 @@ | ||
1 | +/* | |
2 | + * (C) 2020- TeraTerm Project | |
3 | + * All rights reserved. | |
4 | + * | |
5 | + * Redistribution and use in source and binary forms, with or without | |
6 | + * modification, are permitted provided that the following conditions | |
7 | + * are met: | |
8 | + * | |
9 | + * 1. Redistributions of source code must retain the above copyright | |
10 | + * notice, this list of conditions and the following disclaimer. | |
11 | + * 2. Redistributions in binary form must reproduce the above copyright | |
12 | + * notice, this list of conditions and the following disclaimer in the | |
13 | + * documentation and/or other materials provided with the distribution. | |
14 | + * 3. The name of the author may not be used to endorse or promote products | |
15 | + * derived from this software without specific prior written permission. | |
16 | + * | |
17 | + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR | |
18 | + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
19 | + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
20 | + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
21 | + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
22 | + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 | + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 | + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
26 | + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | + */ | |
28 | + | |
29 | +#include <windows.h> | |
30 | + | |
31 | +// 起動時にデバグ用コンソールをオープンする | |
32 | +// #define DEBUG_OPEN_CONSOLE_AT_STARTUP 1 | |
33 | + | |
34 | +// 入力コードをダンプする | |
35 | +// #define DEBUG_DUMP_INPUTCODE 1 | |
36 | + | |
37 | +#ifdef __cplusplus | |
38 | +extern "C" { | |
39 | +#endif | |
40 | + | |
41 | +void DebugSetException(void); | |
42 | +HWND DebugConsoleOpen(void); | |
43 | + | |
44 | +#ifdef __cplusplus | |
45 | +} | |
46 | +#endif |
@@ -6427,7 +6427,7 @@ | ||
6427 | 6427 | LockBuffer(); |
6428 | 6428 | |
6429 | 6429 | while ((c>0) && (ChangeEmu==0)) { |
6430 | -#if UNICODE_DEBUG | |
6430 | +#if defined(DEBUG_DUMP_INPUTCODE) | |
6431 | 6431 | { |
6432 | 6432 | static DWORD prev_tick; |
6433 | 6433 | DWORD now = GetTickCount(); |
@@ -69,7 +69,6 @@ | ||
69 | 69 | #include <shlobj.h> |
70 | 70 | #include <io.h> |
71 | 71 | #include <errno.h> |
72 | -#include <imagehlp.h> | |
73 | 72 | |
74 | 73 | #include <windowsx.h> |
75 | 74 | #include <imm.h> |
@@ -223,207 +222,6 @@ | ||
223 | 222 | AutoDisconnectedPort = port; |
224 | 223 | } |
225 | 224 | |
226 | -// | |
227 | -// 例外ハンドラのフック(スタックトレースのダンプ) | |
228 | -// | |
229 | -// cf. http://svn.collab.net/repos/svn/trunk/subversion/libsvn_subr/win32_crashrpt.c | |
230 | -// (2007.9.30 yutaka) | |
231 | -// | |
232 | -// 例外コードを文字列へ変換する | |
233 | -#if !defined(_M_X64) | |
234 | -static const char *GetExceptionString(DWORD exception) | |
235 | -{ | |
236 | -#define EXCEPTION(x) case EXCEPTION_##x: return (#x); | |
237 | - static char buf[16]; | |
238 | - | |
239 | - switch (exception) | |
240 | - { | |
241 | - EXCEPTION(ACCESS_VIOLATION) | |
242 | - EXCEPTION(DATATYPE_MISALIGNMENT) | |
243 | - EXCEPTION(BREAKPOINT) | |
244 | - EXCEPTION(SINGLE_STEP) | |
245 | - EXCEPTION(ARRAY_BOUNDS_EXCEEDED) | |
246 | - EXCEPTION(FLT_DENORMAL_OPERAND) | |
247 | - EXCEPTION(FLT_DIVIDE_BY_ZERO) | |
248 | - EXCEPTION(FLT_INEXACT_RESULT) | |
249 | - EXCEPTION(FLT_INVALID_OPERATION) | |
250 | - EXCEPTION(FLT_OVERFLOW) | |
251 | - EXCEPTION(FLT_STACK_CHECK) | |
252 | - EXCEPTION(FLT_UNDERFLOW) | |
253 | - EXCEPTION(INT_DIVIDE_BY_ZERO) | |
254 | - EXCEPTION(INT_OVERFLOW) | |
255 | - EXCEPTION(PRIV_INSTRUCTION) | |
256 | - EXCEPTION(IN_PAGE_ERROR) | |
257 | - EXCEPTION(ILLEGAL_INSTRUCTION) | |
258 | - EXCEPTION(NONCONTINUABLE_EXCEPTION) | |
259 | - EXCEPTION(STACK_OVERFLOW) | |
260 | - EXCEPTION(INVALID_DISPOSITION) | |
261 | - EXCEPTION(GUARD_PAGE) | |
262 | - EXCEPTION(INVALID_HANDLE) | |
263 | - | |
264 | - default: | |
265 | - _snprintf_s(buf, sizeof(buf), _TRUNCATE, "0x%x", exception); | |
266 | - return buf; | |
267 | - //return "UNKNOWN_ERROR"; | |
268 | - } | |
269 | -#undef EXCEPTION | |
270 | -} | |
271 | - | |
272 | -/* 例外発生時に関数の呼び出し履歴を表示する、例外フィルタ関数 */ | |
273 | -static LONG CALLBACK ApplicationFaultHandler(EXCEPTION_POINTERS *ExInfo) | |
274 | -{ | |
275 | - HGLOBAL gptr; | |
276 | - STACKFRAME sf; | |
277 | - BOOL bResult; | |
278 | - PIMAGEHLP_SYMBOL pSym; | |
279 | - DWORD Disp; | |
280 | - HANDLE hProcess = GetCurrentProcess(); | |
281 | - HANDLE hThread = GetCurrentThread(); | |
282 | - IMAGEHLP_MODULE ih_module; | |
283 | - IMAGEHLP_LINE ih_line; | |
284 | - int frame; | |
285 | - char msg[3072], buf[256]; | |
286 | - HMODULE h, h2; | |
287 | - char imagehlp_dll[MAX_PATH]; | |
288 | - | |
289 | - // Windows98/Me/NT4では動かないためスキップする。(2007.10.9 yutaka) | |
290 | - GetSystemDirectory(imagehlp_dll, sizeof(imagehlp_dll)); | |
291 | - strncat_s(imagehlp_dll, sizeof(imagehlp_dll), "\\imagehlp.dll", _TRUNCATE); | |
292 | - h2 = LoadLibrary(imagehlp_dll); | |
293 | - if (((h = GetModuleHandle(imagehlp_dll)) == NULL) || | |
294 | - (GetProcAddress(h, "SymGetLineFromAddr") == NULL)) { | |
295 | - FreeLibrary(h2); | |
296 | - goto error; | |
297 | - } | |
298 | - FreeLibrary(h2); | |
299 | - | |
300 | - /* シンボル情報格納用バッファの初期化 */ | |
301 | - gptr = GlobalAlloc(GMEM_FIXED, 10000); | |
302 | - if (gptr == NULL) { | |
303 | - goto error; | |
304 | - } | |
305 | - pSym = (PIMAGEHLP_SYMBOL)GlobalLock(gptr); | |
306 | - ZeroMemory(pSym, sizeof(IMAGEHLP_SYMBOL)); | |
307 | - pSym->SizeOfStruct = 10000; | |
308 | - pSym->MaxNameLength = 10000 - sizeof(IMAGEHLP_SYMBOL); | |
309 | - | |
310 | - /* スタックフレームの初期化 */ | |
311 | - ZeroMemory(&sf, sizeof(sf)); | |
312 | - sf.AddrPC.Offset = ExInfo->ContextRecord->Eip; | |
313 | - sf.AddrStack.Offset = ExInfo->ContextRecord->Esp; | |
314 | - sf.AddrFrame.Offset = ExInfo->ContextRecord->Ebp; | |
315 | - sf.AddrPC.Mode = AddrModeFlat; | |
316 | - sf.AddrStack.Mode = AddrModeFlat; | |
317 | - sf.AddrFrame.Mode = AddrModeFlat; | |
318 | - | |
319 | - /* シンボルハンドラの初期化 */ | |
320 | - SymInitialize(hProcess, NULL, TRUE); | |
321 | - | |
322 | - // レジスタダンプ | |
323 | - msg[0] = '\0'; | |
324 | - _snprintf_s(buf, sizeof(buf), _TRUNCATE, "eax=%08X ebx=%08X ecx=%08X edx=%08X esi=%08X edi=%08X\r\n" | |
325 | - "ebp=%08X esp=%08X eip=%08X efl=%08X\r\n" | |
326 | - "cs=%04X ss=%04X ds=%04X es=%04X fs=%04X gs=%04X\r\n", | |
327 | - ExInfo->ContextRecord->Eax, | |
328 | - ExInfo->ContextRecord->Ebx, | |
329 | - ExInfo->ContextRecord->Ecx, | |
330 | - ExInfo->ContextRecord->Edx, | |
331 | - ExInfo->ContextRecord->Esi, | |
332 | - ExInfo->ContextRecord->Edi, | |
333 | - ExInfo->ContextRecord->Ebp, | |
334 | - ExInfo->ContextRecord->Esp, | |
335 | - ExInfo->ContextRecord->Eip, | |
336 | - ExInfo->ContextRecord->EFlags, | |
337 | - ExInfo->ContextRecord->SegCs, | |
338 | - ExInfo->ContextRecord->SegSs, | |
339 | - ExInfo->ContextRecord->SegDs, | |
340 | - ExInfo->ContextRecord->SegEs, | |
341 | - ExInfo->ContextRecord->SegFs, | |
342 | - ExInfo->ContextRecord->SegGs | |
343 | - ); | |
344 | - strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
345 | - | |
346 | - if (ExInfo->ExceptionRecord != NULL) { | |
347 | - _snprintf_s(buf, sizeof(buf), _TRUNCATE, "Exception: %s\r\n", GetExceptionString(ExInfo->ExceptionRecord->ExceptionCode)); | |
348 | - strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
349 | - } | |
350 | - | |
351 | - /* スタックフレームを順に表示していく */ | |
352 | - frame = 0; | |
353 | - for (;;) { | |
354 | - /* 次のスタックフレームの取得 */ | |
355 | - bResult = StackWalk( | |
356 | - IMAGE_FILE_MACHINE_I386, | |
357 | - hProcess, | |
358 | - hThread, | |
359 | - &sf, | |
360 | - NULL, | |
361 | - NULL, | |
362 | - SymFunctionTableAccess, | |
363 | - SymGetModuleBase, | |
364 | - NULL); | |
365 | - | |
366 | - /* 失敗ならば、ループを抜ける */ | |
367 | - if (!bResult || sf.AddrFrame.Offset == 0) | |
368 | - break; | |
369 | - | |
370 | - frame++; | |
371 | - | |
372 | - /* プログラムカウンタ(仮想アドレス)から関数名とオフセットを取得 */ | |
373 | - bResult = SymGetSymFromAddr(hProcess, sf.AddrPC.Offset, &Disp, pSym); | |
374 | - | |
375 | - /* 取得結果を表示 */ | |
376 | - _snprintf_s(buf, sizeof(buf), _TRUNCATE, "#%d 0x%08x in ", frame, sf.AddrPC.Offset); | |
377 | - strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
378 | - if (bResult) { | |
379 | - _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s() + 0x%x ", pSym->Name, Disp); | |
380 | - strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
381 | - } else { | |
382 | - _snprintf_s(buf, sizeof(buf), _TRUNCATE, " --- "); | |
383 | - strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
384 | - } | |
385 | - | |
386 | - // 実行ファイル名の取得 | |
387 | - ZeroMemory( &(ih_module), sizeof(ih_module) ); | |
388 | - ih_module.SizeOfStruct = sizeof(ih_module); | |
389 | - bResult = SymGetModuleInfo( hProcess, sf.AddrPC.Offset, &(ih_module) ); | |
390 | - strncat_s(msg, sizeof(msg), "at ", _TRUNCATE); | |
391 | - if (bResult) { | |
392 | - _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s ", ih_module.ImageName ); | |
393 | - strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
394 | - } else { | |
395 | - _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s ", "<Unknown Module>" ); | |
396 | - strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
397 | - } | |
398 | - | |
399 | - // ファイル名と行番号の取得 | |
400 | - ZeroMemory( &(ih_line), sizeof(ih_line) ); | |
401 | - ih_line.SizeOfStruct = sizeof(ih_line); | |
402 | - bResult = SymGetLineFromAddr( hProcess, sf.AddrPC.Offset, &Disp, &ih_line ); | |
403 | - if (bResult) | |
404 | - { | |
405 | - _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s:%lu", ih_line.FileName, ih_line.LineNumber ); | |
406 | - strncat_s(msg, sizeof(msg), buf, _TRUNCATE); | |
407 | - } | |
408 | - | |
409 | - strncat_s(msg, sizeof(msg), "\n", _TRUNCATE); | |
410 | - } | |
411 | - | |
412 | - /* 後処理 */ | |
413 | - SymCleanup(hProcess); | |
414 | - GlobalUnlock(pSym); | |
415 | - GlobalFree(pSym); | |
416 | - | |
417 | - // 例外処理中なので、APIを直接呼び出す | |
418 | - ::MessageBoxA(NULL, msg, "Tera Term: Application fault", MB_OK | MB_ICONEXCLAMATION); | |
419 | - | |
420 | -error: | |
421 | -// return (EXCEPTION_EXECUTE_HANDLER); /* そのままプロセスを終了させる */ | |
422 | - return (EXCEPTION_CONTINUE_SEARCH); /* 引き続き[アプリケーションエラー]ポップアップメッセージボックスを呼び出す */ | |
423 | -} | |
424 | -#endif // !defined(_M_X64 ) | |
425 | - | |
426 | - | |
427 | 225 | // Virtual Storeが有効であるかどうかを判別する。 |
428 | 226 | // |
429 | 227 | // [Windows 95-XP] |
@@ -524,11 +322,6 @@ | ||
524 | 322 | BOOL isFirstInstance; |
525 | 323 | m_hInst = hInstance; |
526 | 324 | |
527 | - // 例外ハンドラのフック (2007.9.30 yutaka) | |
528 | -#if !defined(_M_X64) | |
529 | - SetUnhandledExceptionFilter(ApplicationFaultHandler); | |
530 | -#endif | |
531 | - | |
532 | 325 | CommInit(&cv); |
533 | 326 | isFirstInstance = StartTeraTerm(&ts); |
534 | 327 |