2

我的 Go 程序有时会崩溃。

我尝试了一些方法来为该程序生成核心转储:

  1. 在系统上定义 ulimit ,我都尝试了ulimit -c unlimitedulimit -c 10000以防万一。启动我的恐慌程序后,我没有得到核心转储。

  2. 我还在recover()我的程序中添加了支持,并添加了代码以在出现恐慌的情况下记录到 syslog,但我在 syslog 中一无所获。

我现在没有想法了。

我一定忽略了一些东西,但我没有找到什么,任何帮助将不胜感激。

谢谢 !:)

4

2 回答 2

4

请注意,当满足某个集合的条件时,操作系统会生成核心转储。这些条件是相当低级的——比如试图访问未映射的内存或试图执行 CPU 不知道的操作码等。在 POSIX 操作系统(如 Linux)下,当一个进程执行这些操作时,会发送一个适当的信号到它,其中一些,如果不由进程处理,则具有生成核心转储的默认操作,如果不通过设置某个限制来禁止,则由操作系统完成。

现在观察到这种机制在可能的最低级别(机器代码)上处理进程,但 Go 编译器生成的二进制文件比 C 编译器(或汇编程序)生成的二进制文件更高,这意味着进程中产生了某些错误Go 编译器由 Go 运行时而不是操作系统处理。例如,由 C 编译器生成的进程中的典型 NULL 指针取消引用通常会导致向进程发送 SIGSEGV 信号,这通常会导致尝试转储进程的核心并终止它。相反,当这种情况发生在由 Go 编译器编译的进程中时,Go 运行时会启动并出现恐慌,从而为调试目的生成一个很好的堆栈跟踪。

考虑到这些事实,我会尝试这样做:

  1. 将您的程序包装在一个 shell 脚本中,该脚本首先放宽核心转储的限制(但见下文),然后运行您的程序,并将其标准错误流重定向到文件(或通过管道传输到logger二进制文件等)。
  2. 用户可以调整的限制有一个层次结构:有软限制和硬限制——参见这个这个以获得解释。因此,请尝试检查您的系统是否将核心转储大小设置为 0 作为硬限制,因为这可以解释为什么您尝试提高此限制没有效果。
  3. 至少在我的 Debian 系统上,当一个程序由于 SIGSEGV 死机时,这个事实会被内核记录下来,并且在 syslog 日志文件中可见,因此请尝试使用 grep 来获取提示。
于 2013-02-19T07:47:12.443 回答
0
  1. 首先,请确保处理所有错误。

  2. 对于核心转储,您可以参考在 linux 中生成核心转储

  3. 当程序崩溃时,您可以使用主管重新启动程序。

于 2013-02-19T01:32:29.847 回答