【问题标题】:detect assert(0) using tcl/expect使用 tcl/expect 检测 assert(0)
【发布时间】:2019-11-11 17:28:25
【问题描述】:

这是我的test.cpp 程序。它通过assert(0)异常退出。

#include <cassert>

int main() {
  assert(0);
}

当我直接运行这个程序时,我得到了预期的输出,包括非零退出状态:

$ ./test
...
$ echo $?
134

但是当我尝试检测tcl/expect 中的异常退出时,我似乎无法:

#!/usr/bin/expect

spawn ./test
expect eof
lassign [wait] pid spawnid os_error_flag value

if {$os_error_flag != 0} {
  puts "OS error"
  exit 1
}
if {$value != 0} {
  puts "Application error"
  exit 1
}

puts "No error"

当我运行该脚本时:

$ ./test.expect
No error

如果我使用exit(1) 而不是assert(0) 那么tcl 脚本能够检测到异常退出。为什么tcl/expect不提供断言失败的OS-application-returned错误代码,如何通过检查退出代码统一检测所有异常程序退出?

【问题讨论】:

    标签: tcl expect assert


    【解决方案1】:

    不是答案,而是扩展评论:

    运行该代码,我看到了:

    $ ./a.out; echo $?
    Assertion failed: (0), function main, file x.c, line 4.
    Abort trap: 6
    134
    

    在期待中,我看到了:

    $ expect
    expect1.1> spawn ./a.out
    spawn ./a.out
    47429
    expect1.2> expect eof
    Assertion failed: (0), function main, file x.c, line 4.
    expect1.3> wait
    47429 exp6 0 0 CHILDKILLED SIGABRT SIGABRT
    

    看起来您需要查看wait 返回的元素,超过 4 号。

    【讨论】:

      【解决方案2】:

      当我查看 what wait does 时,我看到了:

      wait 的返回值末尾可能会出现其他元素。可选的第五个元素标识一类信息。目前,该元素唯一可能的值是 CHILDKILLED,在这种情况下,接下来的两个值是 C 风格的信号名称和简短的文本描述。

      assert() 调用使用abort() 在断言失败时终止进程,并通过 SIGABRT 显示为退出。

      set result [wait]
      if {[lindex $result 4] eq "CHILDKILLED"} {
          if {[lindex $result 5] eq "SIGABRT"} {
              # assertion failed, or other abort
          } else {
              # other signal
          } 
      } else {
          # normal exit, may be with conventional error
      }
      

      错误处理肯定很繁琐!

      【讨论】:

        猜你喜欢
        • 2011-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-27
        • 2014-06-18
        • 2015-05-21
        • 1970-01-01
        • 2020-09-28
        相关资源
        最近更新 更多