【问题标题】:sh: out of memory for system callsh:系统调用内存不足
【发布时间】:2017-05-09 06:13:57
【问题描述】:

我在基于 ARM 的板上运行以下代码:

void MainLoop()
{
    char command[256];
    int ret = 0;
    int loopCount = 0;
    while(1)
    {
        memset(command, '\0', sizeof(command));
        sprintf(command, "/usr/bin/gst-launch-0.10 imxv4l2src ! imxv4l2sink &");
        ret = system(command);
        printf("StartStreamer: command=[%s], status:%d\n", command, ret);
        if ( ret != 0 )
        {
            ret = system("reboot");
            printf("Rebooting:%d\n", ret);
        }
        sleep(15);
        memset(command, '\0', sizeof(command));
        sprintf(command, "killall gst-launch-0.10");
        ret  = system(command);
        printf("StopStreamer: command=[%s], status = %d\n", command, ret);
        if ( ret != 0 )
        {
            ret = system("reboot");
            printf("Rebooting:%d\n", ret);
        }
        sleep(15);
        loopCount++;
        printf("Loop Count:%d\n", loopCount);

    }
}

运行一些随机循环后,我收到以下错误:

sh: out of memory
StartStreamer: command=[/usr/bin/gst-launch-0.10 imxv4l2src ! imxv4l2sink &], status:256
Segmentation fault
Rebooting:35584
StopStreamer: command=[killall gst-launch-0.10], status = 11
Rebooting:11
Loop Count:26
sh: relocation error: sh: symbol free, version GLIBC_2.4 not defined in file libc.so.6 with link time reference
sh: relocation error: sh: symbol free, version GLIBC_2.4 not defined in file libc.so.6 with link time reference
StartStreamer: command=[/usr/bin/gst-launch-0.10 imxv4l2src ! imxv4l2sink &], status:32512
Rebooting:11
killall: gst-launch-0.10: no process killed
StopStreamer: command=[killall gst-launch-0.10], status = 11
Rebooting:11
Loop Count:27
StartStreamer: command=[/usr/bin/gst-launch-0.10 imxv4l2src ! imxv4l2sink &], status:32512
Rebooting:32512

你能告诉我“sh:Out of Memory”是什么意思吗,是因为系统调用太多吗?另外,我在glibc中出现重定位错误很奇怪……

我已经从 C 应用程序修改为 Bash 脚本:

#!/bin/ash
count=0
    while [ true ];do
            echo "Starting Streamer"
        /usr/bin/gst-launch-0.10 imxv4l2src ! imxv4l2sink &
            sleep 15
            echo "Stopping Streamer"
            killall gst-launch-0.10
            sleep 15
            count=$((count+1))
            echo $count
    done

在运行一些循环后,我得到以下错误:

* /bin/sh': double free or corruption (out): 0x0028ebf8 *** *** Error in/bin/sh' 中的错误:malloc():内存损坏:0x0028edf8 *

【问题讨论】:

  • 如果不是您的程序滥用内存,那么它一定是您启动的程序之一导致主板内存不足。
  • 你能告诉我检查程序内存使用的命令吗

标签: c linux segmentation-fault arm sh


【解决方案1】:

请问“sh: Out of Memory”是什么意思,是不是因为系统调用太多?

来自system 手册页:

   The  system()  library  function  uses  fork(2)  to create a child
   process that executes the shell command specified in command using
   execl(3) as follows:

       execl("/bin/sh", "sh", "-c", command, (char *) 0);

   system() returns after the command has been completed.

我想说这就是您看到该消息的原因。您显然已经用完了 fork 部分的资源。很难说这是遇到 rlimit 还是只是内存不足(更有可能)。

所以基本上你有一个调用system 的主循环,它“在后台”创建你的进程的副本并将二进制文件(execl 部分)复制到副本中。哦,你尝试killall 第一个进程(再次通过system)。不幸的是,信号不能保证可靠,但通常会被接收到。另一个复杂性是您受调度程序的支配,当您认为它会运行该进程时,它可能不会运行。

最好使用更原始的fork/exec 函数来访问此功能——至少您将拥有发送信号的 PID,而不会产生killall 的开销。

【讨论】:

  • killall 与使用 PID 杀戮是否不同。在前一种情况下,killall 正在检索 PID..
  • 并非如此。在这种情况下,killall 是另一个进程,它被 forked 关闭(使用更多内存),它读取进程表以搜索匹配以向 PID 发送信号(例如kill)。 kill 没有 fork,避免了开销和内存使用。
  • 您是说使用带有 system() 的 killall 创建两个进程,一个由 system 创建,另一个由 killall 创建,而使用 system() 的 kill,它只创建一个进程...请确认。
  • 我不是在谈论kill command line utility,我是在谈论kill system call(它向进程发送信号)。您使用system 调用的任何内容都将转到fork(创建执行过程的副本)。
猜你喜欢
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-31
  • 2020-11-07
  • 1970-01-01
相关资源
最近更新 更多