I tried to run some DOS games with wine recently and since most of them crashed with a page fault I tried to find out why and so, examining the last function calls before faulting revealed that when __wine_enter_vm86 in signal_i386.c returns from res = vm86_enter(...) and encounters a VM86TYPE(res) == VM86_UNKNOWN it calls the raise_segv_exception, which in turn calls NtSetContextThread. This one calls set_cpu_context which tries to reload the context of the VM86 thread an, of course, crashes since it can't load the segment registers with invalid (non GDT) values.
Backtrace: =>1 0x7efe2a57 in ntdll (+0x52a57) (0x7d55e348) 2 0x7efd9a8d NtSetContextThread+0x77() in ntdll (0x7d55e478) 3 0x7efd412e in ntdll (+0x4412e) (0x7d55e498) 4 0x7efd5032 __wine_enter_vm86+0x1d6() in ntdll (0x7d55e608) 5 0x7eeb9b15 K32WOWCallback16Ex+0x417() in kernel32 (0x7d55e668) fixme:dbghelp_dwarf:dwarf2_parse_variable Unsupported constant max_clusters in function fixme:dbghelp_dwarf:dwarf2_parse_variable Unsupported constant max_sectors_per_cluster in function fixme:dbghelp_dwarf:dwarf2_parse_variable Unsupported constant max_bytes_per_sector in function 6 0x7d6f50bb DOSVM_Enter+0xab(context=0x7d55e760) [/home/chr/WINE/CVS_BUILD/dlls/winedos/dosvm.c:586] in winedos (0x7d55e748) 7 0x7d71254b MZ_DOSVM+0xbb(lpExtra=0x0) [/home/chr/WINE/CVS_BUILD/dlls/winedos/module.c:638] in winedos (0x7d55ea48) 8 0x7eeacdf6 in kernel32 (+0x6cdf6) (0x7d55eb28) 9 0x7efd9939 in ntdll (+0x49939) (0x7d55f448) 10 0xb7de1512 start_thread+0x84() in libpthread.so.0 (0x7d55f4d8) 11 0xb7d7afde __clone+0x5e() in libc.so.6 (0x00000000) 0x7efe2a57: pop %es
My question, is this a bug, and, if so, what should be done to correct it? Is it sufficient to just make raise_segv_exception return if context->Eflags indicate VM86 instead of calling NtSetContextThread ?
In my example (Realms of Arkania: Blade of Destiny) this lets the app continue and I get the initial text box to select difficulty level. But ... the process doesn't handle any input - events are queued but never handled p.e. by DOSVM_Wait or similar ...
Unfortunately I don't know much about this stuff ... what procedure is responsible to handle these asynchronous events and when ?