Jump to content

  • Log In with Google      Sign In   
  • Create Account

We need your feedback on a survey! Each completed response supports our community and gives you a chance to win a $25 Amazon gift card!


This error has me perplexed.


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
32 replies to this topic

#1 Ryan_001   Prime Members   -  Reputation: 1487

Like
0Likes
Like

Posted 04 April 2013 - 10:16 AM

I've come across an error that has me rather stumped.  I was testing some exception handling code and found that my program was crashing with an "Access violation reading location 0x0000000000000000." error in the <ostream> header.  Figuring it was probably a problem where I accidentally double delete'd something or forgot to release a handle somewhere I started commenting out code to try and narrow down what is causing it.  This is where things got weird.  I've been able to reproduce it with a very minimal set of code (still larger than I'd like to post here though...).  The thing is if I comment out a few functions that are never run, it will compile and run fine, no errors.  If I reintroduce the code (ie. uncomment it), these same functions that are never called and never run, it will produce the error.

 

I'm currently using VS2012 express edition.  I've tried it with both the default toolset and the November CTP toolset (with identical results).  I've tried it with both 32 and 64-bit and under both debug and release and all give the same results.  I've played with every compiler and linker setting I can think of to no avail.

 

Anyone have any idea of what I should try next?



Sponsor:

#2 Ectara   Crossbones+   -  Reputation: 3066

Like
0Likes
Like

Posted 04 April 2013 - 10:34 AM

I'd have to suggest posting the code. I have no idea what to make of a null pointer access just from hearing its name.



#3 Cornstalks   Crossbones+   -  Reputation: 6991

Like
2Likes
Like

Posted 04 April 2013 - 10:45 AM

I'd have to suggest posting the code. I have no idea what to make of a null pointer access just from hearing its name.

Obviously the error is in asdf.cpp, line 42.3. Duh.

 

 

 

Anyone have any idea of what I should try next?

Aside from posting the code, try stepping through the code with a debugger if you can reliably reproduce it. It's possible you're invoking undefined behavior somewhere (earlier) and the problem is only manifesting it later in the execution. Or the error occurs immediately when the undefined behavior is invoked.


[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

#4 Ectara   Crossbones+   -  Reputation: 3066

Like
0Likes
Like

Posted 04 April 2013 - 10:58 AM

Also, see if there's some sort of memory debugger that you can use. One of the first programs I turn to for things like this is Valgrind, which would give you a heads-up once various memory errors occur.



#5 Ameise   Members   -  Reputation: 766

Like
1Likes
Like

Posted 04 April 2013 - 01:49 PM

Also, see if there's some sort of memory debugger that you can use. One of the first programs I turn to for things like this is Valgrind, which would give you a heads-up once various memory errors occur.

 

"VS2012 express edition"

 

Valgrind does not run on Windows.



#6 jms bc   Members   -  Reputation: 445

Like
0Likes
Like

Posted 04 April 2013 - 01:49 PM

What about these functions that you comment out? Perhaps they force linking with a library that then causes some conflicts. Have seen something similar.


The Four Horsemen of Happiness have left.


#7 Ryan_001   Prime Members   -  Reputation: 1487

Like
0Likes
Like

Posted 04 April 2013 - 02:18 PM

The problem with posting the code is that when I try to bring code from other files into the main file (so I can post it all in one spot), identical copy-pasted code will cause it to go from not working, to working.  For example, here's the main part I was able to trim it down to (this does not work):

 

struct TestException : public Exception {};		// class Exception : virtual public boost::exception, virtual public std::exception

std::string GetLineNumber (const boost::exception& e) {
	std::stringstream ss;
	//ss << 15;
	return ss.str();
	}

// ----- WinMain -----
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

	bool show_exception = false;
	std::string error_msg = "No error has occured.";

	try {
		throw_detailed(TestException());
		}
	catch (const Exception& e) {
		show_exception = true;
		//error_msg = e.GetWindowsErrorMessage();
		error_msg = e.GetLineNumber();
		//error_msg = GetLineNumber(e);
		}
	
	return 0;
	}

 

