Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

monkeyman

Program crashes without a "printf" statement..

This topic is 6026 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ok, I''m at the end of my rope with this.. Here''s the deal: I have some fairly straightforward(explicit code, no macros, jump tables, etc.) single-threaded C code that crashes in release mode. The code is completely solid, nothing funny going on. The error states that the instruction referenced memory at 0000, etc. the memory cannot be written. It doesn''t crash in debug mode. After tracing through the code one function at a time(which basically meant logging before and after every function call), I finally isolated it down to one specific section of code. The problem is, I can''t go any further, because the program doesn''t crash if I printf before OR after this function call. The code itself is solid, and has not changed. The only change that was made was that the function was renamed(in order to add an additional overloaded version). If I try to debug in release mode, the debugger states that the app crashes in NTDLL..of course, adding a printf statement ANYWHERE within the function, or before, or after, ''fixes'' the problem.. I''ve cleaned and rebuilt the project(both debug and release), no difference..there is no problem in debug mode, and I can''t really trace anything in release mode, because if I try to log any values(looking for bad pointers, etc.), they will of course be fine because I am printing something.. I can''t even debug the raw assembler output because it''s not my code. Since I can''t check the actual values of any of the data(logging anything makes it work), I tried adding checks after each and every single memory allocation to find the one that turns up NULL, and there are none, so apparently this memory referenced at 0x0 is not one of MY pointers.. So, what I would like to do is find out exactly where Windows and MSVC++ has decided to interpret/execute something other than the instructions I actually coded, and do something a little more structured than adding a printf statement.. btw the code itself is single threaded(only one process going on), but the code generation settings are for multi-thread(it''s a library in part of a larger project)..please don''t bother suggesting that this is some sort of error in the code or the multi-threading, that is NOT the case I can assure you..the only changes made were the renaming of the function to add an additional overloaded version.. To make things more fun, this particular module MUST be fast so I haven''t even bothered turning optimizations off..I could just leave the printf statement in there(that specific function does NOT need to be fast thank god), but I''d rather determine what the problem is with MSVC and Windows, and change my code to accomodate whatever design problem MS has with their multi-threaded architecture.. If anyone wants to take MS''s side here, feel free..the win32 platform has definitely gotten better, but it really frustrates me when I spend several hours out of my life to isolate a crash that I have little or no control over fixing, other than to "work around" the quirks of the win32 multi-threaded architecture.. Well I don''t want to "work around" this, I want the code that I wrote to be compiled and executed as I wrote it..if it crashes, the OS should be able to give me a legitimate reason why.. Does anyone have any sugggestions other than "Windows is inherently unstable, deal with it, leave the printf statement" ? I want a REAL solution to this. Are there any MS people here who can at least point me in the right direction? (btw I have been searching the MSDN library with no results)..at the very least, when the OS chokes and all I have is someone else''s assembly output to debug, is there any way to determine the last bit of MY code that was called? I will appreciate any information anyone can provide.. Thanks, -MM "Like all good things, it starts with a monkey.."

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
Sounds like you might be trying to write to an array and going out of bounds on it. A Debug build will do bounds checking for you but in Release you are on your own.

Share this post


Link to post
Share on other sites
Make sure to call fflush on stdout after every printf, otherwise the output gets buffered and you may never see it. If you haven''t already done this, report back with the results .

Share this post


Link to post
Share on other sites
quote:
Original post by monkeyman
Does anyone have any sugggestions other than "Windows is inherently unstable, deal with it, leave the printf statement" ?

How can you be so very sure that the error is not of your own making? If you are invoking undefined behaviour anywhere within your code, that would adequately explain what you have described. It would also explain why the code worked before and does not work now. Do you have any lint or bounds checker type products?


[C++ FAQ Lite | ACCU | Boost | Stroustrup on Learning C++]

Share this post


Link to post
Share on other sites
you have successful clobbered your stack, by renaming the function (and if there is function pointer use anywhere) you possibly are passing an incorrect number of parms to the function. worse yet, it could modules from the other part of the project doing this because you renamed a fucntion just to overload it. this would screw things over, big time. or you could just be going out of bounds in an array or struct clobbering your return address. using a pointer whose value is NULL perhaps? seems to me its a problem with you misusing the stack, since inserting a printf would change what is on the stack and move positions of things in memory enough to "fix" (really make not apparent) the problem. if you are using ANY inline asm, make sure its being done properly and you are not modifing registers and things on the stack that you should not be modifing. an idea would be to check this single function in an app by itself, where you are 100% sure you can control all inputs to the function. you would be surprised how easily you can screw up the stack, just calling printf (or any varible arg function) with the wrong number of parms will clobber things.

also, this is definatly not a quirk with msvc++ or win32 unless you are doing some real low level undocumented features of win32 stuff. in that case, you should consider not using undocumented features.

just a side note, you dont need to rename a funtion to add overloaded versions, since overloading a function in c++ you can keep the same name as long as the args are different.

[edited by - a person on April 19, 2002 6:26:27 PM]

Share this post


Link to post
Share on other sites
AFAIK MSVC offers debug features for the release mode too (breakpoints, stepping, etc.) You just have to change some project settings to include debug information. That should clear the printf problem, but I don''t know if including debug information will have another effect on the error.

