debugging - Tcl 程序,其行为根据 "puts"语句而变化

标签 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'ers能够提供一些启发......

最佳答案

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

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

那么可能会发生什么?好吧,在这个阶段,我最初的怀疑是程序中其他地方出现了内存损坏,并且这在某种程度上影响了 stdout channel 的内部。如果我是对的,你会发现很难找到这个人; 非本地崩溃总是很难追踪。我建议您使用关闭信号处理程序、附加 gdb 的某种组合,这样您就可以看到崩溃真正发生的位置,并使用 valgrind确保内存得到正确处理(如果幸运的话,valgrind 将直接指出问题所在)。

关于debugging - Tcl 程序,其行为根据 "puts"语句而变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12642460/

相关文章:

Java - 线程因未捕获的异常而退出(组 = 0x95d40b20)

postgresql - postgres (8.3),在函数中使用查询结果

c++ - 退出 Tcl_DoOneEvent 函数

python - 如何从 gdb-python 方法中调用 C 函数

python - 在Python调试器中中断成员函数

c++ - 崩溃与 "glibc detected: vector double free or corruption (out)"

来自 Android 7.0 的 android.webkit.WebViewFactory$MissingWebViewPackageException

c++ - 调用 `source`命令时如何传递参数

c - Hangman 程序帮助(C 编程简介)

apache - 如何调试apache虚拟主机配置?