Now if I uncomment the line "ss << 15;" it will compile and run fine.  Notice how the function is never called.  I was trying to include throw_detailed which consists of:

// ----- special includes -----
#include <boost\exception\detail\attribute_noreturn.hpp>


// ----- ExceptionCore -----
namespace ExceptionCore {

	typedef boost::error_info<struct tagTypeInfo,std::string> TypeMsgInfo;

	template <typename T> BOOST_ATTRIBUTE_NORETURN void ThrowException (T& e, const char* func, const char* file, int line) {
		e << TypeMsgInfo(typeid(T).name());
		e << ::boost::throw_function(func);
		e << ::boost::throw_file(file);
		e << ::boost::throw_line(line);
		throw e;
		}
	}


// ----- throw macro ----
//#define throw_detailed(x) BOOST_THROW_EXCEPTION(x)
#define throw_detailed(x) ::ExceptionCore::ThrowException(x,BOOST_CURRENT_FUNCTION,__FILE__,__LINE__)

 

into main.  But as soon as I copy and paste it in main, it works.  Basically anytime I change any of the code, related or not, it seems to change between working/not working, and I can find no pattern.  I've traced every intermediate value and with the VS2012 debugger they all are correct values at each step along the way.


Edited by Ryan_001, 04 April 2013 - 02:37 PM.


#8 Ectara   Crossbones+   -  Reputation: 3066

Like
1Likes
Like

Posted 04 April 2013 - 02:36 PM


Also, see if there's some sort of memory debugger that you can use. One of the first programs I turn to for things like this is Valgrind, which would give you a heads-up once various memory errors occur.

 
"VS2012 express edition"
 
Valgrind does not run on Windows.
I know. I never said it did. Actually, more accurately, it does: http://sourceforge.net/projects/valgrind4win/, but it doesn't work with VS.
 
 

Now if I uncomment the line "ss << 15;" it will compile and run fine. Notice how the function is never called.

One thing I can think of is that with the line uncommented, that templated member function becomes instantiated. Does it make a difference if you copy the body of this function to some other point in the code?

Edited by Ectara, 04 April 2013 - 02:47 PM.


#9 Ryan_001   Prime Members   -  Reputation: 1487

Like
0Likes
Like

Posted 04 April 2013 - 02:57 PM

If I copy this function below main it makes no difference.  Remove the function completely and it still causes an error.  Are you suggesting that the line "ss << 15" forces instantiation of operator<< where-as without it the member function is not?  After playing around with commenting and uncommenting the code I had a feeling the error was something to do with operator<<, but I wasn't really sure what about it.  That seems like an interesting line of attack.  Now isn't the compiler supposed to instantiate the functions automatically when it encounters them?  So would this be a compiler issue?



#10 Ectara   Crossbones+   -  Reputation: 3066

Like
0Likes
Like

Posted 04 April 2013 - 03:21 PM

If I copy this function below main it makes no difference.

I mean take the stringstream declaration, and use, and put it in a different function entirely, just for now.

Are you suggesting that the line "ss << 15" forces instantiation of operator<< where-as without it the member function is not?

Now isn't the compiler supposed to instantiate the functions automatically when it encounters them? So would this be a compiler issue?

When it encounters them, yes, but with it commented out, it is never used; the compiler never processes what's in comments. I'm not sure if it is implementation defined, but my compiler does not instantiate a member function if it is never called, in order to cut down on executable size. This leads to frustrating bugs that I overlook, because I never used the function, thus the compiler never instantiates it and points out an obvious bug.

So, call it a long shot, but perhaps something relies on this operator <<() function being instantiated, and when it isn't instantiated in any of the objects linked together, the program crashes. This reminds me of a compiler bug discovered not too long ago, where virtual functions were being declared as inline, and thus the compiler never instantiated the function as a normal function, leading to a crash when the program attempted to access the function through the vtable.

Defining a virtual function as an inline function is legal, and has uses, but the compiler is supposed to make a normal function instantiation as well, so that it can be called via function pointer. The bug was that the normal out-of-line instantiation wasn't made, thus the function pointer pointed to garbage.

Edited by Ectara, 04 April 2013 - 03:24 PM.


#11 jms bc   Members   -  Reputation: 445

