Android、CMDTool、stdout 重定向、“致命信号 11 (SIGSEGV)”

Posted

技术标签:

【中文标题】Android、CMDTool、stdout 重定向、“致命信号 11 (SIGSEGV)”【英文标题】:Android, CMDTool, stdout redirect, "Fatal signal 11 (SIGSEGV)" 【发布时间】:2015-04-17 22:29:34 【问题描述】:

用例

android C++ 命令行工具午餐“/system/bin/getprop”并将其标准输出重定向到套接字

问题

午餐 'getprop' 失败并显示“F/libc (20694): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 20694 (getprop)”, code & logcat sn-p follow.

为什么我会得到 SIGSEGV?为什么分叉的进程会失败?

实施

HRESULT ServiceCore::CreateProcessAndRedirectStdout(IN char* pCmd, IN char** args, OUT SOCKET& stdoutstream) 
    HRESULT hr      = S_OK;
    int     fds[2]  =  0 ;
    pid_t   pid     = 0;
    stdoutstream = 0;
    if (SOCKET_ERROR == socketpair(PF_UNIX, SOCK_STREAM, 0, fds))
        goto ErrExit;
    stdoutstream = fds[1];
    if((pid = fork()) < 0)
        goto ErrExit;
    if (pid == 0) 
        // The newly created process
        __android_log_print(ANDROID_LOG_INFO, "ServiceCore", "CreateProcessAndRedirectStdout>> '%s' started", pCmd);
        int newfd = dup2(fds[0], STDOUT_FILENO);
        __android_log_print(ANDROID_LOG_INFO, "ServiceCore", "CreateProcessAndRedirectStdout>> '%s' newfd:%d, oldfd:%d", pCmd, newfd, fds[0]);
        _ASSERT(newfd == STDOUT_FILENO);

        close(fds[0]);
        close(fds[1]);
        execvp(pCmd, args);
        __android_log_print(ANDROID_LOG_INFO, "ServiceCore", "CreateProcessAndRedirectStdout>> '%s' FAILED", pCmd);
        exit(1);
    
    __android_log_print(ANDROID_LOG_INFO, "ServiceCore", "CreateProcessAndRedirectStdout>> '%s(%d)' Created", pCmd, pid);
    return S_OK;
ErrExit:
    if (0 != pid)
        kill(pid, SIGTERM);
    close(fds[0]);
    close(fds[1]);
    stdoutstream = 0;
    return hr;


...
        char* args[] =  0 ;
        SOCKET soc;
        if (SUCCEEDED(hr = CreateProcessAndRedirectStdout("/system/bin/getprop", args, soc))) 
            errno = 0;
            __android_log_print(ANDROID_LOG_INFO, "ServiceCore", "SendConfig>> Reading props");
            char pTmp[256000];
            int iRet = read(soc, pTmp, sizeof(pTmp));// Read the first few lines
        

...

日志猫

I/ServiceCore(20689): CreateProcessAndRedirectStdout>> '/system/bin/getprop(20694)' Created

I/ServiceCore(20689): SendConfig>> Reading props

I/ServiceCore(20694): CreateProcessAndRedirectStdout>> '/system/bin/getprop' started

I/ServiceCore(20694): CreateProcessAndRedirectStdout>> '/system/bin/getprop' newfd:1, oldfd:10

F/libc    (20694): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 20694 (getprop)

【问题讨论】:

我不确定我是否看到了这个问题? 听起来像是在取消引用空指针。您需要查看 logcat 输出中的堆栈跟踪以找出位置,这应该会引导您了解什么/为什么。 【参考方案1】:

您正在以 getprop 未编写处理的方式滥用 execvp()。引用 execvp() 的 OSX/BSD(但实际上是通用的)手册页

execv()、execvp() 和 execvP() 函数提供了一个指向以 null 结尾的字符串的指针数组,这些字符串表示可用的参数列表 到新程序。按照惯例,第一个论点应该指向 与正在执行的文件关联的文件名。数组 指针必须以 NULL 指针终止。

你打破了这个约定,传递一个包含一个 NULL 元素的数组,你应该将程序名称作为第一个元素传递,然后是一个终止 NULL 元素。

这会将getprop 设置为失败,因为它考虑了只有一个参数(本身)的可能性,在这种情况下它将显示所有内容。

    if (argc == 1) 
        list_properties();

但如果它没有 1 个参数,它假设它必须有两个或更多,并尝试取消引用第二个,应该是名称您想获得的财产。

    property_get(argv[1], value, default_value);

将无效且可能为空的指针代替属性名称传递给 property_get() 最终在仿生 libc 深处失败,可能是 __system_property_find() 的实现调用 strlen()。

如果您按照 fadden 的建议检查了堆栈跟踪,您可能会在 libc 中看到一个地址,可能是 strlen()。

【讨论】:

以上是关于Android、CMDTool、stdout 重定向、“致命信号 11 (SIGSEGV)”的主要内容,如果未能解决你的问题,请参考以下文章

重定尺寸图像

selenium重定项

selenium重定项

如何保护 Django 中的静态 HTML 文件? (重定向前需要登录)

重定目标解决方案没有效果

shell脚本编程小技巧——如何解决多行重定,变量不被shell解释