Ok, folks. I've never encountered this before and it boggles the mind and is illogical. I have a somewhat complex loop and I want to try and see if everything is working by putting some printf statements. I look the intermediate products using printf and verify that the answer is ok. Then, when I comment out the printf to the intermediate products, the answer is WRONG. Has anyone ever encountered this? This is driving me insane and I don't see how the printfs could change an answer.... X_x If it helps, I am using a c/c++ compiler for a DSP. Thanks for any advice..
Here is a snippet...
printf("splitBackground = %d, numWindowPoints = %d\n", splitBackground, numWindowPoints);
splitBackground = splitBackground/numWindowPoints;
printf("%d ", splitBackground);
This is good but when I comment out the first line of code, it turns out to be hugely incorrect. :(
Most likely you've made a mistake in your code that results in undefined behavior. And "undefined" implies "it might work under some circumstances".
Why would inserting a printf make it work? Some possibilities:
It changes the timing relationships between different parts of your program, or between your program and the rest of the world.
The printf call inhibits a compiler optimization that might otherwise take place.
The printf call changes the internal state of the standard library in a way that prevents the bug from occurring.
The printf call interacts with the hardware in a way that prevents the bug from occurring.
(Note that many of the same considerations are also true when running under a debugger -- thus the term "heisenbug": a bug that only occurs when you're not watching for it.)
Personally I would print to stderr, not stdout.
If you're using an IDE I would take full advantage of the debugger to try to resolve your issues. Like in Visual Studio 2010, Eclipse or Netbeans, add break points and slowly step through the lines of code.
your printf's can have side-effects (modify some data leading to correct results). in any case it would be very helpful to look at simplified example of the problematic code
Probably, this is stack corruption, and your printfs somehow extend the stack or trigger a guard page or something. But it's hard to say anything without the rest of the code.
Related
I´m searching information about how to compare two codes and decide if the code submitted by someone is correct or not (based on a solution code defined before).
I could compare the output but many codes may have the same output. Then I think I must compare someway the codes and give a percentage of similitude.
Anybody can help me?
(the language code is C but I think this isn´t important)
Some of my teachers used online automated program grading systems like http://web-cat.org/
In the assignment they would specify a public api you must provide, and then they would just write tests against your functions, much like unit tests. They would intentionally pick tests that would exploit boundary conditions and other things students are notorious for not thinking about, and just call your code with many different inputs to try to get your code to fail.
Sometimes they would hardcode the expected values, other times they would allow values within a range, and other times they just did the assignment themselves and made it so your own code has to match the results produced by their code.
Obviously, not all programs can be effectively graded this way. It's also kinda error prone in that sometimes even the teacher made a mistake and overflowed an int or something, then the correct student submissions wouldn't match the teachers incorrect results. But, a system doesn't need to be perfect to be useful. But I think this raises an important point in that manually grading by reading the code won't necessarily reveal all mistakes either.
Another possibility is copy the submitted code, strip out all of the white space and search for substrings that must exist for the code to be correct and/or substrings that cannot exist for the code to be considered correct. The troublesome bit might be setting up to allow for some of the more tricky requirements such as [(a or c),((a or b) and c),((a or b) and c)], where the variables are the result of a boolean check as to if the substring related to the variable exists within the code.
For example, [("printf"),("for"), (not "1,2,3,4,5,6,7,9,10")], would require that "printf" and "for" be substrings in the code, while "1,2,3,4,5,6,7,9,10" i I'm not familiar with C, so I'm I'm assuming here that "printf" is required to be able to print anything without involving output streams, which could be accounted for by something like [("printf" or "out"),("for"), (not "1,2,3,4,5,6,7,9,10")], where "out" is part of C code required to make use of output streams.
It might be possible to automatically find required substrings based on a "correct" code, but as others have mentioned, there are alternative ways to do things. Which is why hard-coding the "solution" is probably required. Even so, it's quite possible that you'll miss a required substring, and it'll be marked as wrong, but it's probably the only way you can do what you ask with some degree of success.
Regular expressions might be useful here.
I am writing a relatively simple C program in Visual C++, and have two global variables which I would like to know the values of as the program runs. The values don't change once they are assigned, but my programming ability is not enough to be able to quickly construct a text box that displays the values (I'm working in Win32) so am looking for a quick routine that can perhaps export the values to a text file so I can look at them and check they are what they ought to be. Values are 'double'.
I was under the impression that this was the purpose of the debugger, but for me the debugger doesn't run as the 'file not found' is always the case.
Any ideas how I can easily check the value of a global variable (double) in a Win32 app?
Get the debugger working. You should maybe post another question with information about why it won't work - with as much info as possible.
Once you have done that, set a breakpoint, and under Visual C++ (I just tried with 2010), hover over the variable name.
You could also use the watch window to enter expressions and track their values.
If your debugger isn't working try using printf statements wherever the program iterates.
Sometimes this can be a useful way of watching a variable without having to step into it.
If however you wish to run through the program in debug mode set a breakpoint as suggested (in VS2010 you can right click on the line you want to set a breakpoint on).
Then you just need to go to Toolbars -> Debug Toolbar.
I usually like to put #ifdef _DEBUG (or write an appropriate macro or even extra code) to do the printing, and send to the output everything that can help me tracking what the program's doing. Since your variables are never changing, I would do so.
However, flooding the console with lots of values is bad imo, and in such cases I would rely on assertions and the debugger - you should really see why it's not working.
I've done enough Python and Ruby to tell you that debugging a complex program when all you have is a printf, although doable, is extremely frustrating and takes way longer than what it should.
Finally, since you mention your data type is double (please make sure you have a good reason for not using floats instead), in case you add some assertion, remember that == is to be avoided unless you know 100% that == is what you really really want (which is unlikely if your data comes from calculations).
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I had my code working earlier in the day on the unix machine, but when compiled under windows it gave me completely strange and incorrect output.
Since our code is going to be marked based on compilation on unix I thought hey that's good enough. But now I just finished refactoring my code (basically just adding comments, getting rid of variables which were never used in the program and getting rid of some functions which I wrote to test the program) and now suddenly my code seems to be giving me the proper output on windows and wrong output on unix.
Note that I have done nothing to modify the functionality of the code.
After spending so many hours working on this banging my head against Seg Fault errors through the week, this last minute bug is going to put it all to waste. What am I supposed to do when the bug is seemingly appearing at random?
Edit: The program is supposed to read a file similar to an html file and print out the tables. I'm loading the data of each individual cell onto a node in a Linked List and then printing out the info based on an algorithm. The output is working fine on windows now but not on unix. I don't even know what part of the code I need to look since I have no idea what's causing this.
Based on the amount of information you supplied (next to none), the best guess is to look for uninitialized variables. That will produce different output on different platforms, and is a common beginner mistake in C.
I suggest you use gdb to debug your code and check where the segmentation fault is arising. That will give you a good hint of were to start looking, even though you don't remember to have done any modification.
There is plenty documentation on the web.
These are the basics:
shell> gdb myprogram
gdb> backtrace #lists the steps until the segmentation fault arises
gdb> select 2 #You can select any step you want (e.g. 2)
gdb> print number #print variables to hack around
There are a lot of features for gdb. I think this will give you a hint quickly.
Don't forget to use a version control system the next time. It's a safe and nice way of having your code organized and clean, and off course!, to avoid these terrible accidents.
(SVN or GIT are cool enough)
Step 1, make a copy of everything.
Copy the entire project somewhere. Make a note of what state the project was in when you made that copy and the date:time. DO NOT edit that copy. You may even make the files unwritable if you want. You need to be able to see what you have changed as well as go back to it. Even though the program does not currently work on Unix, it does work under Windows, so you know that it does have some merit and is close to being useful to turn in. When I get upset at a program I am writing or at the compiler for not understanding it (this happens a lot less now then it did 10 years ago) I tend to lose track of what all I am changing, so changing it back becomes difficult. Using some type of version control (even just keeping extra copies around) will help you to keep track of what you have changes so when you make a mistake you can unmake that mistake pretty easily. Differencing tools, like diff are very helpful when you know how to use them. For right now you might want to try:
diff --minimal --side-by-side --ignore-all-space old_file.c new_file.c | less
Hopefully you are using a diff that supports those options because I think that they may be the most helpful for you in the short time that you have. If you find that you need to fit more on the screen and your terminal window is large you can also add in the --width= command and give it a number of characters in a line on your terminal.
Anyway, make and keep lots of copies of your code until you know that you won't need them anymore (and maybe even then).
If you have graphical access see if kdiff3 is available. It may be easier for you to use quickly. The 3 in its name refers to the ability to compare 3 versions of a file at one time (a common starting point and two edited versions of that file) and is useful, but you can learn about that later. It is perfectly able to compare just two versions of a file and produce decent output.
Step 2 Don't ignore warnings
I suggest that you compile it with the highest warning level possible with your compiler and DO NOT ignore any warnings. If you already have warnings without telling the compiler to issue more warnings then examine those first. Warnings are there for a reason, and only occasionally should you ever encounter code the produces warnings that should just be ignored (and even then I usually add a comment about the expected type of warning and why it is not an error). With gcc you can add the -Wall option to the compile command to issue all warnings.
gcc -Wall my_program.c -o my_program
Some may not make sense to you, but you can at least look at the code and see what might be unclear about it in the vicinity of the warning line.
step 3 Use simple lines of code
Something that will make warnings easier to understand is using very simple to understand lines of code. Trying to fit too much functionality into one line of code makes it so that any warning or error message about that line of code is much more difficult to understand.
step 4 Use temporary variables
Temporary variables don't necessarily mean "my program uses more memory" but they do often mean the compiler gives more meaningful warnings because the data-types of variables in expressions are much clearer.
step 5 Use functions
This is just a continuation of the philosophy from 3 and 4. Functions make things easier to understand. They also make it so that often when you find an error and fix it you don't have to worry about having copies of the erroneous code elsewhere in the program that also needs to be fixed (though you should still search for similar code just to be sure).
step 6 assert
There is a macro (like a function, but not quite) called assert that lives in #include <assert.h> and can help you find all kinds of errors by making your program fail earlier than it otherwise would. This sounds bad, but very often (especially with memory related problems like segmentation faults (SIGSEGV) ) programs are in a fatal state well before they die. Using assert helps you to move their death to an earlier place so that you can see what their fatal mistake was, rather than just seeing the result of it.
assert takes as its parameter a boolean expression -- any comparison, integer, floating point number, or pointer will do. Anything that you could use as a condition in an if or while will do. If this expression is false (0 or NULL) then your program will die right there and on many systems it will give you a helpful error message about where the assertion that killed the program was located and maybe even what the assertion was. There is another helpful thing that this causes which I'll talk about in a little bit, but for now, to use assert you just do:
assert(x < y);
and if x is not less than y the program will abort (actually call the abort function).
This is helpful for things like:
int clear_buffer(char * buffer, unsigned len)
{ /* len should be size_t but I don't want to explain that right now */
assert(buffer);
memset(buffer, 0, len);
}
Step 7, Use a debugger
If you have gdb on your Unix system then GREAT. If not, you probably have some other debugger than you can learn how to use. Many Unix C compilers take the -g option to mean "include debugging symbols", so add that to the other options you are passing to the compiler and recompile your program, and then do:
gdb ./myprogram
Which will print some stuff and then prompt you with:
(gdb)
Then you can set break points and all kinds of good stuff, but since you are in a hurry and getting crashes just do:
(gdb) r
Include any arguments after the r that you would be passing to your program when you normally ran it. gdb will then run your program until something odd happens. The something odd, in this case, should be a SIGSEGV (what UNIXes do to your program when it tries to access memory addresses that it shouldn't). gdb will then prompt you with (gdb) again. You can then do:
(gdb) bt
bt stands for back trace and gdb will print out the call stack, meaning all functions that were called to get to the current function. You should see main near the bottom. Look for the first function near the top that is a function you wrote. This is where you need to start trying to find errors. If the top function on the list is not one of yours then try issuing:
(gdb) up
Which will make it examine the previous function on the call stack. Once in one of your functions say:
(gdb) list
And it will show you some code around the area where things are wrong.
To exit gdb you do:
(gdb) quit
And answer Y if it ask you if you really want to quit.
If you were to use assert and that killed your program then you would not end up with quite as much library stuff on top of the call stack to confuse you.
Sadly 3, 4, and 5 mess up the ability to get good info from diff so I suggest trying to limit your adding of this programming style into places where you are having errors or warnings already (at least for now).
I hope that this helps
First of all, we will need your code to see what's going on. But if what you described is true then it is most likely that your code contains what's called undefined behavior. Undefined behavior can occur due to too many reasons, such as crossing array boundaries, incorrectly deleting pointers etc.etc. So, without code nothing can be said
Run it through valgrind.
I can guarantee you will find your error with valgrind.
If you've got access to a unix or linux machine, you should never release code that you haven't run through valgrind, even if the code works.
With the data you've provided, here is my solution.
Take a break and zone out of the problem domain for a while.
Use a debugger, step through the program, identify where it is segfaulting.
Print data at the point of the segfault and validate it.
That should solve the problem.
Compile your code with all warnings on.
Don't hide warnings with bogus casts, but take them seriously and resolve the real problems.
Use different compilers. On linux clang is a good alternative and gives way more indications than gcc.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Should a function have only one return statement?
Hello,
gcc 4.4.4 c89
Is it good programming practice to return from 1 point in a function.
I have written a function below. However, I am returning from 2 possible points.
Is this good style?
static int init_data(struct timeout_data_t *timeout_data)
{
if(timeout_data == NULL) {
fprintf(stderr, " [ %s ] [ %d ]\n",
__func__, __LINE__);
return FALSE;
}
/* Assign data */
timeout_data->seconds = 3;
timeout_data->func_ptr = timeout_cb;
return TRUE;
}
If it aids readability, then there is nothing wrong with it.
Personally, I write this kind of code all of the time.
This is an ongoing religious-style debate without an accepted answer. There are many people on both sides of the argument, who feel strongly about it.
I don't think there's anything wrong with it personally, but the best approach is to go with the style guidelines of your team, if they have some (and if not, just ask about it. If anyone recoils in horror, it would be kinder to stick to single-return-point).
I've had managers that lived and died by the 1 return policy for the sake of "readability", even though it's much more readable in some cases without it.
The bottom line is... if the man that signs your paycheck says you're only going to use 1 return, use 1 return. The best way to do this is
type myfunc(params) {
type result = defaultValue;
// actual function here, word for word
// replace "return $1" with "result = $1"
return result;
}
This is a valid way to do things in their book, and will smile at your 1 return policy adherence. Of course, you know using this adds ZERO readability because all you've done is replace "return" (which is syntax highlighted) with "result =" which is not. But you've made your boss happy, which when you break it all down is what development is about anyway, right? :-)
In straight C, I think that error checking/parameter verification at the top of the function with a return (or possibly even multiple return points in the parameter verification) results in reasonably clean code. After that point, though, my opinion is that it is a good idea to have one single return at the bottom of the function. That helps avoid problems with cleanup (e.g., freeing of memory) that might be allocated in the workings of the function.
There's nothing inherently wrong about having more than one exit point, especially when you're returning on errors. Returning immediately usually makes for clearer code than having the whole thing wrapped in an if/else statement and setting some result flag to be returned at the end. (When you see "return result;", you have to look through all of the earlier code to see how and when result gets set. More moving parts == less clarity.)
You've tagged your questions as "C" which makes a difference.
In C you might write code such as
open file
process data
close file
If you put a return in the middle of the process data section then you're likely to skip the essential cleanup so it might be considered bad practice to have multiple return points because it's very easy to mess up.
If it was C++ then its best practice to let destructors handle cleanup so it's not nearly such a potential problem so this advice is somewhat obsolete in c++
As Oded and Andrzej Doyle pointed out there is nothing wrong with it.
They is no such thing as a golden rule when it comes to this.
The first an most important thing you have to keep in mind when writing code is that some one else will have to read it and make sense out of it. Maybe you will have to go about it in a couple of months, and if you have made a mess you will regret it.
Personally I always:
if the code is new used the coding style everybody else is using in the project.
If editing others code used the coding style already implemented there.
Avoid above all code optimizations (the compiler is best at that).
keep it clean and lean.
If your function is small enough (10-15 lines), as it should be :), then it really doesn't matter if you use a single return point or multiple one. Both are equally readable.
Problems start cropping up with badly designed large functions. In such cases both the styles, returning from a single point, and returning from multiple points, further complicates the function, although even in such cases I prefer returning early and returning at multiple points.
It's often the case that you have to check for several conditions etc before you start with the real work, and then you are tempted to do an early return, as in your code. I think this is fine for short methods, but when it gets more complicated I'd suggest to break your code in a "setup and check" method and a "real work" method, both having only one exit. Of course as long as it's readeable, it's fine to have multiple returns (e.g. in a long switch statement).
Failing (and thus returning) early is a very very very good practice. All the code after the checks is free of a lot of potential errors.
I was writing a function to figure out if a given system of linear inequalities has a solution, when all of a sudden it started giving the wrong answers after a seemingly innocuous change.
I undid some changes, re-did them, and then proceeded to fiddle for the next two hours, until I had reduced it to absurdity.
The following, inserted anywhere into the function body, but nowhere else in the program, fixes it:
if(0) {
__asm__("nop\n");
__asm__("nop\n");
__asm__("nop\n");
__asm__("nop\n");
}
It's for a school assignment, so I probably shouldn't post the function on the web, but this is so ridiculous that I don't think any context is going to help you. And all the function does is a bunch of math and looping. It doesn't even touch memory that isn't allocated on the stack.
Please help me make sense of the world! I'm loathe to chalk it up to the GCC, since the first rule of debugging is not to blame the compiler. But heck, I'm about to. I'm running Mac OS 10.5 on a G5 tower, and the compiler in question identifies itself as 'powerpc-apple-darwin9-gcc-4.0.1' but I'm thinking it could be an impostor...
UPDATE: Curiouser and curiouser... I diffed the .s files with nops and without. Not only are there too many differences to check, but with no nops the .s file is 196,620 bytes, and with it's 156,719 bytes. (!)
UPDATE 2: Wow, should have posted the code! I came back to the code today, with fresh eyes, and immediately saw the error. See my sheepish self-answer below.
Most times when you modify the code inconsequentially and it fixes your problem, it's a memory corruption problem of some sort. We may need to see the actual code to do proper analysis, but that would be my first guess, based on the available information.
It's faulty pointer arithmetic, either directly (through a pointer) or indirectly (by going past the end of an array). Check all your arrays. Don't forget that if your array is
int a[4];
then a[4] doesn't exist.
What you're doing is overwriting something on the stack accidentally. The stack contains both locals, parameters, and the return address from your function. You might be damaging the return address in a way that the extra noops cures.
For example, if you have some code that is adding something to the return address, inserting those extra 16 bytes of noops would cure the problem, because instead of returning past the next line of code, you return into the middle of some noops.
One way you might be adding something to the return address is by going past the end of a local array or a parameter, for example
int a[4];
a[4]++;
I came back to this after a few days busy with other things, and figured it out right away. Sorry I didn't post the code sooner, but it was hard coming up with minimal example that displayed the problem.
The root problem was that I left out the return statements in the recursive function. I had:
bool function() {
/* lots of code */
function()
}
When it should have been:
bool function() {
/* lots of code */
return function()
}
This worked because, through the magic of optimization, the right value happened to be in the right register at the right time, and made it to the right place.
The bug was originally introduced when I broke the first call into its own special-cased function. And, at that point, the extra nops were the difference between this first case being inlined directly into the general recursive function.
Then, for reasons that I don't fully understand, inlining this first case led to the right value not being in the right place at the right time, and the function returning junk.
Does it happen in debug and release mode build (with symbols and without)? Does it behave the same way using a debugger? Is the code moultithreaded? Are you compiling with optimizations? Can you try another machine?
Can you confirm that you are indeed getting different executables when you add the if(0) {nops}? I don't see nops on my system.
$ gcc --version
powerpc-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5490)
$ cat nop.c
void foo()
{
if (0) {
__asm__("nop");
__asm__("nop");
__asm__("nop");
__asm__("nop");
}
}
$ gcc nop.c -S -O0 -o -
.
.
_foo:
stmw r30,-8(r1)
stwu r1,-48(r1)
mr r30,r1
lwz r1,0(r1)
lmw r30,-8(r1)
blr
$ gcc nop.c -S -O3 -o -
.
.
_foo:
blr
My guess is stack corruption -- though gcc should optimize anything inside an if(0) out, I would have thought.
You could try sticking a big array on the stack in your function and see if that also fixes it -- that would also implicate stack corruption.
Are you sure you're running what you think you're running? (dumb question, but it happens.)
Looks like you will need to put in some hard work and elbow grease
Your problem sounds similar to something I have debugged in the past where my app was running regular ... when out of nowhere it jumped to a different part of the app and the callstack got completely messed up ( however this was embedded programming )!
It sounds like you are spending your time "thinking" about "what should be happening" ... when you should be "looking" at "what is actually happening". A lot of the times the hardest bugs are things that you would never think "should happen".
I would approach the problem like so:
Break out your favorite debugger
Start stepping through your code and watch the call stack and local variables and look for suspicious activity
Make the system fail
Focus in to where the system is failing
Focus on iterating your code changes:
making code changes that will "make the system fail"
running/debugging and watching
If it runs fine you are looking/trying the wrong thing and you need to try something else. If you make it fail then you have made progress towards finding the bug.
If you don't know where or how the system fails you will not be able to solve the problem.
This will be a good opportunity to build your debugging skills. For more help on building your debugging skills read check out the book "9 rules for debugging".
Here is a poster from the book:
(source: google.com)
Concrete suggestions:
If you think it is the compiler, then run a different platform/OS/compiler.
Once you have ruled out the platform/OS/compiler, then try restructuring the code. Look for the "clever" code parts and see if they are actually doing what the code meant to do... maybe the clever solution wasn't actually clever and is doing something else.
I am the author of "Debugging" so kindly referenced above by Trevor Boyd Smith. He has it right -- the key rules here are #2 Make It Fail (which you seem to be doing okay), and #3 Quit Thinking and Look. The conjectures above are very good (demonstrating mastery of rule #1 -- Understand the System -- in this case the way code size can change a bug). But actually watching it fail with a debugger will show you what's actually happening without guesswork.
Break out that one function into a separate .c file (or .cpp or whatever). Compile just that one file with the nops and without them, to .s files and compare them.
Try an old version of gcc. Go back 5 or 10 years and see if things get stranger.