【问题标题】:Compressing the core files during core generation在核心生成期间压缩核心文件
【发布时间】:2011-07-01 02:26:52
【问题描述】:

有没有办法在核心转储生成期间压缩核心文件?

如果系统中的存储空间有限,有没有办法在需要立即压缩生成核心转储时节省它?

理想情况下,该方法适用于旧版本的 linux,例如 2.6.x。

【问题讨论】:

    标签: linux kernel


    【解决方案1】:

    Linux 内核 /proc/sys/kernel/core_pattern 文件会做你想做的事:http://www.mjmwired.net/kernel/Documentation/sysctl/kernel.txt#141

    将文件名设置为|/bin/gzip -1 > /var/crash/core-%t-%p-%u.gz 之类的名称,您的核心文件应为您压缩保存。

    【讨论】:

    • 请注意,这仅从 2.6.19 开始受支持。如果您有一个较早运行的嵌入式系统,这可能是升级的灵感;-)
    • 对于嵌入式的人来说同样值得注意的是,大多数直接flash文件系统(yaffs、jffs2、ubifs)对文件进行透明压缩,会达到类似的净效果。
    • 必须使用绝对路径名指定程序。见CORE(5)。此外,重定向“>”在这里不起作用,您可以将 gzip 命令放入单独的 shell 脚本中,例如“/root/core.sh”,然后改为 echo "|/root/core.sh" > /proc/sys/kernel/core_pattern。
    • @Ted,我很惊讶我忽略了完整的路径。谢谢!
    • busybox 对我来说也一样:应该将核心模式指定为 shell 脚本的参数,例如echo "|/root/core.sh %t %p %u" >/proc/sys/kernel/core_pattern 在脚本中你可以使用 $1, $2, $3: /bin/gzip -f - >/var/crash/core-$1-$2-$3.gz
    【解决方案2】:

    对于嵌入式 Linux 系统,以下脚本更改可以完美地分两步生成压缩的核心文件

    第 1 步:创建脚本

    touch /bin/gen_compress_core.sh
    chmod +x /bin/gen_compress_core.sh

    cat > /bin/gen_compress_core.sh #!/bin/sh exec /bin/gzip -f - >"/var/core/core-$1.$2.gz"
    ctrl +d

    第二步:更新核心模式文件

    cat > /proc/sys/kernel/core_pattern |/bin/gen_compress_core.sh %e %p ctrl+d

    【讨论】:

      【解决方案3】:

      正如其他答案所建议的,Linux 内核 /proc/sys/kernel/core_pattern 文件是开始的好地方:http://www.mjmwired.net/kernel/Documentation/sysctl/kernel.txt#141

      如文档所述,您可以指定特殊字符“|”这将告诉内核将文件输出到脚本。正如建议的那样,您可以使用 |/bin/gzip -1 > /var/crash/core-%t-%p-%u.gz 作为名称,但它似乎对我不起作用。我预计原因是我的系统内核不会将 > 字符视为输出,而是可能将其作为参数传递给 gzip。

      为了避免这个问题,像其他建议一样,您可以在我使用 /home//crash/core.sh 的某个位置创建文件,使用以下命令创建它,替换为您的用户。或者你也可以明显地改变整个路径。

      echo -e '#!/bin/bash\nexec /bin/gzip -f - >"/home/<username>/crashes/core-$1-$2-$3-$4-$5.gz"' > ~/crashes/core.sh
      

      现在这个脚本将接受 5 个输入参数并将它们连接起来并添加到 core-path。必须在 ~/crashes/core.sh 中指定完整路径。还可以指定此脚本的位置。现在让我们告诉内核在生成文件时使用带参数的 tour 可执行文件:

      sudo sysctl -w kernel.core_pattern="|/home/<username>/crashes/core.sh %e %p %h %t"
      

      应再次替换(或匹配 core.sh 脚本的位置和名称的整个路径)。下一步是崩溃一些程序,让我们创建一个示例崩溃 cpp 文件:

      int main (){
          int * a = nullptr;
          int b = *a;
      }
      

      编译运行后有2个选项,我们会看到:

      分段错误(核心转储)

      或者

      分段错误

      如果我们看到后者,可能的原因很少。

      1. ulimit 未设置,ulimit -c 应指定内核的限制
      2. apport 或您的发行版核心转储收集器未运行,这应进一步调查
      3. 我们编写的脚本中有一个错误,我建议不要检查一些基本的转储路径来检查其他事情是否不是下面应该创建 /tmp/core.dump 的原因:

        sudo sysctl -w kernel.core_pattern="/tmp/core.dump"
        

      我知道这个问题已经有了答案,但是我不清楚为什么它不能“开箱即用”,所以我想总结一下我的发现,希望它对某人有所帮助。

      【讨论】:

        猜你喜欢
        • 2014-04-06
        • 2011-12-05
        • 1970-01-01
        • 1970-01-01
        • 2012-10-24
        • 1970-01-01
        • 2014-11-17
        • 1970-01-01
        • 2014-01-24
        相关资源
        最近更新 更多