Curiosity: I was writing codes in Learn Ocaml and when I compiled my codes, the compiler says: "Out of stack error". I guess This is due to the amount of codes I wrote. So I'm wondering how can I check how full is the stack? I wrote about 450-500 lines of codes. With couple of new lines.
It could also be the number of codes that's been executed in the stack is taking up all the stack. So I just want to know what cause the problem and how to resolve it? Here is a picture showing the error:
The error went away when I copy only part of the codes in the editor to the toplevel.
The stack utilization doesn't depend on the size of your program or on the number of lines in it, it depends on the runtime behavior of your program, mostly due to looping recursion. For example, this small function will consume a stack of any size:
let rec f () = f () + f ()
In the picture, that you've provided, I can see at least one case of unbound recursion (i.e., a recursion that definitely will not terminate). When you call insert you're applying it to the whole tree m, instead of a subtree. So at each new invocation nothing actually changes, and you're getting an infinite loop.
Related
When I run certain programs using FORTRAN 77 with the GNU gfortran compiler I have come across the same problem several times and I'm hoping someone has insight. The value I want should be ~ 1, but it writes out at the end of a program as something well over 10^100. This is generally a problem restricted to arrays for me. The improper value often goes away when I write out the value of this at some stage in the program before (which inevitably happens in trying to troubleshoot the issue).
I have tried initializing arrays explicitly and have tried some array bound checking as well as some internal logical checks in my program. The issue, to me and my research supervisor, seems to be pathological.
WRITE(*,*)"OK9999", INV,INVV
vs
WRITE(*,*)"OK9999", INV,INVV,NP,I1STOR(NP),I2STOR(NP)
The former gives incorrect results for what I would expect for the variables INV and INVV, the latter correct. This is the 'newest' example of this problem, which has on and off affected me for about a year.
The greater context of these lines is:
WRITE(*,*)"AFTER ENERGY",I1STOR(1),I2STOR(1)
DO 167 NP=1!,NV
IF(I1STOR(NP).NE.0) THEN
INV = I1STOR(NP)
INVV = I2STOR(NP)
WRITE(*,*)"OK9999", INV,INVV,NP,I1STOR(NP),I2STOR(NP)
PAUSE
ENDIF
I1STOR(1) and I2STOR(1) are written correctly in the first case "AFTER ENERGY" above. If I write out the value of NP after the DO 167 line, this will also remedy the situation.
My expectation would be that writing out a variable wouldn't affect its value. Often times I am doing large, time-intensive calculations where the ultimate value is way off and in many cases it has traced back to the situation where writing the value out (to screen or file) magically alleviates the problem. Any help would be sincerely appreciated.
I see that when I open a C++ crash dump in Visual Studio, I find that the call stack points to - either the line from which it jumped to the next frame in that function, or sometimes the next line after the line from which it jumped to the next frame in that function. Why is that? What is the logic behind that?
TIA!
Basically the location of call is not recorded; the location of return is recorded. So the return location is displayed.
The call stack is extracted from the stack. When you call a functiom, the return location in your code where the instruction pointer is going to go when the function finishes is placed on the stack.
The debugger/call stack display software reverse engineers the data on the stack to work out where this return will be. Then pdb files are used to map the location of return to lines of code.
Two branches of one if clause could have different spots where you call a function, but both return at the exact same instruction. Determining which of the two where used to call the function is impractical, while knowing where the function returns to is easy and reliable. And that line is usually enough information to debug the problem.
On top of that, optimizations by the compiler break down the idea that you are runnimg C++ code line by line; you are actually writing code generated by C++ code. An instruction in the generated machine code may correspond to parts of multiple different C++ code lines.
Between the two, having the call stack frames pointing a line off is not rare. Sometimes it is estremely far off; and with identical comdat folding sometimes it is the wrong function entirely.
In order to know the limit of the recursive calls in C++ i tried this function !
void recurse ( int count ) // Each call gets its own count
{
printf("%d\n",count );
// It is not necessary to increment count since each function's
// variables are separate (so each count will be initialized one greater)
recurse ( count + 1 );
}
this program halt when count is equal 4716 ! so the limit is just 4716 !!
I'm a little bit confused !! why the program stops exeuction when the count is equal to 4716 !!
PS: Executed under Visual studio 2010.
thanks
The limit of recursive calls depends on the size of the stack. The C++ language is not limiting this (from memory, there is a lower limit of how many function calls a standards conforming compiler will need to support, and it's a pretty small value).
And yes, recursing "infinitely" will stop at some point or another. I'm not entirely sure what else you expect.
It is worth noting that designing software to do "boundless" recursion (or recursion that runs in to the hundreds or thousands) is a very bad idea. There is no (standard) way to find out the limit of the stack, and you can't recover from a stack overflow crash.
You will also find that if you add an array or some other data structure [and use it, so it doesn't get optimized out], the recursion limit goes lower, because each stack-frame uses more space on the stack.
Edit: I actually would expect a higher limit, I suspect you are compiling your code in debug mode. If you compile it in release mode, I expect you get several thousand more, possibly even endless, because the compiler converts your tail-recursion into a loop.
The stack size is dependent on your environment.
In *NIX for instance, you can modify the stack size in the environment, then run your program and the result will be different.
In Windows, you can change it this way (source):
$ editbin /STACK:reserve[,commit] program.exe
You've probably run out of stack space.
Every time you call the recursive function, it needs to push a return address on the stack so it knows where to return to after the function call.
It crashes at 4716 because it just happens to run out of stack space after about 4716 iterations.
I've been looking around but was unable to figure out how one could print out in GDB the result of an evaluation. For example, in the code below:
if (strcmp(current_node->word,min_node->word) > 0)
min_node = current_node;
(above I was trying out a possible method for checking alphabetical order for strings, and wasn't absolutely certain it works correctly.)
Now I could watch min_node and see if the value changes but in more involved code this is sometimes more complicated. I am wondering if there is a simple way to watch the evaluation of a test on the line where GDB / program flow currently is.
There is no expression-level single stepping in gdb, if that's what you are asking for.
Your options are (from most commonly to most infrequently used):
evaluate the expression in gdb, doing print strcmp(current_node->word,min_node->word). Surprisingly, this works: gdb can evaluate function calls, by injecting code into the running program and having it execute the code. Of course, this is fairly dangerous if the functions have side effects or may crash; in this case, it is so harmless that people typically won't think about potential problems.
perform instruction-level (assembly) single-stepping (ni/si). When the call instruction is done, you find the result in a register, according to the processor conventions (%eax on x86).
edit the code to assign intermediate values to variables, and split that into separate lines/statements; then use regular single-stepping and inspect the variables.
you may simply try to type in :
call "my_funtion()"
as far as i rember, though it won't work when a function is inlined.
I was remote debugging a stack overflow from a recursive function. The Visual Studio IDE only showed the first 1,000 frames (all the same function), but I needed to go up further too see what the cause was.
Does anybody know how to get VS to 'move up' in a stack listing?
Thanks.
I do not believe there is a way to do this via the UI (or even a registry hack). My guess at the reason is showing all of the frames in a stack overflow situation can have a very negative performance impact.
Most stack frames are the result of bad recursion. If this is the case, you can likely set a conditional breakpoint on the target function. Set it to break only when the hit count reaches a certain level. I'd start with a count of around 1,000. You may have to experiment a bit to get the right count but it shouldn't take more than a few tries.
I would suggest replace your debugging method and use logging to handle such problem. You might find it more productive, you just need to carefully choose what and when to print.
Any way analyzing few thousands lines of text will be much faster than going up few thousands stack frames. IMHO.
And you can use David's suggesting to control the amount of data to print (i.e pass relevant information from one recursion cycle to another)
You might also try WinDbg. It's not as friendly, but it sometimes works where the VC debugger doesn't.
I run into this now and then, what I do is add the following line to the function that is being called recursively:
static int nest; if (++nest == 100) *(char*)0 = 0;
The number 100 is arbitrary, often just 10 will work. This limits the recursion, ending it with a seg fault. The debugger should then show you the frames that started the recursion.
You could add a temporary recursion count parameter to the function, and assert when it goes over a maximum value. Give it a default value and you won't need to edit any other source
void f(int rcount /* = 0 */ )
{
Assert(rcount < 1000);
f(count+1);
}
You are trying to solve this the wrong way.
There should be enough stack frames to show you the recurring call pattern. You should already be provided with enough inferential data to figure out how an infinite cycle of calls can happen.
Another hack idea might be to drastically decrease your stack size or artificially increase the size of each frame...