How can I figure out why my C++ program is crashing in Windows?

I have a program that I've written using Ultimate++

Normally, if I compile in debug mode and run in the debugger, then if an error or exception occurs it will jump me to that point in the file and tell me what line and what problem, which is extremely effective.

However...

Recently, it's been crashing and the error that it gives me isn't traceable back in code. It simply says "Read error at 0xHEXHEXHEX" (paraphrasing of course) and the debugger will not jump me to a line.

It's a multi-threaded application, and each thread has access to a global data array to pass information from one thread to the next. So, there could be a case of one writing and one reading to the same place at the same time which is what I assume is happening.

Since it won't tell me what line, or what error etc then I have no way to fix it.  Is there something else that I can do, debugging wise, to figure out where my program is crashing? If I figure out what line it is, then I'm sure I can do something to fix it.

My first thought was to write something that, on every line of code, it saves the line number to a file that way when it crashes I'll know what line it crashed on..but I would assume that this would be way too HDD or processor intensive.  What else could I possibly do?? I'm pretty frustrated here, so top points to absolutely anybody who can help me through this.

-Kevin
ProjectZIGAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Daniel Van Der WerkenIndependent ConsultantCommented:
So, go here:
http://msdn.microsoft.com/en-us/windows/hardware/gg463009
and read and install WinDBG and get the web symbols setup, and run the application with the debugger attached to the process and see if you can get into what is going on with the issue.
0
evilrixSenior Software Engineer (Avast)Commented:
>>  read and install WinDBG and get the web symbols setup
Unlikely to make any difference because the most likely cause is stack corruption due to a race condition reading/writing to globals (hence, the call stack is shagged).

If you have multiple threads reading/writing to the same global variable without using synchronisation primitives to serialise access you will end up with a race condition (ie. undefined behaviour). Your first job should be to put a mutex or critical section around the code that changes these globals to remove any race conditions.
0
ProjectZIGAuthor Commented:
evilrix, that is exactly right.  See I had this problem before with one of the globals and fixed it by making it to where it writes to a DIFFERENT global first. Then, when I get to the place where it needs to read/write to the main global, I simply copy everything from the secondary one, run my checks,and then update the main one which seemed to help...though this may still be causing the same problem considering at the very beginning of the function it will still be reading from that location..so it may have slowed it down but not stopped it completely.

Can you elaborate a bit further as to the "synchronisation primitives to serialise access"? Also, a mutex or critical section..can you explain this further? they sound vaugely familiar but I'm not sure where to begin there other than doing some Googling, I figure you could explain it a bit better than Google can for my specific problem.

Thanks in advance!

0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

evilrixSenior Software Engineer (Avast)Commented:
You need to ensure than when you are writing to the global variable only the writer has access. The simplest way to do this is to use a mutex or critical section primitive. The exact way these work depends on what threading library you are using but to put it into an easy to understand context you can think of a mutex/critical section as being similar to the lock on a bathroom door. When you enter you lock the door to make sure no one else can come in whilst you're in there. Semantically, this is what a mutex/critical section does.

From a pseudo code point of view it'd look something like this...

function foo
   lock mutex_object # only one thread can lock this the rest will wait here until it's unlocked.
   change global var
   unlock mutex_object
end

Since you've put this zones that suggest Windows development I suggest you look at the following.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686353.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682530.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms684266.aspx
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
sarabandeCommented:
when you have a crash at an address where no souce code is available you should look into the call stack whether there are functions with source code higher up in the call hierarchy.

in c++ you can make a thread-safe container (array) by putting a class around that container which makes any access exclusive by using a mutex. on windows platform a fast mutex is available by means of a structure that is called CRITICAL_SECTION.

class MySaveArray
{
     std::vector<MyStruct> array;
     CRITICAL_SECTION cs;
public:
     MySaveArray() { InitializeCriticalSection(&cs); }
     ...
     void push_back(const MyStruct & ms) 
     {
           EnterCriticalSection(&cs); 
           array.push_back(ms);
           LeaveCriticalSection(&cs); 
     }
     ...

Open in new window


you would need to implement all functions for this class similar to the push_back function and use a shared MySaveArray instead of the current array.

Sara
0
sarabandeCommented:
i see that evilrix also has answered in the meantime. so take my code as an add-on ...

Sara
0
ProjectZIGAuthor Commented:
Ok, this really helps alot! I was trying to use flags to figure this out in the form of a global variable integer..but it gets real complicated.

So a question -- does the critical section thing..is this specific for each variable I need to protect? For example, I have about 7 global variable arrays that can be accessed at any given time. Do I need to set up critical sections for each like so?:

CRITICAL_SECTION cs1;
CRITICAL_SECTION cs2;
CRITICAL_SECTION cs3;
CRITICAL_SECTION cs4;
CRITICAL_SECTION cs5;

and then initialize each one when the program starts and use EnterCriticalSection(cs1/cs2/cs3/etc) or should I just use one of them and have them all run on the same lock?

-Kevin

0
evilrixSenior Software Engineer (Avast)Commented:
>> I was trying to use flags to figure this out in the form of a global variable integer
For various reasons, that is never going to work.

>> does the critical section thing..is this specific for each variable I need to protect?
That depends on whether there are dependencies between them or not. That's a design decision for you to take.

>> should I just use one of them and have them all run on the same lock?
You can use just one critical section but if you have a thread trying to access var1 and var2 at the same time and assuming both are protected by cs1 then access to these will be serialised (meaning only one can be accessed at a time). This is rarely what you want so you probably want a CS for each variable.

Incidentally, there is rarely a good reason to use globals... the fact that you are and it is causing you so much pain is a strong indication that your code probably needs re-thinking. Multi-threaded coding is pretty hard (there are many pit-falls) and adding globals to the mix is just a design problem waiting to bite you very hard indeed.

Ask yourself, do you really need these globals?

0
evilrixSenior Software Engineer (Avast)Commented:
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.