C++ access violation crash - c++

When I attempt to access this specific pointer, the application crashes and shows a c0000005 access violation error.
How can I catch this error and keep it from closing the process as I would in C# with a try&catch block.
Or how could I check if the access is denied to that area of memory before I use it?
Example:
MyClass** a = (MyClass**)(0x12345678);
a[0]->b = 1;
I am accessing a table of pointers and setting the value of one of the members of the class.
This does work, but the issue is that "0x12345678" doesn't always have the classes loaded in that area. The address has a value, but it doesn't point to the correct area of memory and it doesn't hold the value 0.
Keep in mind, this is a DLL that is loaded into a application that I no longer have the source for.
So I'm trying to set the settings of the application dynamically.

You can use Structured Exception Handling to trap these sorts of errors. In particular, filter for EXCEPTION_ACCESS_VIOLATION.
Just make sure you know what you're doing when you swallow the exception: if your garbage address points to a guard page, you might see the behaviour described here.

Related

Why does calling GetDlgItem cause an access violation?

I am trying to access one of my MFC view's dialog elements. To do this, I run the following line of code:
((CButton*)GetDlgItem( IDC_RADIO_VIEW2 ))->SetCheck( 0 );
This causes the following exception:
Exception thrown at 0x53072844 (mfc140ud.dll) in NameOfMyApplication.exe: 0xC0000005: Access violation reading location 0x00000020.
What's strange about this is that the line above it does not cause an access violation, despite being basically the same thing. The line above it is:
((CButton*)GetDlgItem( IDC_RADIO_VIEW1 ))->SetCheck( 1 );
Does anyone know why this is happening?
Obviously, the item with the ID IDC_RADIO_VIEW1 exists, but the item with the ID IDC_RADIO_VIEW2 does not exist. So when you try to retrieve that dialog item, you get a NULL pointer. Yet you cast it to a CButton pointer and then attempt to dereference it without validating the pointer. Right there, you've invoked undefined behavior. Your program has a serious bug, and anything could happen. Luckily, the runtime environment jumped in and issued an access violation before the nasal demons could be unleashed.
The correct way to write the code would be to validate functions' return values. If nothing else, use an assertion:
CButton* pBtn = ((CButton*)GetDlgItem(IDC_RADIO_VIEW2));
ASSERT(pBtn != NULL);
pBtn->SetCheck(0);
This would have given you a very readable (and debuggable) error message.
Note that it would also be more readable to use symbolic constants, rather than magic numbers. So you should be writing SetCheck(BST_UNCHECKED) (or BST CHECKED or BST_INDETERMINATE).
There is no control with ID IDC_RADIO_VIEW2 as an immediate child of the dialog where you are calling the code.
The line of code that doesn't fail references a control with ID IDC_RADIO_VIEW1. It stands to reason, that the dialog has an immediate child window with ID IDC_RADIO_VIEW1.
I'm sure, that calling ((CButton*)GetDlgItem( IDC_RADIO_VIEW999 ))->SetCheck( 1 ); will exhibit a totally different error, although being "basically the same thing". You really need to learn, how computers work. Code doesn't work because it is similar to other working code (for some definition of "similar").

Failure to get call stack in a debug build C++

I have a weird situation. My game is definitely being built with debugging information, and I can merrily hit breakpoints and step through code, and look at data. No settings are unusual. I have ruled out multithreading as a problem.
When I have an actual bug, and a legitimate crash, i get no call stack. A typical crash bug will be
First-chance exception at 0x004678da in Democracy3Debug.exe: 0xC0000005: Access violation reading location 0x0000004c.
Unhandled exception at 0x774015de in Democracy3Debug.exe: 0xC0000005: Access violation reading location 0x0000004c.
And the callstack is just ntdll and some disassembly. I must have changed some option somewhere, but cannot imagine what. Any ideas?
Those errors are indicative of hardware exceptions due to an attempt on your part to access memory that your process cannot read or write. In particular, it looks like you are directly or indirectly attempting to access some element 76 bytes from the address referred to by some pointer, but that pointer is in fact null (thus the access violation reading location 0x0000004c).
Your debug information may not be invalid in any way, you simply may legitimately be in some code inside nt.dll -- for example, if you passed a null pointer to a Windows API function that does not permit them. If you don't have symbols loaded for nt.dll, you won't get a useful call stack.
It's also possible the access violation's coming from a bad pointer you passed that wasn't used until some callback was invoked by the Windows API, which might explain why you don't see your code anywhere in the stack frame.
Enabling break-on-throw in the VS IDE (Debug -> Exceptions, check the boxes for relevant exception types) can help you break earlier when this occurs, but may not help diagnosing the problem if it's legitimately not directly from your code.
You can also use structured exception handling to integrate these exceptions and C++'s exceptions for catching purposes. You may also want to look in to using a symbol server to get the symbols for the Windows DLLs.
Your exception isn't being caught, so it's moving up the call stack all the way to main and terminating your app.
MSDN:
If a matching handler (or ellipsis catch handler) cannot be found for
the current exception, the predefined terminate run-time function is
called.
There's usually an option to allow you to pause debugging when an exception is thrown.
How to: Break When an Exception is Thrown (Visual Studio 2012)
You could also have a catch statement at top level and examine the exception (.what() often gives an description) when you catch it.
Update: You most likely can't catch this exception because it's an Access violation (not a C++ exception, but the pause should still work afaik). If you're on Windows you could use SEH to catch it.

What could this Read Access violation Exception be due to?

My program crashes and a dialog box shows
"Unhandled exception at 0x3aaf1aea (pmsqlsrv.dll) in java.exe: 0xC0000005:
Access violation reading location 0x3ac60880."
The statement shown as causing the crash is
m_pDatabase->m_pIDBCreateCommand->CreateCommand();
In the watch window,
"this" pointer value for the containing object is 0x7395fcaf
m_pDatabase is 0xffff8810 (does it look like a valid address?)
m_pDatabase->m_pIDBCreateCommand CXX0030: Error: expression cannot be evaluated
The addresses shown in the crash dialog box - 0xC0000005 and 0x3ac60880 I don't know what they are. Does this mean that the dll (pmsqlsrv.dll) itself is corrupted and the crash is in reading the code segment rather than in accessing the data?
In 32 bit Windows the address 0xC0000000 and above are reserved for the kernel. Usually the kernel address space starts even at 0x80000000. So that address indeed doesn't look healthy.
0xC0000005 is the address of the "segment fault" interrupt exception handler of the kernel: it is invoked when trying to access a memory address not belonging to your process.
Your m_pDatabase points to 0xffff8810 (very strange memory address: points to the static data area ... was it initialized properly?)
Since it is most likely not a valid address, it contains some meaningless values that makes the program believe that there is something in m_pIDBCreateCommand (probably a random value) trough wich get the address for the function to call. This makes it -after two or three indirection- to access memory outside its process boundaries.
Give a look on how m_pDatabase is initialized, assigned and changed thorough your program.

Variable Name from Memory address in Visual Studio 2008

My c++ application developed in Visual Studio 2008 crashes at some memory location. It is showing memory access violation erroe like,
Unhandled exception at 0x650514aa in XXX.exe: 0xC0000005: Access violation reading location 0x00000004.
how I can get the variable name assigned to 0x650514aa this memory location. Or how to debug this issue.
Thanks,
Nilesh
0x650514aa is the address of code (instruction pointer), not of a variable. If you're lucky, it's your code. Then a map file would help. If you're unlucky, it's some third-party code (blowing because you called it passing in nonsense). But it ain't pretty to dig through map files and it won't tell you your variables' values anyway.
However, if you run it from the debugger, the debugger should intercept and let you examine the stack. And even if you run it without debugger, just-in-time debugging should pop up a dialog asking whether you want to attach a debugger.
The other answers here have useful information. But if for some reason you cannot get the debugger to assist you, here's some more detail you can get out of that error message that may help you locate the problem.
Access violation reading location 0x00000004.
That memory location is what the program is incorrectly trying to read. Typically, reading or writing to a very low memory location like that is caused by code trying to use a NULL pointer as if it pointed to a valid object.
If you happen to know roughly what part of your program is executing when this error occurs, then examine it for any possibilities for NULL pointers to slip through unexpectedly.
Furthermore, 0x00000004 would be the location of a member variable 4 bytes from the start of the object. If the object has virtual functions, then it would probably be the first member variable in the object (because those first 4 bytes are the hidden pointer to the virtual function table). Otherwise, without virtual functions involved, there must be 4 bytes worth of other member variables and/or padding bytes before it. So if you can't immediately tell which pointer is going NULL and causing the problem, then consider which pointers are being used to read such a member variable.
(Note: Technically, the exact memory layout of non-POD objects, particularly when virtual functions are involved, is not guaranteed by any standard. Byte alignment settings in your project can also affect memory layouts. However, in this case it's fairly safe to assume that what I've described is what your compiler is actually doing.)
Usually, if you debug your application inside Visual Studio 2008, at the time of the crash it will stop right at the offending line. Be sure to compile in the Debug configuration, then click Debug | Start.
For further checking, you can go to Debug | Exceptions and check the boxes "Break when an exception is thrown".
If you're running in debug, you should be able to have the system break at that point and be able to see the source code.
If you're running in release mode however, you may need to use the .map file that can be generated. (Link switch /MAP, and you'll need to specify the export files too)
There's a description of how to for v6 here: http://www.codeproject.com/KB/debug/mapfile.aspx
2008 is pretty similar, I believe, although I tend to prefer to run in debug mode if possible.
The map file will allow you to translate your crash address into an exact location in the source code (line number), which may well be helpful. However it will only tell you where the error manifested - not what actually caused it (e.g. a stack corruption wouldn't tell you when you corrupted the stack, only when the corrupted stack was discovered.)
Still, it should help point you in the right direction.

I get an exception if I leave the program running for a while

Platform : Win32
Language : C++
I get an error if I leave the program running for a while (~10 min).
Unhandled exception at 0x10003fe2 in ImportTest.exe: 0xC0000005: Access violation reading location 0x003b1000.
I think it could be a memory leak but I don't know how to find that out.
Im also unable to 'free()' memory because it always causes (maybe i shouldn't be using free() on variables) :
Unhandled exception at 0x76e81f70 in ImportTest.exe: 0xC0000005: Access violation reading location 0x0fffffff.
at that stage the program isn't doing anything and it is just waiting for user input
dllHandle = LoadLibrary(L"miniFMOD.dll");
playSongPtr = (playSongT)GetProcAddress(dllHandle,"SongPlay");
loadSongPtr = (loadSongT)GetProcAddress(dllHandle,"SongLoadFromFile");
int songHandle = loadSongPtr("FILE_PATH");
// ... {just output , couldn't cause errors}
playSongPtr(songHandle);
getch(); // that is where it causes an error if i leave it running for a while
Edit 2:
playSongPtr(); causes the problem. but i don't know how to fix it
I think it's pretty clear that your program has a bug. If you don't know where to start looking, a useful technique is "divide and conquer".
Start with your program in a state where you can cause the exception to happen. Eliminate half your code, and try again. If the exception still happens, then you've got half as much code to look through. If the exception doesn't happen, then it might have been related to the code you just removed.
Repeat the above until you isolate the problem.
Update: You say "at that stage the program isn't doing anything" but clearly it is doing something (otherwise it wouldn't crash). Is your program a console mode program? If so, what function are you using to wait for user input? If not, then is it a GUI mode program? Have you opened a dialog box and are waiting for something to happen? Have you got any Windows timers running? Any threads?
Update 2: In light of the small snippet of code you posted, I'm pretty sure that if you try to remove the call to the playSongPtr(songHandle) function, then your problem is likely to go away. You will have to investigate what the requirements are for "miniFMOD.dll". For example, that DLL might assume that it's running in a GUI environment instead of a console program, and may do things that don't necessarily work in console mode. Also, in order to do anything in the background (including playing a song), that DLL probably needs to create a thread to periodically load the next bit of the song and queue it in the play buffer. You can check the number of threads being created by your program in Task Manager (or better, Process Explorer). If it's more than one, then there are other things going on that you aren't directly controlling.
The error tells you that memory is accessed which you have not allocated at the moment. It could be a pointer error like dereferencing NULL. Another possibility is that you use memory after you freed it.
The first step would be to check your code for NULL reference checks, i.e. make sure you have a valid pointer before you use it, and to check the lifecycle of all allocated and freed resources. Writing NULL's over references you just freed might help find the problem spot.
I doubt this particular problem is a memory leak; the problem is dereferencing a pointer that does not point to something useful. To check for a memory leak, watch your process in your operating system's process list tool (task manager, ps, whatever) and see if the "used memory" value keeps growing.
On calling free: You should call free() once and only once on the non-null values returned from malloc(), calloc() or strdup(). Calling free() less than once will lead to a memory leak. Calling free() more than once will lead to memory corruption.
You should get a stack trace to see what is going on when the process crashes. Based on my reading of the addresses involved you probably have a stack overflow or have an incorrect pointer calculation using a stack address (in C/C++ terms: an "auto" variable.) A stack trace will tell you how you got to the point where it crashed.