【问题标题】:My shell segfault when I do "kill -11 0"当我执行“kill -11 0”时,我的 shell 段错误
【发布时间】:2015-06-04 16:28:04
【问题描述】:

当我尝试在 bash、tcsh 或 zsh 上执行命令“/bin/kill -11 0”时,它不会出现段错误,但当我尝试在我的中执行此操作时,它会出现。

所以我一定有一些我没有处理过的东西。

你知道它可以是什么吗?

谢谢。

【问题讨论】:

  • 没有看到任何代码?
  • 我有 100 个 .c 文件,所以我不知道我需要展示什么。
  • 您的调试堆栈跟踪在哪里?
  • 那些 shell 可能会在单独的进程组中运行每个非内置命令(如 /bin/kill),而不是在 shell 自己的进程组中运行。你的外壳会这样做吗?它主要用于shell想要支持作业控制(Ctrl-Z、fgbg等)
  • @DimitriDanilov 您认为 tek1 论坛希望看到这个问题和答案吗?只是为了让每个学生都平等,你知道的。

标签: c shell unix


【解决方案1】:

您的程序在向自己发送信号 11 时实际上并没有发生段错误。

如果程序的执行导致“段错误”(即程序执行了非法内存引用),那么操作系统会发送程序 SIGSEGV(Linux 上的信号 11)。程序无法区分由于程序错误而由操作系统发送的 SIGSEGV 和由调用 raisekill 发送的 SIGSEGV,可能来自另一个进程,因此它会响应,就好像有一个真正的程序错误。

如果您想保护您的 shell 免受子进程发送到 pid 0 的信号的影响,您需要通过在 fork 之后调用子进程中的 setpgid 来确保您的子进程位于不同的进程组中。

默认情况下,程序由 SIGSEGV 终止。默认情况下,调用该程序的 shell 将报告该程序已被 SIGSEGV 终止。这通常被称为“段错误”,但如上所述,它可能不是真正的程序错误的结果。

如果你想让你的程序做其他事情,你必须用信号处理程序来捕捉信号 SIGSEGV;例如,如果需要在程序终止之前进行一些清理。大多数 shell(和数据库)都这样做,但在用户代码中很少需要这样做。

注意:信号 11 在 Linux 上是 SIGSEGV,但不能保证 SIGSEGV 在不同的操作系统上会是信号 11(甚至在 Linux 的某些未来版本中)。您应该始终使用信号名称而不是数字。

【讨论】:

  • 我知道这一切,但事实是,如果我向 pid 0 发送信号,我的 shell 不必退出,这是真正的 shell 所做的。您可以尝试执行 /bin/kill -11 0,您正在使用的 shell 不会退出。我的一位同事说我需要使用setsid函数,我试过了,但没有用。这就是我在这里问的原因,希望有人知道。
  • @DimitriDanilov:如果您认为您对sigaction 的调用没有生效,请显示代码。如果你不使用sigactionsignal 来捕获SIGSEGV,那么SIGSEGV 将终止你的shell。
  • @DimitriDanilov:如果你向 pid 0 发送信号,那么它会被发送到调用 kill 的进程以及同一进程组中的所有其他进程。所以它会被发送到你的shell。或者我不明白您正在采取的确切操作,在这种情况下,您可以尝试更好地解释或包含实际代码。
  • 捕获 SIGSEGV 是个坏主意,如果我的 shell 段错误我不会知道。而这个问题也不需要这样解决,还有别的办法。即使我捕捉到 SIGSEGV,如果我发送信号 SIGUSR 会发生什么,我也必须捕捉这个信号以避免当我向 pid 0 发送信号时我的 shell 退出?这似乎是个坏主意。
  • @DimitriDanilov:您是从其他进程向 pid 0 发送信号吗?是的,你需要在 fork 后创建一个新的进程组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-19
  • 2021-08-16
相关资源
最近更新 更多