如何处理stackoverflow? [英] How to handle a stackoverflow?

查看:174
本文介绍了如何处理stackoverflow?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在修改我的postscript解释器中的错误处理,当一个堆栈已满时,我无法想出处理程序执行的方式。



我使用的后记级处理程序是Frank Merritt Braswell描述的标准,



  /。error {
// $ error exch / errorname exch put
// $ error exch / command exch put
// $ error / newerror true put
// $ error / errorname get / VMerror ne {
// $ error / ostackarray get null eq {
// $ error / estackarray 250 array put
// $ error / ostackarray 6000 array put
// $ error / dstackarray 30 array put
} if
count
// $ error / ostackarray get exch 0 exch getinterval astore
// $ error exch / ostack exch put
// $ error / dstack // $ error / dstackarray get dictstack put
// $ error / estac k // $ error / estackarray get execstack
dup length 2 sub 0 exch getinterval put
// $ error / ostack get aload pop
} if
// $ error / initializing $ {
}
$ b所以它需要在操作数堆栈(对于$错误字典和名称和东西)和执行堆栈(对于程序体,如果执行)的空间。所以如果任一个堆栈溢出,这个空间应该从哪里来?



我试图首先解决execstackoverflow,因为较少的操作符使用execstack而不是使用操作数堆栈。我定义了一个缓冲区大小

  #define ERRDEPTH 5 / *在execstack上保留的空格用于错误处理* / 
所有exec运算符函数都添加到空间检查中,

例如。这里是 exec 运算符。

  void Aexec(state * st,object x){(void)st; 
if((tes-es)+ 1 + ERRDEPTH> = ESSIZE)error(st,execstackoverflow);
pushe(x);
}

然后解释器循环检查一个更小的大小(所以它不'在尝试运行处理程序时,t会触发更多的错误。)

  bool eval(state * st){
。 ..
/ *工作空间* /
if((tes-es)+ 2 / * + ERRDEPTH * /> ESSIZE)error(st,execstackoverflow);
...

但它不起作用(SEGFAULT),除非我清除一些在C级错误处理程序中的空间,就在它在execstack上推送(调度)PS处理程序之前。

  ... 
if(e == execstackoverflow){/ * make some room! * /
(void)pope(); (无效)教皇(); (无效)教皇(); (无效)教皇(); (无效)教皇();
(void)pope(); (无效)教皇(); (无效)教皇(); (无效)教皇(); (无效)教皇();
}
...

但是现在我把宝宝扔了与洗澡水!堆栈顶部的这些条目可能只是修复错误的关键信息,我刚把它们抛到了深渊。



任何人都可以建议一个更好的

解决方案

不必太了解你的代码,我会想象创建一个可以扩展自身的错误堆栈将是解决方案。


I'm trying to fix up the error handling in my postscript interpreter, and I'm having difficulty coming up with ways for the handler to execute when one of the stacks is full.

The postscript-level handler procedure I'm using is the "standard" one described in Frank Merritt Braswell, Inside Postscript.

/.error {
    //$error exch /errorname exch put
    //$error exch /command exch put
    //$error /newerror true put
    //$error /errorname get /VMerror ne {
        //$error /ostackarray get null eq {
            //$error /estackarray 250 array put
            //$error /ostackarray 6000 array put
            //$error /dstackarray 30 array put
        } if
        count
        //$error /ostackarray get exch 0 exch getinterval astore
        //$error exch /ostack exch put
        //$error /dstack //$error /dstackarray get dictstack put
        //$error /estack //$error /estackarray get execstack
        dup length 2 sub 0 exch getinterval put
        //$error /ostack get aload pop
    } if
    //$error /initializing get {
        handleerror
    } if
    interrupt
} def

So it needs space on the operand stack (for the $error dictionary and names and stuff) and execution stack (for the procedure bodies, if executed). So if either stack has overflowed, where is this space supposed to come from?

I attempted to tackle the execstackoverflow first, since fewer operators use the execstack than use the operand stack. I defined a "buffer" size

#define ERRDEPTH 5 /*space reserved on execstack for error handling*/

which all "exec" operator functions add to the space check. Eg. here's the exec operator.

void Aexec(state *st, object x) { (void)st;
    if ((tes-es)+1+ERRDEPTH >= ESSIZE) error(st,execstackoverflow);
    pushe(x);
}

And then the interpreter loop checks for a much smaller size (so it doesn't trigger even more errors while trying to run the handler).

bool eval (state *st) {
    ...
    /* room to work? */
    if ((tes-es) + 2 /*+ ERRDEPTH*/ > ESSIZE) error(st,execstackoverflow);
    ...

But it doesn't work (SEGFAULT) unless I clear up some space in the C-level error handler, just before it pushes (schedules) the PS handler on the execstack.

...
    if (e == execstackoverflow) { /* make some room! */
        (void)pope(); (void)pope(); (void)pope(); (void)pope(); (void)pope();
        (void)pope(); (void)pope(); (void)pope(); (void)pope(); (void)pope();
    }
...

But now I've thrown the baby out with the bathwater! Those entries on the top of the stack might just be the crucial information for fixing the error, and I've just tossed them into the abyss.

Can anyone suggest a better way of going about this?

解决方案

Without knowing too much about your code, I would imagine creating an error stack that can expand itself would be the solution.

这篇关于如何处理stackoverflow?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