Tcl程序,其行为根据“puts”语句而变化

时间:2012-09-28 14:57:56

标签: debugging crash tcl puts

主要问题:

puts语句(尽管如此,硬编码字符串)如何影响程序流?


我将直接潜入代码的不完整部分,原因将在稍后解释。

proc bgerror { error } {
    puts "Background error: $error"
    exit 1
}

运行我的Tcl程序,我得到:

Background error: can't read "YPE(PROCESS)": no such variable

很公平,我想;必须在某个地方弄清$或括号。为了找到问题,我将puts语句放在任何地方并重新运行程序。

然而,这一次,我的程序崩溃了:

9526:   tclsh testProgram
 fffffd7ffeafebba waitid   (0, 253d, fffffd7fffdf4950, 3)
 fffffd7ffeaeff9d waitpid () + 7d
 fffffd7ffe635132 __1cPGetPstackOutput6Fiiipci_v_ () + b2
 fffffd7ffe634bfb App_CoreSignalHandler () + 76b
 fffffd7ffeafb7b6 __sighndlr () + 6
 fffffd7ffeaf0b82 call_user_handler () + 252
 fffffd7ffeaf0d68 sigacthandler (b, fffffd7fffdfa500, fffffd7fffdfa1a0) + a8
 --- called from signal handler with signal 11 (SIGSEGV) ---

哎哟。

最终,我发现了一些非常奇怪的东西:

proc OnNewState { } {
    puts "foobar"
    # ...
}

使用 puts语句,我得到了崩溃。 没有它,我得到原始错误。 (嗯?!)我来回翻了好几次,以确保它是确定性的 - 它就是。

现在,我深入研究不完整的代码片段的原因是我想把注意力集中在抽象而不是特定的。

(完整的代码很复杂,不透明,主要是利用我公司的基础架构库,所以简化它无论如何都不可行。此外,我已经知道了该问题源于其中一个基础结构库,因为当我删除与TCP发布者/订阅者堆栈库关联的一些代码时问题就消失了。)

puts语句(尽管如此,硬编码字符串)如何影响程序流?

即使我开始深入研究相关图书馆的C源,我也不知道该寻找什么。

希望一些经验丰富的Tcl能够解决一些问题......

1 个答案:

答案 0 :(得分:3)

首先,您提供的证据告诉我们您处于SIGSEGV处理程序的上下文中,并且它是由自定义代码设置的(Tcl未设置SIGSEGV处理程序)。

Tcl的puts命令只会通过生成错误来影响控制流,并且如果您传递了错误数量的参数,无效参数,或者它遇到I / O层中的问题(例如, ,如果你关闭了stdout频道。一个简单的puts "foobar"肯定是一个有效的调用,所以问题出现在通道层。或者你有一个非标准的puts;如果您的自定义代码替换了标准版本,那么几乎可能发生任何事情。

那么可能会发生什么?好吧,在这个阶段,我最初的怀疑是你的程序中的其他地方存在内存损坏,并且这在某种程度上影响了stdout频道的内部。如果我是对的,你会发现很难跟踪这个; 非本地崩溃总是很难找到 。我建议您使用关闭该信号处理程序的一些组合,附加gdb以便您可以看到崩溃真正发生的位置,并使用valgrind来确保处理内存正确的(如果你很幸运,valgrind将指出问题几乎完全在哪里。)