Like
0Likes
Like

Posted 04 April 2013 - 03:27 PM

My brother, when I read your comments I get confused. So you still get the error if GetLineNumber is removed from the code. But you don't get the error if GetLineNumber is in the code, but the line ss<<15 is commented out? 

 

"Notice how the function is never called" -- but in that sample, the function was being called. I think...confused.


The Four Horsemen of Happiness have left.


#12 Ectara   Crossbones+   -  Reputation: 3066

Like
0Likes
Like

Posted 04 April 2013 - 03:35 PM

My brother, when I read your comments I get confused. So you still get the error if GetLineNumber is removed from the code. But you don't get the error if GetLineNumber is in the code, but the line ss<<15 is commented out? 
 
"Notice how the function is never called" -- but in that sample, the function was being called. I think...confused.[/size]

There are two functions with the same name; one is a member function, one is a free function.

#13 Ectara   Crossbones+   -  Reputation: 3066

Like
0Likes
Like

Posted 04 April 2013 - 03:37 PM

Ah, I forgot to ask. Can you post the callstack/stack trace of where the crash occurred? It might be more obvious if you posted the ordered list of the functions that were called leading up to the crash.

#14 Cornstalks   Crossbones+   -  Reputation: 6991

Like
0Likes
Like

Posted 04 April 2013 - 03:49 PM

I think the problem you're having has to do with this thread. You're passing a temporary to that function call, but you are binding it to a non-const reference and modifying it. Technically, that's illegal C++. Visual Studio has a non-standard extension to allow you to do this, but I still don't know if it's well-defined behavior or not.

 

Try going into Project Properties -> C/C++ -> Language, and then setting "Disable Language Extensions" to true/on. You also might want to turn your warning level up to level 4 (level 3 is the default). This will help you catch mistakes like this.

 

In short, when you call throw_detailed(), don't give it a temporary object.


