Debugging crashed 32-bit DOS executable compiled with OpenWatcom - c

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?

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:
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.

Related

GDB cannot step into function, OZone can

I have a setup like this:
GDB from "GNU Arm Embedded Toolchain" 10.3-2021.10
GDB server from "Segger JLink" 7.54d
JLink Ultra+ connected to my PC and my embedded device
Arm Compiler 6.15
I'm having problems stepping into a certain function from a C module (let's call it "F1"). When trying, I get the error message
Single stepping until exit from function "F1", which has no line number information.
If I use Segger Ozone, with the same .elf file, stepping into "F1" works fine.
I've tried to narrow down the problem and have the following observations:
A single line of code from the C module holding "F1" makes the difference. If I remove this line, it works. This line is a simple incrementation (++) of a static uint32_t variable and it is in a separate function (i.e. not "F1").
If I don't link with "--inline" option, it stops working - even with the "fix" in (1)
All source files (a mix of C and C++ files) are compiled with -g option.
I may try to reproduce it in a much smaller context which I could share here but until then, I'm hoping for some hints.
Anything is appreciated.
[Update 2021-11-10] Tried with older/newer versions of "GNU Arm Embedded Toolchain" as well as "Segger JLink". Same problem.
[Update 2021-11-10] Compiler/linker command used:
armclang -g --target=arm-arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=soft -MMD -Werror -D__STDC_LIMIT_MACROS -I<my_include_paths>
armlink --inline --info=sizes --info=veneers --info=unused --info=totals --map --symbols --scatter=<my_scatter_file> --list=list.txt

How to compile C program in GCC to enable debug in WinDbg?

I compile such code by GCC (v7.1.0) (command line below).
int func()
{
return 0x1234;
}
int main()
{
func();
return 0;
}
gcc .\001_simpleMain.c -O0 -m64 -g
After compilation I run WinDbg (10.0), open executable (Ctrl+E), program is loading. Breakpoint is hit on start process everthing is ok.
After it I want to open source code (Ctrl+O) and try to put breakpoint inside func method.
WinDlg tells me:
*** ERROR: Module load completed but symbols could not be loaded for G:\Examples\Gcc\a.exe
Why it is not working? Should I change compilation param? MY CPU is AMD64
Since you're using Windows with WinDbg you need the proprietary PDB files, which contain the debugging information for debugger tools that come from Microsoft.
GCC will generate debugging information that can be used by the gdb debugger (well known in Linux) for example.
gcc -g:
Produce debugging information in the operating system’s native format (stabs, COFF, XCOFF, or DWARF). GDB can work with this debugging information.
If you are using MinGW or Cygwin already you can use gdb from there because it's available in the MinGW/Cygwin environment. If not there are several gdb implemenations for Windows available.
Once you have built debugging files according to #Andre Kampling's instructions, you'll first need to convert them into PDB format. But even then, WinDbg will likely still not find them.
The executable has some data which points to the PDB file. Since you built in on Linux, that will be a Linux path which is not available on your Windows system.
Therefore, you need to set up your symbol path correctly so that WinDbg knows where you put them.
Basically you'll need
0:000> .symfix c:\symbols
for the Microsoft symbols and
0:000> .sympath+ c:\path\to\your\symbols
and then instruct WinDbg to load them again
0:000> .reload /f
0:000> ld*

Problems with linking a library with a c program in linux

I want to run serial commands from a Bealgebone to a 4Dsystems display. Therefore I copied the c library found here into a directory and created a test program main.c:
#include "Picaso_const4D.h"
#include "Picaso_Serial_4DLibrary.h"
int main(int argc,char *argv[])
{
OpenComm("/dev/ttyUSB0", B115200); // Matches with the display "Comms" rate
gfx_BGcolour(0xFFFF);
gfx_Cls();
gfx_CircleFilled(120,160,80,BLUE);
while (1) {}
}
Now when I do gcc -o main main.c its says
main.c:2:37: fatal error: Picaso_Serial_4DLibrary.h: No such file or
directory
So I try linking it:
gcc main.c -L. -lPICASO_SERIAL_4DLIBRARY
which gives me the same error. Then I tried to create a static library:
gcc -Wall -g -c -o PICASO_SERIAL_4DLIBRARY PICASO_SERIAL_4DLIBRARY.C
which gives me this:
PICASO_SERIAL_4DLIBRARY.C:1:21: fatal error: windows.h: No such file
or directory compilation terminated.
What am I doing wrong? the git page clearly says this library is created for people who do not run windows.
Thanks in advance!
You're not getting a linker error; you're getting a preprocessor error. Specifically, your preprocessor can't find Picaso_Serial_4DLibrary.h. Make sure that it's in your include path; you can add directories to your include path using the -I argument to gcc.
You've had two problems. First was the picaso_whatever.h file that couldn't be found. You fixed that with the -I you added. But, now, the picaso.h wants windows.h
What are you building on? WinX or BSD/Linux?
If you're compiling on WinX, you need to install the "platform sdk" for visual studio.
If you're using mingw or cygwin, you need to do something else.
If on WinX, cd to the C: directory. Do find . -type f -name windows.h and add a -I for the containing directory.
If under Linux, repeat the find at the source tree top level. Otherwise, there is probably some compatibility cross-build library that you need to install.
Or, you'll have to find WinX that has it as Picaso clearly includes it. You could try commenting out one or more of the #include's for it and see if things are better or worse.
If you can't find a real one, create an empty windows.h and add -I to it and see how bad [or good] things are.
You may need the mingw cross-compiler. See https://forums.wxwidgets.org/viewtopic.php?t=7729
UPDATE:
Okay ... Wow ... You are on the right track and close, but this is, IMO, ugly WinX stuff.
The primary need of Picaso is getting a serial comm port connection, so the need from within windows.h is [thankfully] minimal. It needs basic boilerplate definitions for WORD, DWORD, etc.
mingw or cygwin will provide their own copies of windows.h. These are "clean room" reimplementations, so no copyright issues.
mingw is a collection of compile/build tools that let you use gcc/ld/make build utilities.
cygwin is more like: I'd like a complete shell-like environment similar to BSD/Linux. You get bash, ls, gcc, tar, and just about any GNU utility you want.
Caveat: I use cygwin, but have never used mingw. The mingw version of windows.h [and a suite of .h files that it includes underneath], being open source, can be reused by other projects (e.g. cygwin, wine).
Under Linux, wine (windows emulator) is a program/suite that attempts to allow you to run WinX binaries under Linux (e.g. wine mywinpgm).
I git cloned the Picaso library and after some fiddling, I was able to get it to compile after pointing it to wine's version of windows.h
Picaso's OpenComm is doing CreateFile [a win32 API call]. So, you'll probably need cygwin. You're opening /dev/ttyUSB0. /dev/* implies cygwin. But, /dev/ttyUSB0 is a Linux-like name. You may need some WinX-style name like "COM:" or whatever. Under the cygwin terminal [which gives you a bash prompt], do ls /dev and see what's available.
You can get cygwin from: http://cygwin.com/ If you have a 64 bit system, be sure to use the 64 bit version of the installer: setup-x86_64.exe It's semi-graphical and will want two directories, one for the "root" FS and one to store packages. On my system, I use C:\cygwin64 and C:\cygwin64_packages--YMMV.
Note that the installer won't install gcc by default. You can [graphically] select which packages to install. You may also need some "devel" packages. They have libraries and .h files that a non-developer wouldn't need. As, docs mention, you can rerun the installer as often as you need. You can add packages that you forgot to specify or even remove ones that you installed that you don't need anymore.
Remember that you'll need to adjust makefile -I and/or -L option appropriately. Also, when building the picaso library, gcc generated a ton of warnings about overflow of a "large integer". The code was doing:
#define control_code -279
unsigned char buf[2];
buf[0] = control_code >> 8;
buf[1] = control_code;
The code is okay, and the warning is correct [because the code is sloppy]. If the code had done:
#define control_code -279
unsigned char buf[2];
buf[0] = (unsigned) control_code >> 8;
buf[1] = (unsigned) control_code;
it probably would have been silent. Use -Wno-overflow in your Makefile to get rid of the warnings rather that edit 50 or so lines

Use GCC as the Default MEX Compiler for MATLAB 2014a on a 64 bit Windows 7 machine

