Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception in DOS #22

Open
sduensin opened this issue Oct 20, 2020 · 9 comments
Open

Exception in DOS #22

sduensin opened this issue Oct 20, 2020 · 9 comments

Comments

@sduensin
Copy link

Problem user here again. :-) This is the demo program from the TV C++ manual. Pressing F4 should open a window that displays a source file. Instead it throws an exception.

image

Pressing F4 should open a dialog but I get another exception:

image

I am able to pull down menus but that's it.

(To be sure it's not DOSBox, I also tried it in VirtualBox in an NT 4.0 command prompt.)

@magiblot
Copy link
Owner

magiblot commented Oct 20, 2020

Well, this is where it stops being funny. These are not C++ exceptions, but memory safety issues. DPMI32 executables are also unstable for me. I don't know if this is a memory issue in Turbo Vision that can be easily fixed, or if it's just a limitation of the DPMI32 model.

I'm not even sure this can be debugged with td32. Does DOSBox-X have a debugger? I wonder if it can help.

I also tried it in VirtualBox in an NT 4.0 command prompt.

Then it should be possible to debug with td32. Build Turbo Vision with -DDEBUG -DTVDEBUG; build your application with -v and link against TV32D.LIB. Run td32 in NT 4.0, and open your application from there. Then reproduce the issue and see if you can get any useful information.

This is the demo program from the TV C++ manual.

Did you copy it manually from the manual? The C++ manual was written for Turbo Vision 1.0, so the program could contain a bug. If you are familiar with Linux development and valgrind, you can try it there first.

My point is: as long as the program logic does not depend on DOS, it can be tested on a platform that's easier to debug for. I said Linux, but this is valid for Visual Studio as well.

@sduensin
Copy link
Author

Building my code against the Borland-supplied TV works. If nothing else, I can fall back to that for DOS.

The code I'm using is basically what is in the TV C++ manual but sanity checked against the tutorial code provided by this port:
https://github.com/set-soft/tvision/tree/master/tvision/examples/tutorial

I'll try to get a debugger going after I get some more TV under my belt. Right now I only know enough to be dangerous.

@Maxwelldoug
Copy link

Hey Sduensin. as far as I can tell, this port is closer to original then set-soft's (based on the readme anyways) I'll tell you the same on discord as well.

@magiblot
Copy link
Owner

magiblot commented Oct 20, 2020

Okay, I can reproduce. It seems that you can work around the issue by changing project/makefile as follows:

 !if $d(DOS32)
 # This is done in several variables to work around the 'Command arguments too 
-EXCLUDE2 = TVEXPOSD.CPP TVWRITE.ASM
+EXCLUDE2 = TVEXPOSD.CPP TVWRITE.CPP
 EXCLUDE1 = EDITS.ASM FRAMELIN.ASM TVCURSOR.ASM TGRMV.ASM TTPRVLNS.ASM
 !else

as far as I can tell, this port is closer to original then set-soft's (based on the readme anyways)

Yes, this is right. This port is backward-compatible, and most code that compiles for the original also compiles for this one.

@magiblot
Copy link
Owner

I recompiled Turbo Vision, and I can no longer reproduce. This is a serious issue, because I haven't changed a single line of code (not even the makefile suggestion above).

tvguid16.zip

@magiblot
Copy link
Owner

If you can reproduce the issue with a debug build, please share the binary.

@mooskagh
Copy link

Probably useless, but here are disassembles of the instructions with illegal memory access (typed from screenshots, disassembled at https://defuse.ca/online-x86-assembler.htm)

At least it's surely not the code in tvwrite.asm (no test (e)ax,(e)ax or clc there).

Raw Hex (zero bytes in bold):

45F88945C88B45C88810837B2E000F84   

String Literal:

"\x45\xF8\x89\x45\xC8\x8B\x45\xC8\x88\x10\x83\x7B\x2E\x00\x0F\x84"

Array Literal:

{ 0x45, 0xF8, 0x89, 0x45, 0xC8, 0x8B, 0x45, 0xC8, 0x88, 0x10, 0x83, 0x7B, 0x2E, 0x00, 0x0F, 0x84 }
Disassembly:

0:  45                      inc    ebp
1:  f8                      clc
2:  89 45 c8                mov    DWORD PTR [ebp-0x38],eax
5:  8b 45 c8                mov    eax,DWORD PTR [ebp-0x38]
8:  88 10                   mov    BYTE PTR [eax],dl         <--------- THIS
a:  83 7b 2e 00             cmp    DWORD PTR [ebx+0x2e],0x0
e:  0f                      .byte 0xf
f:  84                      .byte 0x84
Raw Hex (zero bytes in bold):

578B450885C0747F8B50FCF6C2017477   

String Literal:

"\x57\x8B\x45\x08\x85\xC0\x74\x7F\x8B\x50\xFC\xF6\xC2\x01\x74\x77"

Array Literal:

{ 0x57, 0x8B, 0x45, 0x08, 0x85, 0xC0, 0x74, 0x7F, 0x8B, 0x50, 0xFC, 0xF6, 0xC2, 0x01, 0x74, 0x77 }
Disassembly:

0:  57                      push   edi
1:  8b 45 08                mov    eax,DWORD PTR [ebp+0x8]
4:  85 c0                   test   eax,eax
6:  74 7f                   je     0x87
8:  8b 50 fc                mov    edx,DWORD PTR [eax-0x4]    <------- THIS
b:  f6 c2 01                test   dl,0x1
e:  74 77                   je     0x87

@mooskagh
Copy link

But it indeed does look like it overruns some buffer, and it's just a matter of luck whether memory allocator already allocated adjacent pages from OS (in that case it goes unnoticed) or not (in which case memory protection triggers).

@magiblot
Copy link
Owner

Hi @mooskagh, thanks for investigating. I was able to get a trace the first time I reproduced the issue, and it was something like this:

(most recent first)
memcpy
[...] // No debug symbols
TView::writeLine // implemented in tvwrite.cpp
[...] // No debug symbols

This made me suspect of tvwrite.cpp, which is the C++ translation of tvwrite.asm. Indeed, you can't see these instructions in tvwrite.asm because the default build uses the C++ version and my suggestion was to switch to the ASM one. But the issue could be really anywhere else.

But I absolutely wasn't expecting the issue to disappear after rebuilding. I cannot reproduce it anymore. So if anyone else can reproduce with a debug build, please share the binaries.

magiblot added a commit that referenced this issue Dec 24, 2020
I found this while investigating #22, but I doubt this is the cause of that issue, since the disassebly points out to a write instruction.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants