7

Is there a way to determine the stack depth of all functions being executed in javascript by using javascript itself?

I'm thinking it might involve modifying the Function prototype, but I really don't have any idea.

Additionally, it would be nice to be able to break anytime the stack depth were sufficiently high.

The reason for this is that I have a stack overflow error in IE which is apparently not debuggable. I'm lazy and I would rather not have to hunt through the code that I'm maintaining to find the cause.

Thanks for assisting my laziness.

1
  • You could tell one function to another and increment a global variable until the browser itself throws a stack overflow error. Then you print your counter variable and you have a crude value for the stack depth. Commented Dec 5, 2011 at 21:36

2 Answers 2

5

ECMAscript supported for quite a while the Function.prototype.caller property. Even if its deprecated in ES5 strict, IE should still support it. So you could basically loop your way up through the involved functions.

function one() {
   two();
}

function two() {
   three();
}

function three() {
    var caller = three.caller;

    console.log('caller was: ', caller.name);

    while( caller = caller.caller ) {
           console.log('caller was: ', caller.name);
    }
}

(function outer() {
    one();
}());

That will output:

caller was: two
caller was: one
caller was: _outer

So, if you know in which function an error happens, that way you get the answer all the way up how this method was originally called. If you're just after the depth, you can just count how many interations over the caller.caller property were made. At least IE8 should support the "debugger" statement, which you could just call in that script to bring the debugger on the stage.

Sign up to request clarification or add additional context in comments.

6 Comments

This looks a lot like what I'm going for... but the thing is that I would need to somehow apply this to all functions without having to add it to their code. Do you know what I mean? Thanks.
@user420667: I don't think there is any "easy" way to do that over the Function.prototype. You basically would need to do a recursive loop over all objects (starting with window) and check for functions. If you found one, you need to hook/patch the method and call the above provided code. Might work.
oh, ok.. so something like for each function... newFunction = function(){ oldFunction(args); if(CallerDepth() > MaxAllowedDepth){ debugger;} }; oldFunction = newFunction; ??? I dont' think that's quite right. Also, like you said, making sure that somehow that gets called before any other function is, and also making sure that the list of functions to iterate through is created before modifying any functions.
"Even though it's deprecated in ES5 strict". Not enough of a warning that this should not be used.
@jAndy debugging purpose is fine. You should however run es5 strict in production
|
4
function stackDepth() {
  var c=stackDepth.caller, depth=0;
  while (c) { c = c.caller; depth++; }
  return depth;
}

Chrome seems to think that the stack depth from the console is already 3, so maybe for each JavaScript environment you'd need to determine an initial baseline depth and subtract from that.

stackDepth(); // => 3
(function(){return stackDepth();})(); // => 4

2 Comments

interesting. I wonder what the 3 higher level objects are. window? document?
Probably <html>, <body>, <script> or something like that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.