I am looking for a simple way to compile Unix MEX files on a Windows 7 computer.
The MEX files compile smoothly in MATLAB 2014a on Mac OS X 10.9 (using "XCode with Clang" as the compiler). Some of the people that I work with, however, are having trouble compiling them in Windows 7 using the C compiler from the Windows 7.1 SDK.
I understand that I might be able to avoid these errors if I use GCC to compile MEX files in MATLAB. I am wondering if anyone knows how. I am happy to download and edit whatever files are necessary so that I can a) compile MEX files within MATLAB by using the "MEX" command and b) guarantee that "-I" and "-L" instructions will also passed to the MEX compiler.
Note, my issue is very similar to this post from 2+ years ago. That said, I have put up a new post since a) MATLAB/MinGW/MEX have all had significant updates since then (not even sure if MinGW is the easiest way out of this mess); b) there is a 64 bit thing (not sure if it's a problem) and c) the "-I" and "-L" options are important.
Start by downloading MinGW-w64 compiler toolchain. We'll be using the x64 version. Here's the link to the latest binaries as of this moment (GNU GCC 4.9.1).
Extract the 7z archive to some location (preferably without spaces), say C:\MinGW-w64\mingw64.
Add the bin folder to your PATH environment variable, so something like set PATH=C:\MinGW-w64\mingw64\bin;%PATH% but do it system-wide.
Create the following file (feel free to add compiler switches like -std=c++11 if you want C++11 support):
mexopts_mingw64.bat
#echo off
set MATLAB=%MATLAB%
set MW_TARGET_ARCH=win64
set MINGWROOT=C:\MinGW-w64\mingw64
set PATH=%MINGWROOT%\bin;%PATH%
set COMPILER=x86_64-w64-mingw32-g++
set COMPFLAGS=-c -m64 -mwin32 -mdll -Wall -DMATLAB_MEX_FILE
set OPTIMFLAGS=-DNDEBUG -O2
set DEBUGFLAGS=-g
set NAME_OBJECT=-o
set LINKER=x86_64-w64-mingw32-g++
set LIBLOC=%MATLAB%\extern\lib\%MW_TARGET_ARCH%\microsoft
set LINKFLAGS=-shared -L"%LIBLOC%" -L"%MATLAB%\bin\%MW_TARGET_ARCH%"
set LINKFLAGSPOST=-lmx -lmex -lmat
set LINKOPTIMFLAGS=-O2
set LINKDEBUGFLAGS=-g
set LINK_FILE=
set LINK_LIB=
set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
set RC_COMPILER=
set RC_LINKER=
Now we use it to compile a sample MEX-file:
>> mex -f mexopts_mingw64.bat -v -largeArrayDims "C:\Program Files\MATLAB\R2014a\extern\examples\mex\yprime.c"
>> yprime(1,1:4)
ans =
2.0000 8.9685 4.0000 -1.0947
Note: If you are compiling C++ code and you want to distribute the binaries to other people, you might need to also include a couple of DLL files from MinGW which will be dependencies for the compiled MEX-file (stuff like libstdc++). Use Dependency Walker tool to list them all.

gcc on Windows: generated "a.exe" file vanishes

I'm using GCC version 4.7.1, but I've also tried this on GCC 4.8. Here is the code I'm trying to compile:
#include <stdio.h>
void print(int amount) {
int i;
for (i = 0; i < 5; i++) {
printf("%d", i);
}
}
int main(int argc, char** argv) {
print(5);
return 0;
}
It looks like it should work, and when I compile with...
gcc main.c
It takes a while to compile, produces an a.exe file and the the a.exe file disappears. It isn't giving me any errors with my code.
Here's a gif of proof, as some people are misinterpreting this:
(Since ahoffer's deleted answer isn't quite correct, I'll post this, based on information in the comments.)
On Windows, gcc generates an executable named a.exe by default. (On UNIX-like systems, the default name, for historical reasons, is a.out.) Normally you'd specify a name using the -o option.
Apparently the generated a.exe file generates a false positive match in your antivirus software, so the file is automatically deleted shortly after it's created. I see you've already contacted the developers of Avast about this false positive.
Note that antivirus programs typically check the contents of a file, not its name, so generating the file with a name other than a.exe won't help. Making some changes to the program might change the contents of the executable enough to avoid the problem, though.
You might try compiling a simple "hello, world" program to see if the same thing happens.
Thanks to Chrono Kitsune for linking to this relevant Mingw-users discussion in a comment.
This is not relevant to your problem, but you should print a newline ('\n') at the end of your program's output. It probably doesn't matter much in your Windows environment, but in general a program's standard output should (almost) always have a newline character at the end of its last line.
Try to compile with gcc but without all standard libraries using a command like this:
gcc -nostdlib -c test.c -o test.o; gcc test.o -lgcc -o test.exe
One of the mingw libraries binary must generate a false positive, knowing which library would be useful.
There is no issue with your code it is just exiting properly.
You have to run it in the command line which will show you all the info.
start->run->cmd, then cd to your directory. then a.exe. If you don't want to do that you can add a sleep() before the return in main.
More over, in your code when you pass print(5) to your function it's not being used.
I confirm is due to Antivirus.
I did this test:
compile helloworld.c at t=0;
within 1 second tell McAfee not consider helloworld.exe a threat. >> the file is still there
If I am too slow, the file will be deleted.
If suppose you get the error near a.exe while running the file ,
Theen follow the below steps:
1.open virus & threat protection
2.there select manage settings in virus & threat protection settings
3.there is real time protection and cloud delivered protection is in ON then OFF the real time protection and cloud delivered protection.!
(https://i.stack.imgur.com/mcIio.jpg)
a.exe is also the name of a virus. I suspect your computer's security software is deleting or quarantining the file because it believes it is a virus. Use redFIVE's suggestion to rename your output file to "print.exe" so that the virus scanner does not delete it.
You try:
gcc -o YOUR_PROGRAM.exe main.c
You can stop your antivirus software from deleting your .exe by specifying the full file path (for eg: c:\MyProject) in the 'paths to be excluded from scanning' section of the antivirus software.

Resources