5

I have an application that I compile for 32-bit DOS/DPMI target (with DOS32/A extender) using OpenWatcom classic (1.9 - latest stable release). If the program crashes on a bad memory access, I get the CS:EIP of the faulting instruction. How can I map this to assembly code / source line number? (Note: I am using the Windows version of OpenWatcom under Wine (running in Linux) and then run the executable in DosBox.)

With GCC/binutils I'd compile with -ggdb and then use objdump -DS on the executable to get both assembly and source view. Any OpenWatcom equivalent? Or, maybe, an interactive debugger that can do the same? I tried using wdis, but that only works on object files, not on executables. Since with the object file I cannot tell where it will be relocated to, it's useless. Or maybe there's at least a way to produce the symbol map for the executable?

1 Answers1

0

Note that DOSBox does not fully emulate the CPU, especially with regards to protected-mode debugging support. So if you want to debug a DOS protected-mode executable you need to use a VM or some other emulator.

That said, you can do the following.

Make sure you have these environment variables set (assuming that the development tools path is C:\WATCOM):

SET PATH=C:\WATCOM\BINW;%PATH%
SET INCLUDE=C:\WATCOM\H
SET WATCOM=C:\WATCOM
SET EDPATH=C:\WATCOM\EDDAT
SET WD=/TR#RSI/SWAP

WD is the one that specifies the default options for DOS Watcom Debugger:

  • the /TR#RSI flag specifies that the executable uses the DOS/4G DOS extender
  • /SWAP specifies that video memory swap is done using a single page, it is mandatory if you are developing a graphics application.

As far as I know WD does not support the DOS32/A DOS extender, so you may decide to use DOS/4G.

Be sure to specify the -d2 flag for the compiler (wcc386) and debug all for the linker (wlink).

Example makefile:

LINK_FLAGS_DBG = debug all SYS dos4g op m op maxe=25 op q op symf

CC = wcc386
CC_FLAGS_DBG = -i=C:\WATCOM\H -w4 -e25 -zq -otexan -d2 -5s -bt=dos -mf

OBJS = test.obj

test.exe : $(OBJS) test.lnk
    wlink $(LINK_FLAGS_DBG) @$^*
    
test.lnk : $(OBJS)
    echo NAME $^& >$^@
    echo DEBUG all >>>>$^@
    for %i in ($(OBJS)) do echo FILE %i >>$^@
    
clean :
    del *.obj
    del *.exe
    del *.lnk
    del *.map
    del *.sym

.c.obj : .AUTODEPEND
    $(CC) $[* $(CC_FLAGS_DBG)

test.c file:

#include <stdio.h>

void main(int argc, char *argv[]) {
    int test = 1234;

    printf("Hello world!\ntest is %d", test);
}

Build the executable (and symbols and map files) with:

wmake

Launch the Watcom DOS Debugger with:

wd test

You should be on this screen:

enter image description here

From here you can debug your program interactively, like with modern debuggers.

As a side notes:

  • refer to the documentation, although I only installed the DOS tools, it is very accurate and complete
  • note that knowing the address of the faulting instruction is not the same as knowing why that instruction crashed the program, which is why I invited you to use (maybe temporarily) DOS/4G and Watcom Debugger.
Marco Sacchi
  • 712
  • 6
  • 21