Share this post


Link to post
Share on other sites
quote:
Original post by monkeyman
I have some fairly straightforward(explicit code, no macros, jump tables, etc.) single-threaded C code that crashes in release mode. The code is completely solid, nothing funny going on.

The code has a bug.

quote:
The error states that the instruction referenced memory at 0000, etc. the memory cannot be written. It doesn''t crash in debug mode.

The code tries to write to a pointer that''s got a bad value in it.

quote:
After tracing through the code one function at a time(which basically meant logging before and after every function call),

No, it means stepping through with your debugger.

quote:
I finally isolated it down to one specific section of code. The problem is, I can''t go any further, because the program doesn''t crash if I printf before OR after this function call.

printf()?

You do know what a debugger is, right?

quote:
The code itself is solid, and has not changed. The only change that was made was that the function was renamed(in order to add an additional overloaded version).

The code plainly isn''t solid. You said "C", C has no overloads.

quote:
If I try to debug in release mode, the debugger states that the app crashes in NTDLL..of course, adding a printf statement ANYWHERE within the function, or before, or after, ''fixes'' the problem..

You do know what a call stack is, right?

quote:
I''ve cleaned and rebuilt the project(both debug and release), no difference..there is no problem in debug mode, and I can''t really trace anything in release mode, because if I try to log any values(looking for bad pointers, etc.), they will of course be fine because I am printing something..

So use your debugger.

quote:
I can''t even debug the raw assembler output because it''s not my code. Since I can''t check the actual values of any of the data(logging anything makes it work), I tried adding checks after each and every single memory allocation to find the one that turns up NULL, and there are none, so apparently this memory referenced at 0x0 is not one of MY pointers..

Fuck "checks". Use your debugger.

quote:
So, what I would like to do is find out exactly where Windows and MSVC++ has decided to interpret/execute something other than the instructions I actually coded, and do something a little more structured than adding a printf statement..

USE YOUR DEBUGGER.

quote:
btw the code itself is single threaded(only one process going on), but the code generation settings are for multi-thread(it''s a library in part of a larger project)..please don''t bother suggesting that this is some sort of error in the code or the multi-threading, that is NOT the case I can assure you..the only changes made were the renaming of the function to add an additional overloaded version..

Given that you said "C", this is plainly impossible. C can''t do overloading.

quote:
To make things more fun, this particular module MUST be fast so I haven''t even bothered turning optimizations off..I could just leave the printf statement in there(that specific function does NOT need to be fast thank god), but I''d rather determine what the problem is with MSVC and Windows, and change my code to accomodate whatever design problem MS has with their multi-threaded architecture..

The problem is that your code is broken.

The "multithreaded" thing has nothing to do with anything.

quote:
If anyone wants to take MS''s side here, feel free..the win32 platform has definitely gotten better, but it really frustrates me when I spend several hours out of my life to isolate a crash that I have little or no control over fixing, other than to "work around" the quirks of the win32 multi-threaded architecture..

What the fuck are you blathering about?

quote:
Well I don''t want to "work around" this, I want the code that I wrote to be compiled and executed as I wrote it..if it crashes, the OS should be able to give me a legitimate reason why..

It is. It''s telling you that you''re trying to write through a null pointer.

quote:
Does anyone have any sugggestions other than "Windows is inherently unstable, deal with it, leave the printf statement" ?

Yes. Fix the code.

quote:
I want a REAL solution to this. Are there any MS people here who can at least point me in the right direction? (btw I have been searching the MSDN library with no results)..at the very least, when the OS chokes and all I have is someone else''s assembly output to debug, is there any way to determine the last bit of MY code that was called?

Yes. Use your debugger.

Share this post


Link to post
Share on other sites
If you can afford it, get a memory checker like BoundsChecker.

Otherwise, follow Dr Pizza advice, compile with debugging info in release mode, install windows debug symbols, and run the debugger.

Share this post


Link to post
Share on other sites
Now we're getting closer

I guess I should clarify things:

The 'overloaded' function is overloaded in what it actually does, I wasn't referring to the C++ function name overloading. I apologize for using the term loosely..

As for any problems with the code itself(invalid memory writes, etc.), I'm well aware they might exist Somewhere Else In The Project, but I know they don't exist in THIS particular section of code. Of course, I can't trace it any further without seeing what's going on..I have had build problems(this app is about 20 or so libraries that get constantly updated)before, and I have seen these same problems occur because of it..of course, now a clean and rebuild all isn't helping..

DrPizza, I appreciate your suggestion to use the debugger. I'd really like to. Can you please tell me where I can find the instructions for including debug information in the release build? I do know that this can be done, unfortunately I haven't found out how or where.

I'm sorry if this is obvious to everyone but me, but a big reason why I posted is because I could NOT find a way to watch this stuff in the debugger. I haven't found a clear reference in my msdn about how to do it(I'm sure it's in there), and I haven't seen anything in the project settings.

As always, thanks to anyone who responds.


"Like all good things, it starts with a monkey.."

[edited by - monkeyman on April 20, 2002 3:16:11 PM]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!