[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

#15 Ryan_001   Prime Members   -  Reputation: 1487

Like
0Likes
Like

Posted 04 April 2013 - 03:53 PM

If I copy this function below main it makes no difference.

I mean take the stringstream declaration, and use, and put it in a different function entirely, just for now.

>Are you suggesting that the line "ss << 15" forces instantiation of operator<< where-as without it the member function is not?

Now isn't the compiler supposed to instantiate the functions automatically when it encounters them? So would this be a compiler issue?

When it encounters them, yes, but with it commented out, it is never used; the compiler never processes what's in comments. I'm not sure if it is implementation defined, but my compiler does not instantiate a member function if it is never called, in order to cut down on executable size. This leads to frustrating bugs that I overlook, because I never used the function, thus the compiler never instantiates it and points out an obvious bug.

So, call it a long shot, but perhaps something relies on this operator <<() function being instantiated, and when it isn't instantiated in any of the objects linked together, the program crashes. This reminds me of a compiler bug discovered not too long ago, where virtual functions were being declared as inline, and thus the compiler never instantiated the function as a normal function, leading to a crash when the program attempted to access the function through the vtable.

Defining a virtual function as an inline function is legal, and has uses, but the compiler is supposed to make a normal function instantiation as well, so that it can be called via function pointer. The bug was that the normal out-of-line instantiation wasn't made, thus the function pointer pointed to garbage.

 

 

I understand that if commented out operator<<() would never be instantiated IF that was the only place it was used.  In this case though it was being used in another function that was being called (in this case e.GetLineNumber()) but that is in another file which is part of a small library which is linked in.  My guess is that despite being used in the library, something with the linking step is causing it to discard that instantiation, which is why the line "ss << 15" causes it to run as it forces the instantiation that should have been there in the first place.  This would also explain why copy-pasting identical code from the library into main caused it to fix itself/run.

 

So I guess the next question is, why is the linker doing this and how can I prevent it?  Did I personally do something wrong (is there a linker setting I'm not aware of?) or is this a bug with VS2012?  If my hypothesis is indeed correct, I don't see how I could have been the 1st one to come across this error.

 

btw here is the call stack:

> Zombies.exe!std::basic_ostream<char,std::char_traits<char> >::operator<<(int _Val=34) Line 300 C++

  Zombies.exe!Exception::GetLineNumber() Line 185 C++
  Zombies.exe!WinMain(HINSTANCE__ * hInstance=0x00f50000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x002a375b, int nCmdShow=10) Line 39 C++
  Zombies.exe!__tmainCRTStartup() Line 238 C
  Zombies.exe!WinMainCRTStartup() Line 164 C
  kernel32.dll!759a33aa() Unknown
  [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
  ntdll.dll!776f9ef2() Unknown
  ntdll.dll!776f9ec5() Unknown


#16 Ryan_001   Prime Members   -  Reputation: 1487

Like
0Likes
Like

Posted 04 April 2013 - 03:56 PM

I think the problem you're having has to do with this thread. You're passing a temporary to that function call, but you are binding it to a non-const reference and modifying it. Technically, that's illegal C++. Visual Studio has a non-standard extension to allow you to do this, but I still don't know if it's well-defined behavior or not.

 

Try going into Project Properties -> C/C++ -> Language, and then setting "Disable Language Extensions" to true/on. You also might want to turn your warning level up to level 4 (level 3 is the default). This will help you catch mistakes like this.

 

In short, when you call throw_detailed(), don't give it a temporary object.

 

I didn't know you couldn't throw a temporary object, I assumed it would make a copy.  Even if that's not the cause of the error that is good to know.



#17 Cornstalks   Crossbones+   -  Reputation: 6991

Like
0Likes
Like

Posted 04 April 2013 - 03:59 PM

I didn't know you couldn't throw a temporary object, I assumed it would make a copy.  Even if that's not the cause of the error that is good to know.

The problem isn't throwing the object. The problem is modifying the temporary object, which (by standard C++) is undefined behavior. The problem is binding a non-constant reference to a temporary object and then modifying the object (not throwing the object). In the ThrowException() function, e is a reference to a temporary, and you are modifying it, which is undefined behavior. e should be a const reference, and you should not modify it (feel free to throw it).
[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

#18 Ryan_001   Prime Members   -  Reputation: 1487

Like
0Likes
Like

Posted 04 April 2013 - 04:09 PM

The problem isn't throwing the object. The problem is modifying the temporary object, which (by standard C++) is undefined behavior. The problem is binding a non-constant reference to a temporary object and then modifying the object (not throwing the object). In the ThrowException() function, e is a reference to a temporary, and you are modifying it, which is undefined behavior. e should be a const reference, and you should not modify it (feel free to throw it).

Is not the reference valid for the lifetime of the temporary object?  I was certain pg.245 of N3337 implies that the temporary object the reference was bound to will exist for the duration of the function, in particular 12.2.5.  Am I reading this wrong?



#19 Ectara   Crossbones+   -  Reputation: 3066

Like
0Likes
Like

Posted 04 April 2013 - 04:11 PM

In this case though it was being used in another function that was being called (in this case e.GetLineNumber()) but that is in another file which is part of a small library which is linked in.

Is the problematic code also part of the library? The compiler/linker is not required to ensure that only one copy of a function exists during linking, as far as I know. Additionally, if the library is compiled with different settings (optimization, debugging, secure iterators...), there must be two distinct copies, because the compiler flags are different.

#20 Ryan_001   Prime Members   -  Reputation: 1487

Like
0Likes
Like

Posted 04 April 2013 - 04:33 PM

In this case though it was being used in another function that was being called (in this case e.GetLineNumber()) but that is in another file which is part of a small library which is linked in.

Is the problematic code also part of the library? The compiler/linker is not required to ensure that only one copy of a function exists during linking, as far as I know. Additionally, if the library is compiled with different settings (optimization, debugging, secure iterators...), there must be two distinct copies, because the compiler flags are different.

The code that calls the operator<<() in ostream, that blows up, is in the library (and moving it into the non-lib portion of the program seems to fix it).  As far as I can tell, though I guess I will check again for the 100th time, all the compiler settings for the library are the same as for the rest.  In the past when I have screwed this up though, the linker spits a whole host of 'function not found' linker errors.  In this case it seems to be building the exe fine, then just blowing up when it is run.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS