I have some crashes in some C code, built without debugging symbols, and I have only a backtrace with the absolute addresses of the call stack. This is on windows (64 bits). I am more of a linux guy, so I am a bit lost at how to look into debugging this - on Linux, I would run the code under valgrind, but AFAIK, no such tool exists for windows 64 bits.
What are my options ? I can modify the C code at will, but I cannot build it with the debug symbols. The reason why I cannot build with debugging symbols is that my binary is not built with MS tools (it is built with mingw-w64).
You need to generate a map file. A map file lists out the addresses of various public symbols (functions, globals etc) in your executable/binary. Usually it can be generated by passign on a special switch to the linker.
MSDN reference for /MAP
You should probably be using the ming version of gdb, which can understand the symbols embedded in the binary.
Related
I'm trying to implement breakpad crash handler in our application which runs cross-platform.
I've had great success with the Linux build, however, on Windows, I've gotten as far as getting a crash dump, extracting symbols from the .exe using dump_syms utility, and using minidump_stackwalk to check out the crash and line number.
Unless I'm missing something, It's difficult(impossible) using only minidump_stackwalk to debug further (checking out local variables, etc). On Linux I've used a tool minidump-2-core to convert minidumps to core files that can be loaded in gdb. On Windows we use a MSYS2/MINGW64 environment to build the application. Is it possible to convert the minidumps to core and load them in a similar fashion ?
I understand that an alternative is using WinDbg, however I can't seem to extract symbols correctly from the .exe. Any tips on how I would do that ?
I'm trying to build a program from its source code with VC 11. When the compiler is about to finish, it raises the error mentioned in title of this post.
As I've read here and in other forums, I tried to both close as many programs as possible and enlarge the size of the swap file in Windows... neither works.
I've read about a parameter called \Zm but I don't understand how to use it.
Can you please help me?
Take a look at this documentation which gives possible solutions:
I also had that problem and found the documentation useful. Main points:
If the compiler also issues errors C1076 and C3859, use the /Zm compiler option to lower the memory allocation limit. More heap space
is available to your application if you lower the remaining memory
allocation.
If the /Zm option is already set, try removing it. Heap space might be
exhausted because the memory allocation limit specified in the option
is too high. The compiler uses a default limit if you remove the /Zm
option.
If you are compiling on a 64-bit platform, use the 64-bit compiler toolset. For information, see How to: Enable a 64-Bit Visual C++
Toolset on the Command Line.
On 32-bit Windows, try using the /3GB boot.ini switch.
Increase the size of the Windows swap-file.
Close other running programs.
Eliminate unnecessary include files.
Eliminate unnecessary global variables, for example, by allocating memory dynamically instead of declaring a large array.
Eliminate unused declarations.
Split the current file into smaller files.
I can't tell much about the /Zm parameter, but I had the same issue (compiler is out of heap space).
What has helped me was the /m:4 (4 for the count of your CPUs) parameter so that you can use multiple CPUs for building.
Hope that helps you as well.
Also, if you are running on x64, be sure that the x64 version of "msbuild.exe" and "cl.exe" is beeing used. I had the issue that even when using e.g. the x64 ms powershell, the compiler would still choose the 32-bit version of msbuild.exe (in task manager "msbuild.exe*32", windows 7)
In addition to the other answers here (and in my case), fatal error C1060: compiler is out of heap space can be caused by a syntax error. The following code (in certain circumstances) can cause this error even with correct compiler options -- for instance if you've previously successfully compiled the same program.
r.push_back(e[1];
instead of
r.push_back(e[1]);
It seems to only cause this error rather than the standard error C2143: syntax error: missing ')' before ';' when r and e are of certain types, but it's worth checking any code you've edited recently if the program previously compiled without errors.
We had similar problem: a relativelly simple program (although, full of templates, using Eigen library) persistently failed to compile on one of the computers. All were using MSVC2013 x64, but only one was unable to compile the program due to C1060 error. We tried different compiler flags, setting/unsetting -Zm, but failed to resolve it without modifying code.
Some pointers were, however, given to us, when we switched from x64/x64 (64bit compiler for 64bit resulting executable) version of the compiler to the x86/x86 (32bit compiler for 32bit resulting executable). The x86 compiler gave us exact locations of the problematic parts of the program - calls to template functions receiving heavy templated objects. We have rewritten those to normal functions (build in different object file) and that solved the problem...
VS: Visual Studio 2015
OS: Windows10
If you are using VS2015 as your IDE, maybe there is another solution:
Go to update the VS2015 "Update3" package and everything will work smoothly.
In my case, a main program would not compile is VS 2022 Community Edition (free). It had many include files. By process of elimination, I managed to compile it once I removed any "volatile" modifiers in declarations that had this modifier.
A very strange bug, to say the least!
I got this error when compiling OnnxRuntime with MS Visual C++ 17 2022.
The solution for this issue was to close all other programs and compile using a single thread (in this case, removing the --parallel argument from the build.bat call).
I was trying to make my program accept input without the user having to press enter, so I tried the following:
mov ah,01h
int 21h
But it just crashes my program over an unhandled exception. This seems to be the way to do it according to much that I have read, so why isn't it working for me?
Now, I am fairly new to this language so I still do not exactly understand the process of how this piece of code works, so I would also appreciate what the logic is behind accepting input by pressing enter and accepting input without the user having to press enter.
MY OS is Windows, by the way.
Your code looks like MS-DOS-era assembly. VS2010 doesn't support generating DOS executables, and modern versions of Windows (the 64-bit kind) don't support running them, either. Looks like you were going by some old book or site, one that was written in late 80'es-early 90's. Back at that time, assembly was way more relevant and marketable as a job skill. Not so much these days, although some assembly knowledge won't hurt.
Decide what do you want to learn. If you want to learn modern assembly (and target Windows), get some recent guidance. The techniques are quite different, and int21h isn't among them :) If you're indeed after DOS-era assembly, set up a DOS virtual machine with DOSBox, and find some old free assembler. Visual Studio 2010 won't help you here. The latest version of Visual C++ that generated 16-bit executables was v1.5x.
Specifically why does your program crash. Int21h was how MS-DOS exposed its applciation program interface (API). Windows doesn't support it for Windows executables - there are other ways of invoking the API. When you assemble with Visual Studio 2010, you end up with a Windows executable, not a DOS one, and there's no option to generate a DOS one. As for the Windows executables, they're not supposed to invoke interrupts at all - that's a crash condition.
You need to obtain a tool set that can generate 16 MS-DOS programs. These should run on DOSBOX, or on a Virtual PC with MS-DOS installed on it. Microsoft included 16 bit tool sets up to Visual C / C++ 1.52, but Visual C / C++ 4.0 and 4.1 also contain the 1.52 16 bit tool set. The older version of the compilers would be named Microsoft C 8.xx or earlier version. I don't know if any the early versions of Visual Studio (2002 or 2003) include the 16 bit tool set.
Use the linker version 5.60 to generate 16-bit DOS applications. You can get this from:
http://download.microsoft.com/download/vc15/Update/1/WIN98/EN-US/Lnk563.exe
Dirk
I must reverse a legacy windows (16-bit, NE exec) application that controls an old DAQ that I must interface somehow with upgraded hardware. I've been able to disassemble the exec using W32Dasm (and WindowsCodeBack as well, the only two from many that I've tried that have worked) but the resulting asm file contains too many lines. I'd like to use a debugger and set some breakpoints to restrict the work. Could you advise which is the right approach to debug a Win16 app in 32-bit times? A VM running Windows98 for example? Which Win16 debugger could I use?
Many thanks
IDA can disassemble Win16 programs as well (though not the free version), and it's much more convenient than plain dead listing.
As for debuggers, I would try to find the Win16 Turbo Debugger (TDW.EXE). There's also OpenWatcom, which even supports remote debugging (so you can run the program in a VM and the debugger UI on your desktop).
What is the need/use of 'symbols' in the Microsoft debugger?
I spent some time trying to figure out the debugger a while back and never was able to get it making any sense (I was trying to debug a server hang...). Part of my problem was not having the proper 'symbols'.
What are they? And why would I need them? Aren't I just looking for text?
Are there any better links out there to using it than How to solve Windows system crashes in minutes ?
You need symbols in order to translate addresses into meaningful names. For example, you have locations on your stack at every function call:
0x00003791
0x00004a42
Symbols allows the debugger to map these addresses to methods
0x00003791 myprog!methodnamea
0x00004a42 myprog!methodnameb
When you build a debug version of a program, the compiler emits symbols with the extension .PDB. It also contains line information so you can do source code debugging, etc..
You need to set your symbol search path correctly for the debugger to pick this up. IN the command window you can do
.sympath c:\symbols;c:\temp\symbols
in order to have it search for the .PDB in these directories. It will also look in the same directory that the executable is ran from.
It also might be helpful to use the Microsoft public symbols server so that you can resolve OS binaries such as NTDLL, GDI, etc.. with this path at the beginning:
.sympath SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols;c:\symbols
You will need to create c:\websymbols first.
On the Windows binary architecture, the information needed for debugging (function names, file and line numbers, etc.) aren't present in the binary itself. Rather, they're collected into a PDB file (Program DataBase, file extension .pdb), which the debugger uses to correlate binary instructions with the sorts of information you probably use while debugging.
So in order to debug a server hang, you need the PDB file both for the server application itself, and optionally for the Windows binaries that your server is calling into.
As a general note, my experience with WinDbg is that it was much, much harder to learn how to use compared to GDB, but that it had much greater power once you understood how to use it. (The opposite of the usual case with Windows/Linux tools, interestingly.)
If you just have the binary file, the only info you can typically get is the stack trace, and maybe the binary or IL(in .NET) instructions. Having the symbols lets you actually match that binary/IL instruction up with a corresponding line in the source code. If you have the source code, it also lets you hook up the debugger in Visual Studio and step through the source code.