This serie implements a more robust strategy when winedbg attaches to process which tries to terminate. This let --auto mode print some more information (and no longer crash) in such situation. Revamped also a bit information displayed in auto mode.
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/winedbg/debugger.h | 1 + programs/winedbg/gdbproxy.c | 10 +++------- programs/winedbg/tgt_active.c | 4 +--- programs/winedbg/winedbg.c | 5 +++-- 4 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index 59c923c38ad..28fb788b3c7 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -280,6 +280,7 @@ struct dbg_process struct backend_cpu* be_cpu; HANDLE event_on_first_exception; BOOL active_debuggee; + BOOL is_wow64; struct dbg_breakpoint bp[MAX_BREAKPOINTS]; unsigned next_bp; struct dbg_delayed_bp* delayed_bp; diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c index 18e18289bee..238eecb1538 100644 --- a/programs/winedbg/gdbproxy.c +++ b/programs/winedbg/gdbproxy.c @@ -1685,7 +1685,6 @@ static BOOL CALLBACK packet_query_libraries_cb(PCSTR mod_name, DWORD64 base, PVO IMAGE_NT_HEADERS *nth = NULL; IMAGEHLP_MODULE64 mod; SIZE_T size, i; - BOOL is_wow64; char buffer[0x400];
mod.SizeOfStruct = sizeof(mod); @@ -1709,8 +1708,7 @@ static BOOL CALLBACK packet_query_libraries_cb(PCSTR mod_name, DWORD64 base, PVO
if ((unix_path = wine_get_unix_file_name(nt_name.Buffer))) { - if (IsWow64Process(gdbctx->process->handle, &is_wow64) && - is_wow64 && (tmp = strstr(unix_path, "system32"))) + if (gdbctx->process->is_wow64 && (tmp = strstr(unix_path, "system32"))) memcpy(tmp, "syswow64", 8); reply_buffer_append_xmlstr(reply, unix_path); } @@ -1743,7 +1741,7 @@ static BOOL CALLBACK packet_query_libraries_cb(PCSTR mod_name, DWORD64 base, PVO * the following computation valid in all cases. */ dos = (IMAGE_DOS_HEADER *)buffer; nth = (IMAGE_NT_HEADERS *)(buffer + dos->e_lfanew); - if (IsWow64Process(gdbctx->process->handle, &is_wow64) && is_wow64) + if (gdbctx->process->is_wow64) sec = IMAGE_FIRST_SECTION((IMAGE_NT_HEADERS32 *)nth); else sec = IMAGE_FIRST_SECTION((IMAGE_NT_HEADERS64 *)nth); @@ -1967,7 +1965,6 @@ static enum packet_return packet_query_exec_file(struct gdb_context* gdbctx) struct reply_buffer* reply = &gdbctx->qxfer_buffer; struct dbg_process* process = gdbctx->process; char *unix_path; - BOOL is_wow64; char *tmp;
if (!process) return packet_error; @@ -1978,8 +1975,7 @@ static enum packet_return packet_query_exec_file(struct gdb_context* gdbctx) if (!(unix_path = wine_get_unix_file_name(process->imageName))) return packet_reply_error(gdbctx, GetLastError() == ERROR_NOT_ENOUGH_MEMORY ? HOST_ENOMEM : HOST_ENOENT);
- if (IsWow64Process(process->handle, &is_wow64) && - is_wow64 && (tmp = strstr(unix_path, "system32"))) + if (process->is_wow64 && (tmp = strstr(unix_path, "system32"))) memcpy(tmp, "syswow64", 8);
reply_buffer_append_str(reply, unix_path); diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c index 0d5ae754af5..7a5d71d8909 100644 --- a/programs/winedbg/tgt_active.c +++ b/programs/winedbg/tgt_active.c @@ -869,15 +869,13 @@ static void output_system_info(void)
const char *(CDECL *wine_get_build_id)(void); void (CDECL *wine_get_host_version)( const char **sysname, const char **release ); - BOOL is_wow64;
wine_get_build_id = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_build_id"); wine_get_host_version = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_host_version"); - if (!IsWow64Process( dbg_curr_process->handle, &is_wow64 )) is_wow64 = FALSE;
dbg_printf( "System information:\n" ); if (wine_get_build_id) dbg_printf( " Wine build: %s\n", wine_get_build_id() ); - dbg_printf( " Platform: %s%s\n", platform, is_wow64 ? " (WOW64)" : "" ); + dbg_printf( " Platform: %s%s\n", platform, dbg_curr_process->is_wow64 ? " (WOW64)" : "" ); dbg_printf( " Version: Windows %s\n", get_windows_version() ); if (wine_get_host_version) { diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c index e7ba6afa2e4..438d4a3d94b 100644 --- a/programs/winedbg/winedbg.c +++ b/programs/winedbg/winedbg.c @@ -266,6 +266,8 @@ struct dbg_process* dbg_add_process(const struct be_process_io* pio, DWORD pid, if (!h) h = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
+ if (!IsWow64Process(h, &wow64)) wow64 = FALSE; + if (!(p = malloc(sizeof(struct dbg_process)))) return NULL; p->handle = h; p->pid = pid; @@ -276,6 +278,7 @@ struct dbg_process* dbg_add_process(const struct be_process_io* pio, DWORD pid, list_init(&p->modules); p->event_on_first_exception = NULL; p->active_debuggee = FALSE; + p->is_wow64 = wow64; p->next_bp = 1; /* breakpoint 0 is reserved for step-over */ memset(p->bp, 0, sizeof(p->bp)); p->delayed_bp = NULL; @@ -291,8 +294,6 @@ struct dbg_process* dbg_add_process(const struct be_process_io* pio, DWORD pid,
list_add_head(&dbg_process_list, &p->entry);
- IsWow64Process(h, &wow64); - #ifdef __i386__ p->be_cpu = &be_i386; #elif defined(__x86_64__)
From: Eric Pouech epouech@codeweavers.com
Letting the information displayed in '--auto' mode be available as a command. Simplify a bit the --auto mode handling.
Note: - the WOW64 status of the debuggee used to be printed in system information, which is a bit ackward as system info shouldn't be tied to a given process. - replaced it with supported guest machines (for the record, a 64-bit only setup incorrectly returns i386 as supported guest; I guess we shouldn't care). - now printing the wow64 status of a process when displaying an exception information instead.
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/winedbg/dbg.y | 3 +- programs/winedbg/debug.l | 1 + programs/winedbg/debugger.h | 1 + programs/winedbg/info.c | 108 +++++++++++++++++++++++++++++++++- programs/winedbg/tgt_active.c | 97 ++---------------------------- 5 files changed, 115 insertions(+), 95 deletions(-)
diff --git a/programs/winedbg/dbg.y b/programs/winedbg/dbg.y index a7336c34206..fc9a2977041 100644 --- a/programs/winedbg/dbg.y +++ b/programs/winedbg/dbg.y @@ -53,7 +53,7 @@ static void parser(const char*); %token tABORT tECHO %token tCLASS tMAPS tSTACK tSEGMENTS tSYMBOL tREGS tALLREGS tWND tLOCAL tEXCEPTION %token tPROCESS tTHREAD tEOL tEOF -%token tFRAME tSHARE tMODULE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE +%token tFRAME tSHARE tMODULE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE tSYSTEM %token tSTEPI tNEXTI tFINISH tSHOW tDIR tWHATIS tSOURCE %token <string> tPATH tIDENTIFIER tSTRING tINTVAR %token <integer> tNUM tFORMAT @@ -292,6 +292,7 @@ info_command: | tINFO tMAPS { info_win32_virtual(dbg_curr_pid); } | tINFO tMAPS expr_rvalue { info_win32_virtual($3); } | tINFO tEXCEPTION { info_win32_exception(); } + | tINFO tSYSTEM { info_win32_system(); } ;
maintenance_command: diff --git a/programs/winedbg/debug.l b/programs/winedbg/debug.l index 0b76ba74329..dd7fb0db76f 100644 --- a/programs/winedbg/debug.l +++ b/programs/winedbg/debug.l @@ -245,6 +245,7 @@ STRING "(\[^\n]|[^\"\n])*" <INFO_CMD>symbol|symbo|symb|sym { BEGIN(ASTRING_EXPECTED); return tSYMBOL; } <INFO_CMD>maps|map { return tMAPS; } <INFO_CMD>window|windo|wind|win|wnd { return tWND; } +<INFO_CMD>system|syst|sys { return tSYSTEM; } <HELP_CMD>info|inf|in { return tINFO; } <MAINT_CMD>type { return tTYPE; }
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index 28fb788b3c7..c65b9bfae67 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -394,6 +394,7 @@ extern void info_win32_frame_exceptions(DWORD tid); extern void info_win32_virtual(DWORD pid); extern void info_win32_segments(DWORD start, int length); extern void info_win32_exception(void); +extern void info_win32_system(void); extern void info_wine_dbg_channel(BOOL add, const char* chnl, const char* name); extern WCHAR* fetch_thread_description(DWORD tid);
diff --git a/programs/winedbg/info.c b/programs/winedbg/info.c index 6ffcf99392a..251b92c607b 100644 --- a/programs/winedbg/info.c +++ b/programs/winedbg/info.c @@ -1078,7 +1078,8 @@ void info_win32_exception(void) switch (addr.Mode) { case AddrModeFlat: - dbg_printf(" in %ld-bit code (%s)", + dbg_printf(" in %s%ld-bit code (%s)", + dbg_curr_process->is_wow64 ? "wow64 " : "", dbg_curr_process->be_cpu->pointer_size * 8, memory_offset_to_string(hexbuf, addr.Offset, 0)); break; @@ -1095,3 +1096,108 @@ void info_win32_exception(void) } dbg_printf(".\n"); } + +static const struct +{ + int type; + int platform; + int major; + int minor; + const char *str; +} +version_table[] = +{ + { 0, VER_PLATFORM_WIN32s, 2, 0, "2.0" }, + { 0, VER_PLATFORM_WIN32s, 3, 0, "3.0" }, + { 0, VER_PLATFORM_WIN32s, 3, 10, "3.1" }, + { 0, VER_PLATFORM_WIN32_WINDOWS, 4, 0, "95" }, + { 0, VER_PLATFORM_WIN32_WINDOWS, 4, 10, "98" }, + { 0, VER_PLATFORM_WIN32_WINDOWS, 4, 90, "ME" }, + { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 3, 51, "NT 3.51" }, + { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 4, 0, "NT 4.0" }, + { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 5, 0, "2000" }, + { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 5, 1, "XP" }, + { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 5, 2, "XP" }, + { VER_NT_SERVER, VER_PLATFORM_WIN32_NT, 5, 2, "Server 2003" }, + { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 6, 0, "Vista" }, + { VER_NT_SERVER, VER_PLATFORM_WIN32_NT, 6, 0, "Server 2008" }, + { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 6, 1, "7" }, + { VER_NT_SERVER, VER_PLATFORM_WIN32_NT, 6, 1, "Server 2008 R2" }, + { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 6, 2, "8" }, + { VER_NT_SERVER, VER_PLATFORM_WIN32_NT, 6, 2, "Server 2012" }, + { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 6, 3, "8.1" }, + { VER_NT_SERVER, VER_PLATFORM_WIN32_NT, 6, 3, "Server 2012 R2" }, + { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 10, 0, "10" }, +}; + +static const char *get_windows_version(void) +{ + RTL_OSVERSIONINFOEXW info = { sizeof(RTL_OSVERSIONINFOEXW) }; + static char str[64]; + int i; + + RtlGetVersion( &info ); + + for (i = 0; i < ARRAY_SIZE(version_table); i++) + { + if (version_table[i].type == info.wProductType && + version_table[i].platform == info.dwPlatformId && + version_table[i].major == info.dwMajorVersion && + version_table[i].minor == info.dwMinorVersion) + { + return version_table[i].str; + } + } + + snprintf( str, sizeof(str), "%ld.%ld (%d)", info.dwMajorVersion, + info.dwMinorVersion, info.wProductType ); + return str; +} + +static BOOL is_guest(USHORT native, USHORT guest) +{ + BOOLEAN supported; + + return native != guest && !RtlWow64IsWowGuestMachineSupported(guest, &supported) && supported; +} + +void info_win32_system(void) +{ + USHORT current, native; + int i, count; + + const char *(CDECL *wine_get_build_id)(void); + void (CDECL *wine_get_host_version)( const char **sysname, const char **release ); + + static USHORT guest_machines[] = + { + IMAGE_FILE_MACHINE_I386, IMAGE_FILE_MACHINE_ARM, IMAGE_FILE_MACHINE_ARMNT, + }; + + wine_get_build_id = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_build_id"); + wine_get_host_version = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_host_version"); + + RtlWow64GetProcessMachines( GetCurrentProcess(), ¤t, &native ); + + dbg_printf( "System information:\n" ); + if (wine_get_build_id) dbg_printf( " Wine build: %s\n", wine_get_build_id() ); + dbg_printf( " Platform: %s", get_machine_str(native)); + for (count = i = 0; i < ARRAY_SIZE(guest_machines); i++) + { + if (is_guest(native, guest_machines[i])) + { + if (!count++) dbg_printf(" (guest:"); + dbg_printf(" %s", get_machine_str(guest_machines[i])); + } + } + dbg_printf("%s\n", count ? ")" : ""); + + dbg_printf( " Version: Windows %s\n", get_windows_version() ); + if (wine_get_host_version) + { + const char *sysname, *release; + wine_get_host_version( &sysname, &release ); + dbg_printf( " Host system: %s\n", sysname ); + dbg_printf( " Host version: %s\n", release ); + } +} diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c index 7a5d71d8909..a339a586eca 100644 --- a/programs/winedbg/tgt_active.c +++ b/programs/winedbg/tgt_active.c @@ -796,96 +796,6 @@ static HANDLE create_temp_file(void) NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0 ); }
-static const struct -{ - int type; - int platform; - int major; - int minor; - const char *str; -} -version_table[] = -{ - { 0, VER_PLATFORM_WIN32s, 2, 0, "2.0" }, - { 0, VER_PLATFORM_WIN32s, 3, 0, "3.0" }, - { 0, VER_PLATFORM_WIN32s, 3, 10, "3.1" }, - { 0, VER_PLATFORM_WIN32_WINDOWS, 4, 0, "95" }, - { 0, VER_PLATFORM_WIN32_WINDOWS, 4, 10, "98" }, - { 0, VER_PLATFORM_WIN32_WINDOWS, 4, 90, "ME" }, - { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 3, 51, "NT 3.51" }, - { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 4, 0, "NT 4.0" }, - { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 5, 0, "2000" }, - { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 5, 1, "XP" }, - { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 5, 2, "XP" }, - { VER_NT_SERVER, VER_PLATFORM_WIN32_NT, 5, 2, "Server 2003" }, - { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 6, 0, "Vista" }, - { VER_NT_SERVER, VER_PLATFORM_WIN32_NT, 6, 0, "Server 2008" }, - { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 6, 1, "7" }, - { VER_NT_SERVER, VER_PLATFORM_WIN32_NT, 6, 1, "Server 2008 R2" }, - { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 6, 2, "8" }, - { VER_NT_SERVER, VER_PLATFORM_WIN32_NT, 6, 2, "Server 2012" }, - { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 6, 3, "8.1" }, - { VER_NT_SERVER, VER_PLATFORM_WIN32_NT, 6, 3, "Server 2012 R2" }, - { VER_NT_WORKSTATION, VER_PLATFORM_WIN32_NT, 10, 0, "10" }, -}; - -static const char *get_windows_version(void) -{ - RTL_OSVERSIONINFOEXW info = { sizeof(RTL_OSVERSIONINFOEXW) }; - static char str[64]; - int i; - - RtlGetVersion( &info ); - - for (i = 0; i < ARRAY_SIZE(version_table); i++) - { - if (version_table[i].type == info.wProductType && - version_table[i].platform == info.dwPlatformId && - version_table[i].major == info.dwMajorVersion && - version_table[i].minor == info.dwMinorVersion) - { - return version_table[i].str; - } - } - - snprintf( str, sizeof(str), "%ld.%ld (%d)", info.dwMajorVersion, - info.dwMinorVersion, info.wProductType ); - return str; -} - -static void output_system_info(void) -{ -#ifdef __i386__ - static const char platform[] = "i386"; -#elif defined(__x86_64__) - static const char platform[] = "x86_64"; -#elif defined(__arm__) - static const char platform[] = "arm"; -#elif defined(__aarch64__) - static const char platform[] = "arm64"; -#else -# error CPU unknown -#endif - - const char *(CDECL *wine_get_build_id)(void); - void (CDECL *wine_get_host_version)( const char **sysname, const char **release ); - - wine_get_build_id = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_build_id"); - wine_get_host_version = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_host_version"); - - dbg_printf( "System information:\n" ); - if (wine_get_build_id) dbg_printf( " Wine build: %s\n", wine_get_build_id() ); - dbg_printf( " Platform: %s%s\n", platform, dbg_curr_process->is_wow64 ? " (WOW64)" : "" ); - dbg_printf( " Version: Windows %s\n", get_windows_version() ); - if (wine_get_host_version) - { - const char *sysname, *release; - wine_get_host_version( &sysname, &release ); - dbg_printf( " Host system: %s\n", sysname ); - dbg_printf( " Host version: %s\n", release ); - } -} - /****************************************************************** * dbg_active_attach * @@ -978,7 +888,10 @@ enum dbg_start dbg_active_auto(int argc, char* argv[]) }
input = parser_generate_command_file("echo Modules:", "info share", - "echo Threads:", "info threads", NULL); + "echo Threads:", "info threads", + "info system", + "detach", + NULL); if (input == INVALID_HANDLE_VALUE) return start_error_parse;
if (dbg_curr_process->active_debuggee) @@ -986,7 +899,6 @@ enum dbg_start dbg_active_auto(int argc, char* argv[])
dbg_interactiveP = TRUE; parser_handle(NULL, input); - output_system_info();
if (output != INVALID_HANDLE_VALUE) { @@ -998,7 +910,6 @@ enum dbg_start dbg_active_auto(int argc, char* argv[]) }
CloseHandle( input ); - dbg_curr_process->process_io->close_process(dbg_curr_process, TRUE); return start_ok; }
From: Eric Pouech epouech@codeweavers.com
When a crash in a program happens, and the debugger in launched in --auto mode, in some cases the program terminates before the debugger has gotten proper context on debuggee. (Could be a watchdog in programs checking if it's debugged and terminating itself if so).
Detect debuggee termination and still provide some information on debuggee (threads, modules, system info). The backtrace will not be available as no exception is gotten from debuggee.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55187
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/winedbg/tgt_active.c | 39 +++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-)
diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c index a339a586eca..5ac9a4d1229 100644 --- a/programs/winedbg/tgt_active.c +++ b/programs/winedbg/tgt_active.c @@ -597,6 +597,26 @@ void dbg_active_wait_for_first_exception(void) wait_exception(); }
+static BOOL dbg_active_wait_for_startup(DEBUG_EVENT* de) +{ + dbg_interactiveP = FALSE; + while (dbg_num_processes() && WaitForDebugEvent(de, INFINITE)) + { + switch (de->dwDebugEventCode) + { + case CREATE_PROCESS_DEBUG_EVENT: + case CREATE_THREAD_DEBUG_EVENT: + case LOAD_DLL_DEBUG_EVENT: + case EXCEPTION_DEBUG_EVENT: + if (dbg_handle_debug_event(de)) return TRUE; + break; + default: + return FALSE; + } + } + return FALSE; +} + static BOOL dbg_start_debuggee(LPSTR cmdLine) { PROCESS_INFORMATION info; @@ -862,6 +882,8 @@ enum dbg_start dbg_active_auto(int argc, char* argv[]) { HANDLE thread = 0, event = 0, input, output = INVALID_HANDLE_VALUE; enum dbg_start ds = start_error_parse; + BOOL first_exception = TRUE; + DEBUG_EVENT de;
DBG_IVAR(BreakOnDllLoad) = 0;
@@ -894,12 +916,25 @@ enum dbg_start dbg_active_auto(int argc, char* argv[]) NULL); if (input == INVALID_HANDLE_VALUE) return start_error_parse;
- if (dbg_curr_process->active_debuggee) - dbg_active_wait_for_first_exception(); + /* debuggee can terminate before we get the first exception. + * so detect end of attach load sequence, and then print information. + */ + if (dbg_curr_process->active_debuggee && !(first_exception = dbg_active_wait_for_startup(&de))) + { + dbg_printf("Couldn't get first exception for process %04lx %ls%s.\n" + "No backtrace available\n", + dbg_curr_pid, dbg_curr_process->imageName, dbg_curr_process->is_wow64 ? " (WOW64)" : ""); + }
dbg_interactiveP = TRUE; parser_handle(NULL, input);
+ if (!first_exception) + { + /* continue managing debug events, in case the exception event comes after current debug event */ + ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE); + dbg_active_wait_for_first_exception(); + } if (output != INVALID_HANDLE_VALUE) { SetEvent( event );
This merge request was approved by Rémi Bernon.
Rémi Bernon (@rbernon) commented about programs/winedbg/info.c:
- wine_get_host_version = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_host_version");
- RtlWow64GetProcessMachines( GetCurrentProcess(), ¤t, &native );
- dbg_printf( "System information:\n" );
- if (wine_get_build_id) dbg_printf( " Wine build: %s\n", wine_get_build_id() );
- dbg_printf( " Platform: %s", get_machine_str(native));
- for (count = i = 0; i < ARRAY_SIZE(guest_machines); i++)
- {
if (is_guest(native, guest_machines[i]))
{
if (!count++) dbg_printf(" (guest:");
dbg_printf(" %s", get_machine_str(guest_machines[i]));
}
- }
- dbg_printf("%s\n", count ? ")" : "");
Fwiw I think it's best to move code around without modification (except maybe stylistic) first, then make some logic changes, otherwise it's hard to tell if something and what has changed.