[PATCH] winedbg: add a crash dialog for --auto mode
Mikołaj Zalewski
mikolaj at zalewski.pl
Sun Dec 21 15:28:32 CST 2008
---
programs/winedbg/Makefile.in | 5 +-
programs/winedbg/crashdlg.c | 193 +++++++++++++++++++++++++++++++++++++++++
programs/winedbg/debugger.h | 6 ++
programs/winedbg/resource.h | 34 +++++++
programs/winedbg/rsrc.rc | 26 ++++++
programs/winedbg/rsrc_En.rc | 53 +++++++++++
programs/winedbg/tgt_active.c | 16 +++-
programs/winedbg/winedbg.c | 36 +++++---
8 files changed, 351 insertions(+), 18 deletions(-)
diff --git a/programs/winedbg/Makefile.in b/programs/winedbg/Makefile.in
index 395869e..b4dd150 100644
--- a/programs/winedbg/Makefile.in
+++ b/programs/winedbg/Makefile.in
@@ -5,7 +5,7 @@ VPATH = @srcdir@
MODULE = winedbg.exe
APPMODE = -mconsole
IMPORTS = psapi dbghelp advapi32 kernel32 ntdll
-DELAYIMPORTS = user32
+DELAYIMPORTS = user32 gdi32
EXTRALIBS = @LIBPOLL@
C_SRCS = \
@@ -14,6 +14,7 @@ C_SRCS = \
be_ppc.c \
be_x86_64.c \
break.c \
+ crashdlg.c \
db_disasm.c \
display.c \
expr.c \
@@ -29,6 +30,8 @@ C_SRCS = \
types.c \
winedbg.c
+RC_SRCS = rsrc.rc
+
LEX_SRCS = debug.l
BISON_SRCS = dbg.y
diff --git a/programs/winedbg/crashdlg.c b/programs/winedbg/crashdlg.c
new file mode 100644
index 0000000..eeb448b
--- /dev/null
+++ b/programs/winedbg/crashdlg.c
@@ -0,0 +1,193 @@
+/*
+ * The dialog that displays after a crash
+ *
+ * Copyright 2008 Mikolaj Zalewski
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "resource.h"
+#include "debugger.h"
+#include "wingdi.h"
+#include "winuser.h"
+
+#include <wine/debug.h>
+#include <wine/unicode.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
+
+#define MAX_PROGRAM_NAME_LENGTH 80
+
+/* needed for get_process_image_name */
+#include "winternl.h"
+#define STATUS_SUCCESS ((NTSTATUS) 0x00000000)
+#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004)
+
+/* FIXME: we should use psapi.GetProcessImageFileName when it works */
+static LPWSTR get_process_image_name(HANDLE hProcess)
+{
+ UNICODE_STRING *output;
+ ULONG size, returned;
+ NTSTATUS status;
+
+ status = NtQueryInformationProcess(hProcess, ProcessImageFileName, NULL, 0, &size);
+ if (status != STATUS_INFO_LENGTH_MISMATCH)
+ {
+ WINE_FIXME("First query returned %08x\n", status);
+ return NULL;
+ }
+
+ output = HeapAlloc(GetProcessHeap(), 0, size);
+ status = NtQueryInformationProcess(hProcess, ProcessImageFileName, output, size, &returned);
+ if (status != STATUS_SUCCESS)
+ {
+ WINE_FIXME("Second query returned %08x\n", status);
+ HeapFree(GetProcessHeap(), 0, output);
+ return NULL;
+ }
+
+ return output->Buffer;
+}
+
+int msgbox_res_id(HWND hwnd, UINT textId, UINT captionId, UINT uType)
+{
+ WCHAR caption[256];
+ WCHAR text[256];
+ LoadStringW(GetModuleHandleW(NULL), captionId, caption, sizeof(caption)/sizeof(caption[0]));
+ LoadStringW(GetModuleHandleW(NULL), textId, text, sizeof(text)/sizeof(text[0]));
+ return MessageBoxW(hwnd, text, caption, uType);
+}
+
+static WCHAR *get_program_name(HANDLE hProcess)
+{
+ LPWSTR image_name;
+ WCHAR *programname;
+
+ image_name = get_process_image_name(hProcess);
+ if (image_name == NULL)
+ {
+ static WCHAR unidentified[MAX_PROGRAM_NAME_LENGTH];
+ LoadStringW(GetModuleHandleW(NULL), IDS_UNIDENTIFIED,
+ unidentified, MAX_PROGRAM_NAME_LENGTH);
+ return unidentified;
+ }
+
+ programname = strrchrW(image_name, '\\');
+ if (programname != NULL)
+ programname++;
+ else
+ programname = image_name;
+ /* don't display a too long string to the user */
+ if (strlenW(programname) > MAX_PROGRAM_NAME_LENGTH)
+ {
+ programname[MAX_PROGRAM_NAME_LENGTH - 4] = '.';
+ programname[MAX_PROGRAM_NAME_LENGTH - 3] = '.';
+ programname[MAX_PROGRAM_NAME_LENGTH - 2] = '.';
+ programname[MAX_PROGRAM_NAME_LENGTH - 1] = 0;
+ }
+
+ /* TODO: if the image has a VERSIONINFO, we could try to find there a more
+ * user-friendly program name */
+
+ /* we waste some memory for the full path and UNICODE_STRING header, but
+ * that's OK, as this function is called only once */
+ return programname;
+}
+
+static LPWSTR g_ProgramName;
+static HFONT g_hBoldFont;
+static HMENU g_hDebugMenu = NULL;
+
+static void set_bold_font(HWND hDlg)
+{
+ HFONT hNormalFont = (HFONT)SendDlgItemMessageW(hDlg, IDC_STATIC_TXT1,
+ WM_GETFONT, 0, 0);
+ LOGFONTW font;
+ GetObjectW(hNormalFont, sizeof(LOGFONTW), &font);
+ font.lfWeight = FW_BOLD;
+ g_hBoldFont = CreateFontIndirectW(&font);
+ SendDlgItemMessageW(hDlg, IDC_STATIC_TXT1, WM_SETFONT, (WPARAM)g_hBoldFont, TRUE);
+}
+
+static void set_message_with_filename(HWND hDlg)
+{
+ WCHAR originalText[1000];
+ WCHAR newText[1000 + MAX_PROGRAM_NAME_LENGTH];
+
+ GetDlgItemTextW(hDlg, IDC_STATIC_TXT1, originalText,
+ sizeof(originalText)/sizeof(originalText[0]));
+ wsprintfW(newText, originalText, g_ProgramName);
+ SetDlgItemTextW(hDlg, IDC_STATIC_TXT1, newText);
+}
+
+static INT_PTR WINAPI DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ set_bold_font(hwnd);
+ set_message_with_filename(hwnd);
+ return TRUE;
+ }
+ case WM_CTLCOLORSTATIC:
+ {
+ /* WM_CTLCOLOR* don't use DWLP_MSGRESULT */
+ INT_PTR id = GetDlgCtrlID((HWND)lParam);
+ if (id == IDC_STATIC_BG || id == IDC_STATIC_TXT1)
+ return (LONG_PTR)GetSysColorBrush(COLOR_WINDOW);
+
+ return FALSE;
+ }
+ case WM_RBUTTONDOWN:
+ {
+ POINT mousePos;
+ if (!(wParam & MK_SHIFT))
+ return FALSE;
+ if (g_hDebugMenu == NULL)
+ g_hDebugMenu = LoadMenuW(GetModuleHandleW(NULL), MAKEINTRESOURCEW(IDM_DEBUG_POPUP));
+ GetCursorPos(&mousePos);
+ TrackPopupMenu(GetSubMenu(g_hDebugMenu, 0), TPM_RIGHTBUTTON, mousePos.x, mousePos.y,
+ 0, hwnd, NULL);
+ return TRUE;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDOK:
+ case IDCANCEL:
+ case ID_DEBUG:
+ EndDialog(hwnd, LOWORD(wParam));
+ return TRUE;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL display_crash_dialog()
+{
+ INT_PTR result;
+ /* dbg_curr_process->handle is not set */
+ HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dbg_curr_pid);
+ g_ProgramName = get_program_name(hProcess);
+ CloseHandle(hProcess);
+ result = DialogBoxW(GetModuleHandleW(NULL), MAKEINTRESOURCEW(IDD_CRASH_DLG), NULL, DlgProc);
+ if (result == ID_DEBUG) {
+ AllocConsole();
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index 319f0dc..added35 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -300,6 +300,10 @@ extern void break_suspend_execution(void);
extern void break_restart_execution(int count);
extern int break_add_condition(int bpnum, struct expr* exp);
+ /* crashdlg.c */
+extern BOOL display_crash_dialog();
+extern int msgbox_res_id(HWND hwnd, UINT textId, UINT captionId, UINT uType);
+
/* dbg.y */
extern void parser(const char*);
extern void parser_handle(HANDLE);
@@ -459,6 +463,8 @@ extern BOOL dbg_init(HANDLE hProc, const WCHAR* in, BOOL invade);
extern BOOL dbg_load_module(HANDLE hProc, HANDLE hFile, const WCHAR* name, DWORD base, DWORD size);
extern BOOL dbg_get_debuggee_info(HANDLE hProcess, IMAGEHLP_MODULE* imh_mod);
extern void dbg_set_option(const char*, const char*);
+extern void dbg_start_interactive(HANDLE hFile);
+extern void dbg_init_console(void);
/* gdbproxy.c */
extern int gdb_main(int argc, char* argv[]);
diff --git a/programs/winedbg/resource.h b/programs/winedbg/resource.h
new file mode 100644
index 0000000..49d19ef
--- /dev/null
+++ b/programs/winedbg/resource.h
@@ -0,0 +1,34 @@
+/*
+ * Resource IDs (resource.h)
+ *
+ * Copyright 2008 Mikolaj Zalewski
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#define IDD_CRASH_DLG 100
+
+#define IDC_STATIC_BG 100
+#define IDC_STATIC_TXT1 101
+#define IDC_STATIC_TXT2 102
+
+#define IDM_DEBUG_POPUP 100
+
+#define ID_DEBUG 200
+
+#define IDS_AUTO_CAPTION 16
+#define IDS_INVALID_PARAMS 17
+#define IDS_UNIDENTIFIED 18
diff --git a/programs/winedbg/rsrc.rc b/programs/winedbg/rsrc.rc
new file mode 100644
index 0000000..1c202a9
--- /dev/null
+++ b/programs/winedbg/rsrc.rc
@@ -0,0 +1,26 @@
+/*
+ * Resources (rsrc.rc)
+ *
+ * Copyright 2008 Mikolaj Zalewski
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <windef.h>
+#include <winuser.h>
+
+#include "resource.h"
+
+#include "rsrc_En.rc"
diff --git a/programs/winedbg/rsrc_En.rc b/programs/winedbg/rsrc_En.rc
new file mode 100644
index 0000000..773f7eb
--- /dev/null
+++ b/programs/winedbg/rsrc_En.rc
@@ -0,0 +1,53 @@
+/*
+ * English Language Support
+ *
+ * Copyright 2008 Mikolaj Zalewski
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+IDM_DEBUG_POPUP MENU
+BEGIN
+ POPUP ""
+ BEGIN
+ MENUITEM "&Debug", ID_DEBUG
+ END
+END
+
+IDD_CRASH_DLG DIALOGEX 100, 100, 273, 175
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Program Error"
+FONT 8, "Tahoma"
+BEGIN
+ LTEXT "",IDC_STATIC_BG,0,0,273,52,WS_BORDER,0
+ LTEXT "The program %s has encountered a serious problem and needs \
+ to close. We are sorry for the inconvinience.",
+ IDC_STATIC_TXT1,27,10,224,30
+ LTEXT "This can be caused by a problem in the program or a deficiency in Wine. \
+ You may want to check http://appdb.winehq.org for tips about running \
+ this application.\n\n\
+ If this problem is not present under Windows and it has not been reported \
+ yet, you can report it at http://bugs.winehq.org",IDC_STATIC_TXT2,27,60,224,100
+ DEFPUSHBUTTON "Close", IDOK, 205, 151, 60, 16, WS_TABSTOP
+END
+
+STRINGTABLE
+BEGIN
+ IDS_AUTO_CAPTION "Wine program crash"
+ IDS_INVALID_PARAMS "Internal errors - invalid parameters received"
+ IDS_UNIDENTIFIED "(unidentified)"
+END
diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c
index f5ea8f2..fb82a0c 100644
--- a/programs/winedbg/tgt_active.c
+++ b/programs/winedbg/tgt_active.c
@@ -27,6 +27,7 @@
#include "debugger.h"
#include "psapi.h"
+#include "resource.h"
#include "winternl.h"
#include "wine/debug.h"
#include "wine/exception.h"
@@ -45,9 +46,9 @@ static void dbg_init_current_thread(void* start)
{
if (start)
{
- if (dbg_curr_process->threads &&
+ if (dbg_curr_process->threads &&
!dbg_curr_process->threads->next && /* first thread ? */
- DBG_IVAR(BreakAllThreadsStartup))
+ DBG_IVAR(BreakAllThreadsStartup))
{
ADDRESS64 addr;
@@ -898,7 +899,16 @@ enum dbg_start dbg_active_auto(int argc, char* argv[])
/* auto mode */
argc--; argv++;
ds = dbg_active_attach(argc, argv);
- if (ds != start_ok) return ds;
+ if (ds != start_ok) {
+ msgbox_res_id(NULL, IDS_INVALID_PARAMS, IDS_AUTO_CAPTION, MB_OK);
+ return ds;
+ }
+ if (!display_crash_dialog()) {
+ dbg_init_console();
+ dbg_start_interactive(INVALID_HANDLE_VALUE);
+ return start_ok;
+ }
+
hFile = parser_generate_command_file("echo Modules:", "info share",
"echo Threads:", "info threads",
"backtrace", "detach", NULL);
diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c
index d1df695..c87a0da 100644
--- a/programs/winedbg/winedbg.c
+++ b/programs/winedbg/winedbg.c
@@ -556,8 +556,11 @@ static BOOL WINAPI ctrl_c_handler(DWORD dwCtrlType)
return FALSE;
}
-static void dbg_init_console(void)
+void dbg_init_console(void)
{
+ /* set the output handle */
+ dbg_houtput = GetStdHandle(STD_OUTPUT_HANDLE);
+
/* set our control-C handler */
SetConsoleCtrlHandler(ctrl_c_handler, TRUE);
@@ -587,6 +590,23 @@ static int dbg_winedbg_usage(BOOL advanced)
return -1;
}
+void dbg_start_interactive(HANDLE hFile)
+{
+ if (dbg_curr_process)
+ {
+ dbg_printf("WineDbg starting on pid %04x\n", dbg_curr_pid);
+ if (dbg_curr_process->active_debuggee) dbg_active_wait_for_first_exception();
+ }
+
+ dbg_interactiveP = TRUE;
+ parser_handle(hFile);
+
+ while (dbg_process_list)
+ dbg_process_list->process_io->close_process(dbg_process_list, FALSE);
+
+ dbg_save_internal_vars();
+}
+
struct backend_cpu* be_cpu;
#ifdef __i386__
extern struct backend_cpu be_i386;
@@ -698,19 +718,7 @@ int main(int argc, char** argv)
case start_error_init: return -1;
}
- if (dbg_curr_process)
- {
- dbg_printf("WineDbg starting on pid %04x\n", dbg_curr_pid);
- if (dbg_curr_process->active_debuggee) dbg_active_wait_for_first_exception();
- }
-
- dbg_interactiveP = TRUE;
- parser_handle(hFile);
-
- while (dbg_process_list)
- dbg_process_list->process_io->close_process(dbg_process_list, FALSE);
-
- dbg_save_internal_vars();
+ dbg_start_interactive(hFile);
return 0;
}
--
1.4.4.2
--------------090707070503050205060302--
More information about the wine-patches
mailing list