Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/ttdebug.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10171 - (hide annotations) (download) (as text)
Thu Aug 18 14:43:36 2022 UTC (19 months, 3 weeks ago) by zmatsuo
File MIME type: text/x-c++src
File size: 10671 byte(s)
テスト用クラッシュ関数のクラッシュ方法を変更

- __debugbreak() を使用するようにした
- 以前はNULLポインタへの書き込みだった
- MinGW の時は __builtin_trap() を使用していた (r10167)
1 zmatsuo 9124 /*
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 zmatsuo 9405 #include <shlobj.h> // for SHGetSpecialFolderPathW()
33 zmatsuo 10171 #include <intrin.h> // for __debugbreak()
34 zmatsuo 9124
35     #include "compat_win.h"
36 zmatsuo 9405 #include "asprintf.h"
37     #include "svnversion.h" // for SVNVERSION
38 zmatsuo 9124
39     #include "ttdebug.h"
40 nmaya 9715 #include "ttlib.h"
41 zmatsuo 9124
42     /**
43     * �R���\�[���E�B���h�E���\�������f�o�O�p
44     * �f�o�O�p������������printf()�n���\����������������������������
45     *
46     * @retval �R���\�[����Window Handle
47     */
48     HWND DebugConsoleOpen(void)
49     {
50     FILE *fp;
51     HWND hWnd = pGetConsoleWindow();
52     if (hWnd != NULL) {
53     return hWnd;
54     }
55     AllocConsole();
56     freopen_s(&fp, "CONOUT$", "w", stdout);
57     freopen_s(&fp, "CONOUT$", "w", stderr);
58    
59     // �������{�^����������
60     hWnd = pGetConsoleWindow();
61     HMENU hmenu = GetSystemMenu(hWnd, FALSE);
62     RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
63    
64     return hWnd;
65     }
66    
67     //
68     // ���O�n���h�����t�b�N�i�X�^�b�N�g���[�X���_���v�j
69     //
70     // cf. http://svn.collab.net/repos/svn/trunk/subversion/libsvn_subr/win32_crashrpt.c
71     // (2007.9.30 yutaka)
72     //
73     // ���O�R�[�h������������������
74     #if !defined(_M_X64)
75     static const char *GetExceptionString(DWORD exception)
76     {
77     #define EXCEPTION(x) case EXCEPTION_##x: return (#x);
78     static char buf[16];
79    
80     switch (exception)
81     {
82     EXCEPTION(ACCESS_VIOLATION)
83     EXCEPTION(DATATYPE_MISALIGNMENT)
84     EXCEPTION(BREAKPOINT)
85     EXCEPTION(SINGLE_STEP)
86     EXCEPTION(ARRAY_BOUNDS_EXCEEDED)
87     EXCEPTION(FLT_DENORMAL_OPERAND)
88     EXCEPTION(FLT_DIVIDE_BY_ZERO)
89     EXCEPTION(FLT_INEXACT_RESULT)
90     EXCEPTION(FLT_INVALID_OPERATION)
91     EXCEPTION(FLT_OVERFLOW)
92     EXCEPTION(FLT_STACK_CHECK)
93     EXCEPTION(FLT_UNDERFLOW)
94     EXCEPTION(INT_DIVIDE_BY_ZERO)
95     EXCEPTION(INT_OVERFLOW)
96     EXCEPTION(PRIV_INSTRUCTION)
97     EXCEPTION(IN_PAGE_ERROR)
98     EXCEPTION(ILLEGAL_INSTRUCTION)
99     EXCEPTION(NONCONTINUABLE_EXCEPTION)
100     EXCEPTION(STACK_OVERFLOW)
101     EXCEPTION(INVALID_DISPOSITION)
102     EXCEPTION(GUARD_PAGE)
103     EXCEPTION(INVALID_HANDLE)
104    
105     default:
106     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "0x%x", exception);
107     return buf;
108     //return "UNKNOWN_ERROR";
109     }
110     #undef EXCEPTION
111     }
112    
113     /* ���O�������������������o���������\�������A���O�t�B���^���� */
114 zmatsuo 9405 static void CALLBACK ApplicationFaultHandler(EXCEPTION_POINTERS *ExInfo)
115 zmatsuo 9124 {
116     HGLOBAL gptr;
117     STACKFRAME sf;
118     BOOL bResult;
119     PIMAGEHLP_SYMBOL pSym;
120     DWORD Disp;
121     HANDLE hProcess = GetCurrentProcess();
122     HANDLE hThread = GetCurrentThread();
123     IMAGEHLP_MODULE ih_module;
124     IMAGEHLP_LINE ih_line;
125     int frame;
126     char msg[3072], buf[256];
127    
128 zmatsuo 9127 if (pSymGetLineFromAddr == NULL) {
129     goto error;
130     }
131 zmatsuo 9124
132     /* �V���{�������i�[�p�o�b�t�@�������� */
133     gptr = GlobalAlloc(GMEM_FIXED, 10000);
134     if (gptr == NULL) {
135     goto error;
136     }
137     pSym = (PIMAGEHLP_SYMBOL)GlobalLock(gptr);
138     ZeroMemory(pSym, sizeof(IMAGEHLP_SYMBOL));
139     pSym->SizeOfStruct = 10000;
140     pSym->MaxNameLength = 10000 - sizeof(IMAGEHLP_SYMBOL);
141    
142     /* �X�^�b�N�t���[���������� */
143     ZeroMemory(&sf, sizeof(sf));
144     sf.AddrPC.Offset = ExInfo->ContextRecord->Eip;
145     sf.AddrStack.Offset = ExInfo->ContextRecord->Esp;
146     sf.AddrFrame.Offset = ExInfo->ContextRecord->Ebp;
147     sf.AddrPC.Mode = AddrModeFlat;
148     sf.AddrStack.Mode = AddrModeFlat;
149     sf.AddrFrame.Mode = AddrModeFlat;
150    
151     /* �V���{���n���h���������� */
152     SymInitialize(hProcess, NULL, TRUE);
153    
154     // ���W�X�^�_���v
155     msg[0] = '\0';
156     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "eax=%08X ebx=%08X ecx=%08X edx=%08X esi=%08X edi=%08X\r\n"
157     "ebp=%08X esp=%08X eip=%08X efl=%08X\r\n"
158     "cs=%04X ss=%04X ds=%04X es=%04X fs=%04X gs=%04X\r\n",
159     ExInfo->ContextRecord->Eax,
160     ExInfo->ContextRecord->Ebx,
161     ExInfo->ContextRecord->Ecx,
162     ExInfo->ContextRecord->Edx,
163     ExInfo->ContextRecord->Esi,
164     ExInfo->ContextRecord->Edi,
165     ExInfo->ContextRecord->Ebp,
166     ExInfo->ContextRecord->Esp,
167     ExInfo->ContextRecord->Eip,
168     ExInfo->ContextRecord->EFlags,
169     ExInfo->ContextRecord->SegCs,
170     ExInfo->ContextRecord->SegSs,
171     ExInfo->ContextRecord->SegDs,
172     ExInfo->ContextRecord->SegEs,
173     ExInfo->ContextRecord->SegFs,
174     ExInfo->ContextRecord->SegGs
175     );
176     strncat_s(msg, sizeof(msg), buf, _TRUNCATE);
177    
178     if (ExInfo->ExceptionRecord != NULL) {
179     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "Exception: %s\r\n", GetExceptionString(ExInfo->ExceptionRecord->ExceptionCode));
180     strncat_s(msg, sizeof(msg), buf, _TRUNCATE);
181     }
182    
183     /* �X�^�b�N�t���[���������\���������� */
184     frame = 0;
185     for (;;) {
186     /* �����X�^�b�N�t���[�������� */
187     bResult = StackWalk(
188     IMAGE_FILE_MACHINE_I386,
189     hProcess,
190     hThread,
191     &sf,
192     NULL,
193     NULL,
194     SymFunctionTableAccess,
195     SymGetModuleBase,
196     NULL);
197    
198     /* ���s�������A���[�v�������� */
199     if (!bResult || sf.AddrFrame.Offset == 0)
200     break;
201    
202     frame++;
203    
204     /* �v���O�����J�E���^�i���z�A�h���X�j�������������I�t�Z�b�g������ */
205     bResult = SymGetSymFromAddr(hProcess, sf.AddrPC.Offset, &Disp, pSym);
206    
207     /* �����������\�� */
208     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "#%d 0x%08x in ", frame, sf.AddrPC.Offset);
209     strncat_s(msg, sizeof(msg), buf, _TRUNCATE);
210     if (bResult) {
211     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s() + 0x%x ", pSym->Name, Disp);
212     strncat_s(msg, sizeof(msg), buf, _TRUNCATE);
213     } else {
214     _snprintf_s(buf, sizeof(buf), _TRUNCATE, " --- ");
215     strncat_s(msg, sizeof(msg), buf, _TRUNCATE);
216     }
217    
218     // ���s�t�@�C����������
219     ZeroMemory( &(ih_module), sizeof(ih_module) );
220     ih_module.SizeOfStruct = sizeof(ih_module);
221     bResult = SymGetModuleInfo( hProcess, sf.AddrPC.Offset, &(ih_module) );
222     strncat_s(msg, sizeof(msg), "at ", _TRUNCATE);
223     if (bResult) {
224     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s ", ih_module.ImageName );
225     strncat_s(msg, sizeof(msg), buf, _TRUNCATE);
226     } else {
227     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s ", "<Unknown Module>" );
228     strncat_s(msg, sizeof(msg), buf, _TRUNCATE);
229     }
230    
231     // �t�@�C�������s����������
232     ZeroMemory( &(ih_line), sizeof(ih_line) );
233     ih_line.SizeOfStruct = sizeof(ih_line);
234 zmatsuo 9127 bResult = pSymGetLineFromAddr( hProcess, sf.AddrPC.Offset, &Disp, &ih_line );
235 zmatsuo 9124 if (bResult)
236     {
237     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s:%lu", ih_line.FileName, ih_line.LineNumber );
238     strncat_s(msg, sizeof(msg), buf, _TRUNCATE);
239     }
240    
241     strncat_s(msg, sizeof(msg), "\n", _TRUNCATE);
242     }
243    
244     /* ������ */
245     SymCleanup(hProcess);
246     GlobalUnlock(pSym);
247     GlobalFree(pSym);
248    
249     // ���O�������������AAPI�����������o��
250     ::MessageBoxA(NULL, msg, "Tera Term: Application fault", MB_OK | MB_ICONEXCLAMATION);
251    
252     error:
253 zmatsuo 9405 ;
254 zmatsuo 9124 }
255     #endif // !defined(_M_X64 )
256    
257 zmatsuo 9405 static wchar_t *CreateDumpFilename()
258     {
259     SYSTEMTIME local_time;
260     GetLocalTime(&local_time);
261    
262 zmatsuo 9442 #if defined(SVNVERSION)
263     char *version;
264     asprintf(&version, "r%04d", SVNVERSION);
265     #else
266 zmatsuo 9463 char *version = _strdup("unknown");
267 zmatsuo 9442 #endif
268 zmatsuo 9405 wchar_t *dump_file;
269 nmaya 9715 aswprintf(&dump_file, L"teraterm_%hs_%04u%02u%02u-%02u%02u%02u.dmp",
270     version,
271 zmatsuo 9405 local_time.wYear, local_time.wMonth, local_time.wDay,
272     local_time.wHour, local_time.wMinute, local_time.wSecond);
273 zmatsuo 9442 free(version);
274 zmatsuo 9405 return dump_file;
275     }
276    
277     static void DumpMiniDump(const wchar_t *filename, struct _EXCEPTION_POINTERS* pExceptionPointers)
278     {
279 nmaya 9715 wchar_t *logdir = NULL;
280     wchar_t *dumpfile = NULL;
281    
282 zmatsuo 9405 if (pMiniDumpWriteDump == NULL) {
283     // MiniDumpWriteDump() ���T�|�[�g�������������BXP�����O
284     return;
285     }
286    
287 zmatsuo 9727 logdir = GetLogDirW(NULL);
288 nmaya 9715 awcscats(&dumpfile, logdir, L"\\", filename, NULL);
289     HANDLE file = CreateFileW(dumpfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
290     free(dumpfile);
291 zmatsuo 9405 if (file == INVALID_HANDLE_VALUE) {
292     return;
293     }
294    
295     MINIDUMP_EXCEPTION_INFORMATION mdei;
296     mdei.ThreadId = GetCurrentThreadId();
297     mdei.ExceptionPointers = pExceptionPointers;
298     mdei.ClientPointers = TRUE;
299    
300     pMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file,
301     (MINIDUMP_TYPE)(MiniDumpNormal|MiniDumpWithHandleData), &mdei, NULL, NULL);
302    
303     CloseHandle(file);
304     }
305    
306     static BOOL DumpFile = TRUE;
307    
308     static LONG WINAPI ExceptionFilter(struct _EXCEPTION_POINTERS* pExceptionPointers)
309     {
310     if (DumpFile) {
311     wchar_t *fname = CreateDumpFilename();
312     if (fname != NULL) {
313     DumpMiniDump(fname, pExceptionPointers);
314     MessageBoxW(NULL, fname, L"Tera Term", MB_OK);
315     free(fname);
316     }
317     else {
318     DumpMiniDump(L"teraterm.dmp", pExceptionPointers);
319     MessageBoxW(NULL, L"dump teraterm.dmp", L"Tera Term", MB_OK);
320     }
321     }
322    
323     #if !defined(_M_X64)
324     ApplicationFaultHandler(pExceptionPointers);
325     #endif
326    
327     // return EXCEPTION_EXECUTE_HANDLER; /* ���������v���Z�X���I�������� */
328     return EXCEPTION_CONTINUE_SEARCH; /* ���������m�A�v���P�[�V�����G���[�n�|�b�v�A�b�v���b�Z�[�W�{�b�N�X�������o�� */
329     }
330    
331     void DebugTestCrash(void)
332     {
333 zmatsuo 10171 __debugbreak();
334 zmatsuo 9405 }
335    
336     static void InvalidParameterHandler(const wchar_t* /*expression*/,
337     const wchar_t* /*function*/,
338     const wchar_t* /*file*/,
339     unsigned int /*line*/,
340     uintptr_t /*pReserved*/)
341     {
342     DebugTestCrash();
343     }
344    
345 zmatsuo 9124 /**
346     * ���O�n���h�����t�b�N
347     */
348     void DebugSetException(void)
349     {
350 zmatsuo 9405 SetUnhandledExceptionFilter(ExceptionFilter);
351    
352     // C�����^�C���������p�����[�^�G���[�n���h��
353     _set_invalid_parameter_handler(InvalidParameterHandler);
354 zmatsuo 9124 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26