I am a java developer trying my hands on C-C++ code.
Basically I have some build script that uses Visual Studio components to build the application libraries - dlls. We do not use Visual Studio IDE to debug.
But whenever we face some crash in our application, we have to enter the debug statements line by line and need to check the exact line of code in which it is crashing.
Is there any API in C/C++ which would write the stack trace into a file during the crash of our program?
Some kind of event listener that would be called during a program exit and that could print the stack trace and error information into a log file.
I have seen many questions related to this but I am not able to get how to handle this in code rather than debugging tools. I feel Java is very much advanced with respect to error handling.
Thanks in advance!
The Standard does not give you any facilites for this. That said, you can use OS-specific APIs to get what you want. On windows, the easiest is probably to use StackWalker. You do need to take care of SEH oddities yourself. I suggest this article for more information.
On POSIX platforms, you can use the backtrace function from glibc.
In general, both require your program to be compiled with debug information. It is also possible to create crash dumps without symbol names (see Minidumps on Windows), but you will need to decode them (which Visual Studio does for you for example, but you mentioned in your post that you don't use it).
Also, keep in mind that writing crash dumps from a crashing process is very error-prone (since you really have no idea what state your application is at that time). You might get more reliable results if you write the crash dumps from another process. Earlier I've put together a simple example out-of-process crash handler that demonstrates how to implement that.
You can use std::set_terminate to define a function to be called when an exception leaves main() additionally you can install a signal handler for SIGSEGV to catch segmentation faults.
You can get a stack trace (on Linux) using libunwind ( http://www.nongnu.org/libunwind/ ) or use the backtrace() function from libc.
One thing I sometimes do in my own exception classes is to grab and store a stacktrace in the constructor that I can then obtain where I catch the exception and print the trace of where it was thrown from.
You could use <errno.h> in C to handle your error and log them into a log file. The standard flux for the errors is stderr.
One solution to get the error is to use the function perror included in <errno.h> that will display the exact error.
To use it, put it in an error catcher.
if (!fileIsOpen())
perror("File not opened");
I hope it helped.
Related
Background
I've got about a terabyte of files with raw data, with a relatively small subset of labelled data. I've written c++ code (calling some ancient MSVC++2003 code I heavily modified to get it to compile on recent compilers) to aggregate the annotated data slices.
A big part of that labelled data is concentrated in one file, but that file turns out to be the one where my program crashes.
Problem
I'm getting
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
terminate called after throwing an instance of 'int'
In my Qt output window, and windows tells me the same in a popup, but at this point it's too late to get any useful info out of the executable / debugger it seems (though I'm not experienced at all with Qt's debugger).
What I have tried
I've googled all over and found plenty of people with this error message but it's so generic that none of their issues could be the same as mine, and there's such a long list of different C runtime functions that sifting through all of them is slow and it doesn't seem to help.
My question
"Find a man a bug, and you help him for a day. Teach a man to debug and you help him for a lifetime. Post the way on stackoverflow and you help many men and get a lot of upvotes."
Is there a generic method to find what C runtime function the problem was and what the argument was? Did I miss some fancy debugger features? Is there anything else you could recommend or info I could provide?
I'd hope to get a catch-all answer to this to help everyone with this problem, not just me, but I'll be glad if I'm helped too of course.
Specific to my problem:
My stack trace is as follows:
0 ntdll!DbgBreakPoint 0x7727000d
1 ntdll!DbgUiRemoteBreakin 0x772ff156
2 ?? 0x6f06eaa1
3 KERNEL32!BaseThreadInitThunk 0x7501338a
4 ntdll!RtlInitializeExceptionChain 0x77299902
5 ntdll!RtlInitializeExceptionChain 0x772998d5
6 ??
and gdb can't get a better trace it seems (anything I try to do with it gets me a timeout error).
After trying a couple more functions just to be sure everything gave a timeout trying "backtrace" once again did give me a result. I guess I just never put this much time in gdb after it timeouting on me once.
That said, I might be able to find something with this new info. Consider my specific problem closed, but my general point is still valid I believe: I've now found the function with the problem (I think), but not why it is a problem, nor what the invalid parameter is. Even better, I've traced it to a line where it says "throw 1". So now I'm assuming windows/Qt translates that to the "invalid parameter". But it's not true.
It can just be some bad code, it does not even need to be a C function, and nothing needs to be wrong with your parameters.
...
#17 0x00c17d72 in libstdc++-6!.cxa_throw () from C:\Qt\5.5\mingw492_32\bin\libstdc++-6.dll
No symbol table info available.
...
Since the log is printed to the debug console then it should be reported by OutputDebugStringA function. You can place a breakpoint on the function to see who results in that log. To place a breakpoint on a function you can Ctrl+B in Visual Studio and enter function name:
But this might not work, or you may have too many other messages logged using OutputDebugStringA. Usually Invalid parameter passed to C runtime function is reported by _invalid_parameter, so, you may as well try to place a breakpoint on _invalid_parameter function. This might not work as well because it could be reported from some other system dll that your process links to: ntdll.dll, KernelBase.dll etc. To place a breakpoint on a function exported by a dll you need to use: <dll>!<exportname>:
_invalid_parameter
ntdll.dll!__invalid_parameter
KernelBase.dll!__invalid_parameter
msvcrt.dll!__invalid_parameter
ucrtbase.dll!__invalid_parameter
All of these are different functions and you can see their addresses:
In my case only when I set a breakpoint on ntdll.dll!__invalid_parameter I was able to see backtrace and the log message was caused by GetAdaptersAddresses winapi. The reason breakpoint on OutputDebugStringA wasn't helpful was because the log was printed through DbgPrint api. Placing breakpoint on DbgPrint works in this case.
In Visual Studio 2017 at least, you can hit CTRL+B and add a function breakpoint on _invalid_parameter. This will stop your program at the point where the message would have been logged, which will let you find the offending function in the call stack. It will work even if someone else's code undoes your call to _CrtSetReportMode().
Things I learned from this question (and that might help people searching for this question) :
Turns out that this error could be traced back to a line of code saying
throw 1;
This means It can just be some bad code, it does not even need to be a C function, and nothing needs to be wrong with your parameters. Searching your code and libraries' source for "throw"
Turns out that getting timeouts on gdb are not an indicator of anything. Keep trying things and retrying and maybe at one time you might get a stack trace.
Personally, on a Linux terminal, I use gcc for compiling and gdb for debugging. To compile a program with debugging options using gcc, you simply have to add a -g to your other flags. Ex:gcc file.c -o file -std=c99 -g. You can then type gdb file and you enter into an interactive debugger. Among other helpful things, you can run the program, call functions and insert breakpoints. For a full and well explained usage go to this website-http://www.tutorialspoint.com/gnu_debugger/index.htm
I ran into this same error message "Invalid parameter..." while debugging a windows driver.
The technique on this page, even though for Windows and not exactly addressing for this question, might be useful to someone who is looking for this particular error message. IOW HTH..
http://dennisyurichev.blogspot.com/2013/05/warning-invalid-parameter-passed-to-c.html
So in summary you have to narrow down specific to your environment where a debug string is being output by possibly a debugging "helper" library function. Once known, set a breakpoint there and then look back up the call stack. IMHO, it's a very clever solution to what can be a tough location to find.
If you are using MinGW only (no Visual Studio build stuff). Try compiling your application for the Console subsystem instead of the Windows subsystem when building debug version. In that case when an invalid argument is passed to a C function the function will fail and will trip your error handling code instead of the standard library's error box which should give you better control over what is happening.
We are using Google Test as our C++ unit testing framework. But I ran into a painful situation and don't know how to deal with.
Basically, when there is an uncaught exception in the code, I got the following error message printed in the console and get a FAILED. Obviously, the exception is captures by google test. However, I have no information at all where is the exception was throw.
unknown file: error: SEH exception with code 0xc000005 thrown in the test body.
What I can do is debug and step through the code and I will eventually figure out where the problem is. But this is not very efficient as the project is big.
I want the debugger to stop at the line of uncaught exception and give me a nice call stack. Is there any settings in google test that I don't know of? Any other work around or suggestions will be very much appreciated.
Edit: I am looking for something like the following under Windows
Finally according to the answers, I found this settings for visual studio and everything works as the way I want now :)
At work the approach I use is to run only the failing testcase using gdb like so:
gdb /path/to/test
catch throw
r --gtest_filter='Test.Testcase' --gmock_verbose=info
bt
With visual studio, I suspect you should be able to start your binary with arguments as above, and set a breakpoint to any throw, then take a look at the backtrace.
An SEH Exception is NOT a C++ exception.
It is a windows exception that is throw outside of the standard C++ framework for exception handing (there is a different syntax for catching them).
The best way to find the location is to run this inside DevStudio. Its been a while but I am sure DevStudio has an option to break when SEH exception is thrown. Just turn this on and your debugger will stop at the throw point and allow you to debug.
See: https://msdn.microsoft.com/en-us/library/d14azbfh.aspx
As noted by #MatthiasVegh you should pass the name of the test as well so you don't have to run through all the tests.
That is not possible since C++ doesn't keep stack trace in the exception object and even if gtest had some smart catching mechanism it would have no means to know where the exception came from. The best you can do is to store some information in the exception yourself and check it in the test case.
I'm writing a plugin (basically a dll) for a 3D application and occasionally there are crashes. Sometimes these are very difficult to find and I wanted to invest some time into making (or integrating an existing) crash logger that will
Give me a stack trace.
Give me a list of local variables.
Dump these items to a file, or upload it to a given URL.
So far I've looked at Google breakpad, but have no idea how to integrate it and the documentation seems poor at best. I've tried to use it and managed to get as far as building it on windows, but some unit tests fail and there is no help about what to do at that point. Also, it may be a bit excessive for my needs.
I've found the following site which details how to get a stack trace GENERATE STACK TRACES ON CRASH PORTABLY IN C++. But I'm not sure if this will work on a remote system. I'm guessing this will need to be the debug version and be supplied the pdb file for this to work?
As for getting local variables, I've not managed to find anything yet.
Does anyone know of some resources to help?
this article, though written in 2002, is still relevant to post-mortem debugging. It shows you all the reasons and steps and design required to get it working.
Nowadays, its a little easier (though I liked Windbg!) you get your app to call SetUnhandledExceptionFilter and write the .dmp file, then just double-click it to load it into Visual Studio. You will need good symbols (.pdf files) on the debugging system to make sense of the dump, but create your own symbol server (instructions in the article, its dead easy) and it should be able to figure out which symbols are needed for any app. You have to be disciplined about saving the symbols though - wrong symbols are worse than useless.
This question is rather old, but regarding exceptions I want to note that you can get nice backtraces in a cross-platform way, using only standard C++11 and without the need for a debugger or cumbersome logging:
Use std::nested_exception and std::throw_with_nested
It is described on StackOverflow here and here, how you can get a backtrace on your exceptions inside your code by simply writing a proper exception handler which will rethrow nested exceptions.
It will, however, require that you insert try/catch statements at the functions you wish to trace.
Since you can do this with any derived exception class, you can add a lot of information to such a backtrace!
You may also take a look at my MWE on GitHub or my "trace" library, where a backtrace would look something like this:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
Regarding local variables, in this approach you would have to manually place those you wish to print into your exception or exception message in some form, which would be quite cumbersome...
Writing whatever you logged to a file and uploading it somewhere is a different problem for which I don't have any specific suggestions.
Is there a way catch an exception like access violation and get information about on which line an exception occurred? This would be very good for debugging purposes, especially for testers..
My environment is Windows with VC++ on VS2008
An access violation is not an exception in C++ terms, so the answer is in general "no". Concieveably, your specific implementation might have a feature that turns access violations into C++ exceptions - you need to specify what compiler & platform you are using.
In case you really want to log info about C++ exceptions (AV is not one) thrown from your code, you can use macros __FILE__ and __LINE__ within constructors of your exception types.
If you catch the SEH exception using a __catch handler you can then access the thread context at the time of the exception and then use StackWalk64 to dump the call stack at the point where the exception was generated. Note that as I mentioned here: Printing the stack trace in C++ (MSVC)? StackWalker by Jochen Kalmbach [MVP VC++] and available on codeproject is probably the easiest way to do this. It wraps up all of the details of dealing with the underlying StackWalk64 API.
Alternatively you could the same solution that I proposed here: How to catch divide-by-zero error in Visual Studio 2008 C++? to convert the Windows Structured Exceptions into C++ exceptions and capture the stack trace as shown above at the point where you translate the exception. This would give you a C++ exception with a stack trace like you get in C# or Java.
I'm not sure why testers would need to know which line an exception occurred.
The developers might want to know, though. But a better approach is the following:
Include the information about class and method with each PROGRAM exception. These are exceptions that should NOT have happened.
This should be output by whatever logs your exceptions. Your program does catch and log every exception, doesn't it? If not, it should.
Make sure your methods are small enough that the above is enough information to easy track down a bug. If you need line information as well, then your methods are too large and your exceptions are not specific enough.
In MSVC you can set the debugger to break when any exception or things like an access violation happen buy going to debug->Exceptions and checking the appropriate box.
Note that access violations are not C++ exceptions and will be handled differently on different systems. In Windows you can trap them with a structured exception handler. In unixy systems it will usually core dump. You can usually get a stacktrace from that.
For msdev / Windows, during development, always have your linker generate a MAP file.
When Windows throws up an access violation, and it's your code (not library), you can use the address to match up function / data in the MAP file and get within a few lines of the offender. At a minimum, you'll know the function/method.
That's really a compiler question.
If you want to know if it is possible for a compiler to provide, the answer is yes. I know multiple Ada compilers that provide tracebacks for unhandled exceptions, so it is clearly possible. This includes the gcc-based Gnat, so if the C++ compiler uses any of the same facilities for its exceptions, the support for doing that should already be there.
On unix type systems a Access violation generates a SEGV or BUS signal. This normally causes the application to core dump. You could always write your own signal handler. From there you could probably generate a stack-dump using the glibc before core dumping.
A core dump generally give you all this for wasy analysis in gdb.
My answer refers to Windows only. You have quite a few options:
Without changing your code -
Avoid catching exceptions (at least ones you do not expect), and let your app just crash. Configure good ol' dr. watson (drwtsn32.exe) to create a crash dump, and open that dump in your debugger. You'll get the exact line of code there.
Use adPlus (from the windbg installation) to monitor your app's run, and create a dump when an exception is thrown.
From within your code, you can -
Easily walk the stack when a structured exception is thrown. See Jochen Kalmbach's stack walker for example.
Use this weird hack to walk the stack when a C++ exception is thrown.
Finally, quite a lot of questions have been asked here on this issue. Look around, and you'll get additional answers.
On one project I worked on, the root class of the exception hierarchy used captured a callstack in the constructor in case that information was needed later for debugging after the exception was caught. It was a decent idea, although if you're catching and 'handling' the exception, exactly when it was thrown shouldn't really matter all that much.
To put it another way, if you care about this info (context of "who" threw it), you probably shouldn't be using an exception to report this condition, or potentially you shouldn't be catching the exception in the first place. Uncaught exceptions cause crashes, giving you a crash dump at the point the exception was thrown.
On windows, the C runtime system function _set_se_translator() takes a simple static function with signature
void f(int, EXCEPTION_POINTERS*)
neither of which argument you totally need. In the body of f, throw your favorite exception. Call the function near the beginning of your program. The documentation is reasonable for microsoft.
You can do all manner of additional stuff with this function.
The google breakpad project has many good things. Among them are means to convert a crash address to file, line, and function name using build symbols and the debuginfo dll.
I have been provided with a C++ DLL and associated header file in order to integrate it with my application. To begin with, I am simply trying to call the DLL from a simple Win32 console application (I'm using Visual Studio 2008 Express).
I've linked the DLL by specifying it as an additional dependency in the project settings.
The interface (i.e. the only exported function) simply returns a pointer to an instance of the Class that I actually need to call. I can successfully call this, get the pointer and call the first function that I need to (an "init" function).
When I come to call the function that actually does the processing I require, I'm intermittently getting a "0xC0000005: Access violation reading location...." error. That is, I run the program - it works successfully and exits - I try to run it again (changing nothing - all parameters are hard coded) and get the error (and continue to do so).
I can't consistently recreate the problem but I'm beginning to think that it may be something to do with the DLL not being unloaded properly - after getting the error on one occasion I tried deleting the DLL and was told by Windows that it was in use. That said, on another occasion I was able to delete the DLL after getting the error, copy it back, then still got the error on the next run.
Should the DLL be correctly unloaded when my .exe finishes? Would I be better off trying to explicitly load/unload the DLL rather than doing it implicitly?
Any other help or advice greatly appreciated.
It won't have anything to do with the DLL being unloaded; different processes using the same DLL do not share any state. Also, the DLL will be unloaded when the process exits; perhaps not gracefully, but it will be unloaded.
I can think of two likely reasons for an intermittent failure.
Most likely, the DLL has a race condition. This could be one that's exposed if the DLL has been cached, causing the timing to change. That would explain why your first run didn't fail but subsequent ones did.
I think it's also possible that the DLL didn't release its lock on some file. If there is some file you know is accessed by this DLL, try checking to see if that file is locked after the process ends.
Also, get this in a debugger. Turn on first-chance exceptions in visual studio and look at the callstack where the AV is happening, and post it here.
What types are involved in the classes exported by the DLL? We have often had these kinds of problems with Visual Studio when the classes make use of STL - I'd guess that any template usage would probably be a way to potentially cause this sort of problem.
What's your setting for "Runtime library" under "C/C++" in the configuration properties?
You should probably try /MD (or /MDd for debugging).
see http://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.71).aspx