Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/ttcomtester/teraterm/teraterm/ttdebug.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9727 - (hide annotations) (download) (as text)
Sun Feb 6 13:56:49 2022 UTC (2 years, 2 months ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/ttdebug.cpp
File MIME type: text/x-c++src
File size: 10627 byte(s)
ポータブル版のフォルダを考慮

- ポータブル版の判定
  - ExeDirW() (exe があるフォルダ)に portable.ini というファイルがあるとき
- ポータブル版の時の動作
  - HomeDirW() は ExeDirW() と同じフォルダを返す
  - LogDirW() は ExeDirW() + "\log" を返す

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

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