views:

230

answers:

8

Hi.

When I exit my C++ program it crashes with errors like:

EAccessViolation with mesage 'Access violation at address 0...

and

Abnormal Program Termination

It is probably caused by some destructor because it happens only when the application exits. I use a few external libraries and cannot find the code that causes it. Is there a function that forces immediate program exit (something like kill in Linux) so that memory would have to be freed by the operating system? I could use this function in app exit event.

I know that it would be a terrible solution because it'd just hide the problem.

I'm just asking out of sheer curiosity, so please don't give me -1 :)

I tried exit(0) from stdlib but it didn't help.

EDIT:

Thanks for your numerous replies:) I use Builder C++ 6 (I know it's outdated but for some reasons I had to use it). My app uses library to neural networks (FANN). Using the debugger I found that program crashes in:

~neural_net()
{
    destroy();
}

destroy() calls multiple time another function fann_safe_free(ptr), that is:

#define fann_safe_free(x) {if(x) { free(x); x = NULL; }}

The library works great, problem only appears when it does cleaning. That's why I asked about so brutal solution. My app is multi-threaded but other threads operate on different data.

I will analyze my code for the n-th time(the bug must be somewhere), thanks for all your tips :)

+1  A: 

On Linux/UNIX you can use _exit:

#include <unistd.h>
void _exit(int status);

The function _exit() is like exit(), but does not call any functions registered with atexit() or on_exit(). Whether it flushes standard I/O buffers and removes temporary files created with tmpfile(3) is implementation dependent. On the other hand, _exit() does close open file descriptors, and this may cause an unknown delay, waiting for pending output to finish. If the delay is undesired, it may be useful to call functions like tcflush() before calling _exit(). Whether any pending I/O is cancelled, and which pending I/O may be cancelled upon _exit(), is implementation-dependent.

John Kugelman
+6  A: 

You should fix the problem.

  • First step: find at check all functions you register with atexit() (not many I hope)
  • Second step: find all global variables and check their destructors.
  • Third Step: find all static function variables check their destructors.

But otherwise you can abort.
Note: abort is for Abnormal program termination.

abort()

The difference: (note letting an application leave the main function is the equivalent of exit())

  • exit()

    1. Call the functions registered with the atexit(3) function, in the reverse order of their registration. This includes the destruction of all global (static storage duration) variables.
    2. Flush all open output streams.
    3. Close all open streams.
    4. Unlink all files created with the tmpfile(3) function.
  • abort()

    1. Flush all open output streams.
    2. Close all open streams.
Martin York
+2  A: 

You could try calling abort(); (declared in <stdlib.h> and in <process.h>)

The version in VisualC++, however, will print a warning message as it exits: "This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information."

James Curran
A: 

That immediate program exit (and yes, that's a terrible solution) is abort()

usta
+4  A: 

It's a terrible solution for more than one reason. It will hide the problem (maybe), but it could also corrupt data, depending on the nature of your application.

Why don't you use a debugger and try to find out what is causing the error?

If your application is multi-threaded, you should make sure that all threads are properly shut down before exiting the application. This is a fairly common cause of that type of error on exit, when a background thread is attempting to use memory/objects that have already been destructed.

Edit:

based on your updated question, I have the following suggestions:

Try to find out more specifically what is causing the crash in the destructor.

The first thing I would do is make sure that it's not trying to destruct a NULL object. When you get your crash in ~neural_net in your debugger, check your "this" pointer to make sure it's not NULL. If it is, then check your call-stack and see where it's being destructed, and do a check to make sure it's not NULL before calling delete.

If it's not NULL, then I would unroll that macro in destroy, so you can see if it's crashing on the call to free.

Gerald
Yes my app is multi-threaded, theoretically these threads should interfere because they operate on different data. I will make sure one more time. Thanks for info.
Andrzej Nosal
A: 

That happens most likely because a NULL pointer is being accessed. Depending on your OS try getting a stack trace and identify the culprit, don't just exit.

Novikov
+1  A: 

Have you tried the gruesome step by step? If you're project/solution is simply to large to do so maybe you could try segmenting it assuming you use a modular build and test each component indivdually. Without any code or visible destructors abstract advice is all I can give you I'm afraid. But nonetheless I hope trying to minimize the debugging field will help in some way.

Good luck with getting an answer :)

Proclyon
A: 

If you use linux, valgrind should solve your problem. but if it is windows, try one of these: MemoryValidator, BoundsChecker or other tools like these.

Simply close your application is not the best way to deal with bugs ...

Tiago Natel