【问题标题】:How to handle a stackoverflow?如何处理堆栈溢出?
【发布时间】:2011-11-02 05:07:16
【问题描述】:

我正在尝试修复我的 postscript 解释器中的错误处理,但我很难想出在其中一个堆栈已满时执行处理程序的方法。

我正在使用的 postscript 级处理程序是 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

因此它需要操作数堆栈(用于 $error 字典和名称和内容)和执行堆栈(用于过程主体,如果执行)上的空间。那么如果任一栈溢出,这个空间应该从哪里来?

我尝试先解决 execstackoverflow,因为使用 execstack 的操作员比使用操作数堆栈的操作员少。我定义了一个“缓冲区”大小

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

所有“exec”运算符函数都添加到空间检查中。例如。这是exec 运算符。

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

然后解释器循环检查更小的大小(因此在尝试运行处理程序时不会触发更多错误)。

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

但它不起作用 (SEGFAULT),除非我在 C 级错误处理程序中清除一些空间,就在它将 PS 处理程序推送(调度)到 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();
    }
...

但现在我已经把婴儿和洗澡水一起扔了出去!堆栈顶部的那些条目可能只是修复错误的关键信息,而我只是将它们扔进了深渊。

谁能提出更好的解决方法?

【问题讨论】:

  • 你没有一个开始。
  • 你的意思是像一个不能溢出的扩展堆栈吗?或者在处理程序执行期间暂停检查? ......或者这只是一个小笑话?如果是这样,哈哈哈!

标签: c error-handling stack-overflow interpreter postscript


【解决方案1】:

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

【讨论】:

  • 嗯,是的。那是 Postscript Level 2 采用的解决方案。但是我正在将 Level 2 设计作为一个单独的项目进行工作......目前我认为我只需要在处理程序期间暂停 ERRDEPTH 校正(使 use 的保留空间)。
  • 你能做一个临时的 malloc 来持续足够长的时间来处理最重要的消息吗?
  • 嗯,是的。我想我可以!我完全没有想到这一点。现在它们都是静态分配的;但是在 init() 中 malloc 应该不会很痛苦。然后我可以重新分配并继续(我认为以后没有任何迫切需要再次缩小它们)。
猜你喜欢
  • 2010-12-19
  • 1970-01-01
  • 2011-03-29
  • 1970-01-01
  • 2012-08-22
  • 2019-05-18
  • 2013-10-29
  • 2021-04-28
  • 2019-02-01
相关资源
最近更新 更多