I'm having trouble reproducing a bug where I get a null pointer exception when I call first on a PersistentArrayMap. If I copy and paste the map and call first it works, but when the map is in a ref it doesn't work. Is this some weird behaviour related to laziness (not my own) ?
Update: I cannot produce an example that fails every time, so I am forcing evaluation of everything now and it seems to work
my general game plan when i suspect that i may have been bitten by the lazy bug is to
put doseq around everything until the point of failure starts changing.
ps: pasting a stack trace would help give better answers.
Calling first can never cause an NPE, so the problem is elsewhere. My guess is you tried to deref a ref which was nil:
user=> (first #nil)
java.lang.NullPointerException (NO_SOURCE_FILE:0)
Related
I'm currently dealing with one of the strangest bugs I have ever seen. I have this "else if" statement and inside the else-if I have a line of code that is causing a bug to happen elsewhere (my program is kind of complicated so I don't think it would help to post a short snippet of code here because it would be too difficult to explain -- so I apologize in advance if this post seems rather vague).
The issue is that the line of code that is causing the bug is not being called at all. I put a break point at the line and also put a print statement before it but the program never enters that particular "if-else" statement. The bug goes away when I comment out the line and shows up again when I uncomment it. This leads me to believe that the line must be getting called somehow but my break point and prints suggest otherwise.
Has anyone ever heard of something like this happening? Why would a line of code that is not even being called affect the rest of my program? Are there other ways to detect if the line is being called somehow besides using breakpoints and print statements?
I'm using XCode as my IDE and this is a single threaded program (so it's not some weird asynchronous bug)
PROBLEM HAS BEEN SOLVED. SEE TOP ANSWER
It actually may happen in some cases indeed and I already saw it before. If the bug is some slight buffer overflow then the presence/abasence of that line may make the compiler differently optimize the memory layout (ie. not allocate some variables or arrange them in a different way or place segments differently for example) that will by chance not trigger the problem anymore.
The same applies if the bug is a strange race condition: the lack of that line may change slightly the timings (due to differently optimized code) and make the bug come out.
Very long shot: that code may even somehow trigger a compiler bug. But this may be less the case, but it may.
So: yes it's definitely possible and I already saw it. And if something like this is happening to you and you're 100% sure your code is correct then be very careful since something quite nasty may be hiding in the code.
Not that there is enough information here to really answer this question, but perhaps I can try to provide some pointers.
Optimization. Try turning it off if it is turned on at all. When the compiler is optimizing your code, it may make different decisions when a statement is present vs. when it isn't. Whenever I am dealing with bugs that go away when a a seemingly unrelated code construct is changed, it is usually that the optimizer is doing something differently. I suppose a very simple example would be if the statement accesses something that the compiler would otherwise think is never accessed and can be folded away. The "unrelated" line may take an address of something which affects aliasing information, etc. All this isn't to say that the optimizer is wrong, your code likely still does have a bug, but it just explains the weird behaviour.
Debugging. It is very unlikely that the bug is in this line that is not reached. What I would focus on is setting watch points for the variables that are getting incorrect values (assuming you can narrow it down to what is receiving the wrong value).
These very weird issues often indicate an uninitialized variable or something along those lines. If the underlying compiler supports it, you can try providing an option that will cause the program to trap when an uninitialized memory location is being accessed.
Finally, this could be an indication that something is overwriting areas of the stack (and perhaps less likely other memory areas - heap, data). If you have anything that is writing to arrays allocated on the stack, check if you're walking past the end of the array.
Make sure you're using { and } around the bodies in your if() and else clauses. Without them it's easy to wind up with something like this:
if (a)
do_a_work();
if (b)
do_a_and_b_work();
else
do_not_a_work();
Which actually equates to this (and is not what's implied by the indenting):
if (a) {
do_a_work();
}
if (b) {
do_a_and_b_work();
} else {
do_not_a_work();
}
because the brace-less if (a) only takes the first statement below it for its body.
Commenting out your mystery line may be changing which code belongs to which if-else.
I just was looking up funciton attributes for gcc
(http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html)
and came across the returns_twice attribute.
And I am absolutely clueless in what case a function can return twice... I looked up quickly the mentioned vfork() and setjmp() but continue without an idea how an applicable scenario looks like - anyone of you used it or can explain a bit?
The setjmp function is analogous to creating a label (in the goto sense), as such you will first return from setjmp when you set the label, and then each time that you actually jump to it.
If it seems weird, rest assured, you should not be using setjmp in your daily programming. Or actually... you should probably not be using it at all. It is a very low-level command that break the expected execution flow (much like goto) and, especially in C++, most of the invariants you could expect.
When you call setjmp, it establishes that as a return point, then execution continues at the code immediately following the setjmp call.
At some point later in the code, calling longjmp (with the jump buffer initialized by the previous call to setjmp) returns execution to start from that same point again (i.e., the code immediately following the call the setjmp).
Therefore, the original call returns normally, then at arbitrary later times, execution returns (or at least may return) to the same point again.
The attribute simply warns the compiler of that fact.
I like very much the assert behaviour for testing invariants and pre-conditions in my code. I use it a lot. But now I am developing a library (C++) and I like the client (the programmer who uses the library) to know when he violates the precondition. I think is easier to see the application crashes and fix the problem than just throwing in a undefined behaviour.
I could just use assert in this situation, but when my library is ready a release build will disable the assert macro. I know I can keep it but I'm not sure I want to because there is a lot of internal asserts don't need being tested in release build.
An instance:
Some state machine has a maximum number of states that can be added. The limit is setted by the client in the constructor. Then, the client calls the method addState to add specific states, but of course, he can't add more states than he said initially.
Should I:
Just ignore states after the limit and, probably, start a state machine with undefined behaviour (at least to client perspective)?
Keep assertions alive and put an assertion at that point?
Throw an exception (some std::logic_error, I presume)?
Just print a message to stderr and abort the program?
I don't like 1. very much. The idea is tell the client what is he doing wrong.
Is this a situation to throw a logical error exception?
Is there another, better possibility?
Thanks.
Definitely, if a problem is "detectable", you should do something to inform the "user" of the error (some things are very hard to identify that it's gone wrong)
You use assert when the programmer does something directly wrong, and that is unlikely to happen in "normal use" of the code. E.g. if you have a pointer parameter that mustn't be NULL, doing assert(ptr != NULL) would be a sensible thing, likewise if you have an int that is a count of something, it probably shouldn't be negative (but then it should probably be unsigned?). These type of things don't necessarily need to be that clearly documented - just that the precondition "ptr must not be NULL" or "count should not be negative".
You use exceptions for something that MAY happen in normal running conditions, but really shouldn't. Such as running out of memory, or the "user" trying to add too many things to something that they had a reason to give a reasonable size in the first place. Exceptions should be clearly documented by the description of the function - "If you try to add more states than you have reserved space for, the exception x will be thrown".
I personally would think that a "custom" exception would make more sense than std::logic_error. In this case, perhaps too_many_states? The more distinct your exception is, the easier it is to determine where it came from and what it means. Nothing worse than getting some "generic" exception and not knowing how you ended up there - and when you search for it, there are hundreds of places it could have come from...
Sorry if this sounds like an "It compiles, so it must work!" question, but I want to understand why something is happening (or not happening, as the case may be).
In Project Settings, I set Basic Runtime Checks to Both. The debugger informs me that:
Run-Time Check Failure #2 - Stack around the variable 'beg' was corrupted.
But if I set it to the default, which is none, the program runs and completes normally, throwing no exceptions and causing no errors.
My question is, can I safely ignore this (because MSVC++ could be somehow wrong) or is this a real problem? I don't see how the program can continue successfully when the stack has been screwed up.
Edit:
The function that causes this error looks exactly like this:
int fun(list<int>::iterator&, const list<int>::iterator&);
int foo(list<int>& l) {
list<int>::iterator beg = l.begin();
list<int>::iterator end = l.end();
return fun(beg, end);
}
fun increments and operates on beg and when it returns, beg == end, and when MSVC++ breaks, it points to the closing }.
Edit 2:
I have isolated the problem. In some situations, fun removes some elements from the list who owns the items it iterates. This is what causes the error.
Your question isn't answerable without code to reproduce the problem.
But to give a vague answer to your general problem - If the compiler or debugger detected a problem, you probably have one.
In C++, just because something "goes wrong" doesn't mean your program will crash - it might keep running with completely unpredictable results. It may even complete with the results you desired. But just because it ran well on your system doesn't give you any guarantee for other systems, compilers, times of day, or even for additional runs of the same program.
This is called undefined behavior, and is caused by using the language incorrectly (but not in a way that causes a compile failure). A buffer overrun is only one of dozens of examples.
It turned out something was wrong with my Visual Studio installation, so reinstalling it fixed the problem.
In the following C++ code, it should be impossible for ain integer division by zero to occur:
// gradedUnits and totalGrades are both of type int
if (gradedUnits == 0) {
return 0;
} else {
return totalGrades/gradedUnits; //call stack points to this line
}
however Visual Studio is popping up this error:
Unhandled exception at 0x001712c0 in DSA_asgn1.exe: 0xC0000094: Integer division by zero.
And the stack trace points to the line indicated in the code.
UPDATE: I may have just been doing something silly here. While messing around trying to get VS to pay attention to my debug breakpoints, I rebuilt the solution and the exception isn't happening any more. It seems likely to me that I was stopping in the middle of a debug session and resuming it, when I thought I was starting new sessions.
Thanks for the responses. Would it be appropriate here to delete my question since it's resolved and wasn't really what I thought it was?
It seems like VS might just do this with any integer division, without checking whether a divide by zero is possible. Do I need to catch this exception even though the code should never be able to throw it? If so, what's the best way to go about this?
This is for an assignment that specifies VS 2005/2008 with C++. I would prefer not to make things more complicated than I need to, but at the same time I like to do things properly where possible.
You should try going through this code with VS debugger, and see what are the actual values of those variables.
It turns out this problem was caused by the code I originally had, which did not have the divide-by-zero check, shown here:
return totalGrades/gradedUnits;
The problem was that although I'd updated the code, I was actually still in the same debug session that threw the original error, so the program was still running on the old code and threw the error again every time I restarted it.
The problem was solved by rebuilding the solution, which forced a new debug session. Simply terminating the debug session and restarting it with a rebuild would have solved it too (I just hadn't noticed I was still in the session).