This software is designed to control older Agilent GC/MS systems which are no longer supported with newer versions of the same software.
Basically a few of the components are win16 apps and the others are win32. The win32 data analysis component (MSDA.EXE) runs OK on Wine 5.0-rc6 on Mac with no major issues other than that the file dialog not allowing you to select the application's 'files' which are actually directories. You can still type the name of the directory manually and it will load the contents correctly.
However, the configuration program (MSCONFIG.EXE) which is win16 crashes on startup.
Having resolved one issue with argument marshalling in win16-32 cross calling (see https://bugs.winehq.org/show_bug.cgi?id=48480) the program now starts but fails to display its menu bar.
The actual he GCMS control program (MSTOP.EXE) is also 16-bit and does not load its menus either, but this doesn’t crash on startup.
As both programs include an interpreter for Chemstation macros, the menus are dynamically programmable. The configuration file that controls the menus errors in a builtin routine called MENUEND. It appears the error handling is internally represented by structured exceptions.
Both programs exhibit the same issues when started with WINEDEBUG=+relay,+menu,+seh,+global.
Exceptions of the following form:
Code: Select all
002c:Ret KERNEL.19: GLOBALUNLOCK() retval=00000000 ret=12af:13ce ds=1336
002c:trace:global:GlobalHandle16 1017
002c:Call KERNEL.17: GLOBALFREE(16be) ret=12af:13d6 ds=1336
002c:trace:global:GlobalFree16 16be
002c:Call KERNEL32.HeapFree(00540000,00000000,005d3498) ret=6ab660cb
002c:Ret KERNEL32.HeapFree() retval=00000001 ret=6ab660cb
002c:Ret KERNEL.17: GLOBALFREE() retval=00000000 ret=12af:13d6 ds=1336
002c:trace:seh:raise_exception code=c0000005 flags=0 addr=0x6ab5e7c9 ip=6ab5e7c9 tid=002c
002c:trace:seh:raise_exception info[0]=00000000
002c:trace:seh:raise_exception info[1]=000016b8
002c:trace:seh:raise_exception eax=00000000 ebx=00000000 ecx=00000000 edx=16bf0000 esi=000002b6 edi=000046ce
002c:trace:seh:raise_exception ebp=00004b4a esp=0000452a cs=001b ds=1336 es=0023 fs=11cf gs=000f flags=00010202
When run in winedbg, I see the following:
Code: Select all
0038:err:thunk:K32WOWHandle16 handle 0x10072 of type 0 has non-zero HIWORD
First chance exception: page fault on read access to 0x000016b8 in 32-bit code (0x000000006b0147c9).
Register dump:
CS:001b SS:1337 DS:1336 ES:0023 FS:11cf GS:000f
EIP:6b0147c9 ESP:0000452a EBP:00004b4a EFLAGS:00010246( R- -- I Z- -P- )
EAX:00000000 EBX:00000000 ECX:00000000 EDX:16bf0000
ESI:000002b6 EDI:000046ce
Bad segment (4919)
Stack dump:
Backtrace:
=>0 0x000000006b0147c9 __wine_call_from_16+0x91() in krnl386.exe16 (0x0000000000000000)
0x000000006b0147c9 __wine_call_from_16+0x91 in krnl386.exe16: pop %es
It appears that the exception occurs in one of the automatically built thunks defined in winebuild. When tracing, this seems to be on return from GlobalFree16. It’s popping an invalid segment descriptor into DS just before the pop %es. This is segment 0x1337.
I think the err:thunk is irrelevant because the same error occurs in the working MSDA program, and doesn’t occur immediately adjacent to the exceptions.
The problem I am having is that I can’t figure out how to debug through the thunks and the following additional challenges apply:
The exception occurs only after certain GlobalFree16 calls, not all of them,
All the internal calls in GlobalFree16 (such as to HeapFree) appear to succeed.
Looking at the handle usage with +global, the handle 16be is allocated, locked and unlocked in what appears to be a valid sequence.
The exception occurs after calls to GLOBALFREE() with different handles- It’s not just one specific corrupt memory area or handle.
Can anybody suggest how I go about debugging this further?
Is the segment number 1337 significant? Or is a ‘leet’ segment descriptor just a coincidence?
Is this some sort of handle to segment descriptor conversion bug?