You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LLDB调试安卓Native C++应用时continue触发SIGSEGV,如何正常执行?

问题描述

我正在使用lldb调试一个崩溃的原生C++应用,在android_main开头添加了sleep(5),以便有时间将调试器附加到应用。附加完成后应用处于暂停状态,执行continue命令后,进程立即停止并抛出SIGSEGV信号:

(lldb) continue
Process 4158 resuming
Process 4158 stopped
* thread #19, name = 'com.example.app', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
    frame #0: 0x00007cefe26282c8
->  0x7cefe26282c8: movq   (%rcx), %rdx
    0x7cefe26282cb: movq   %rdx, 0x18a0(%rax)
    0x7cefe26282d2: movl   0x8(%rcx), %ecx
    0x7cefe26282d5: movl   %ecx, 0x18a8(%rax)

再次执行continue命令后,应用直接退出崩溃:

(lldb) continue
Process 4158 exited with status = 11 (0x0000000b)

请问如何修复该问题,使应用能够正常继续执行?

解决步骤
  • 定位空指针根源
    当前SIGSEGV是因为rcx寄存器指向0x0地址,执行movq (%rcx), %rdx时访问了空指针。先执行bt命令打印完整调用栈,确认崩溃触发点是自有代码还是系统库:

    (lldb) bt
    

    若调用栈包含自有函数,直接定位对应代码检查空指针;若为系统库,则排查调用该库函数时传入的参数是否为空。

  • 替换sleep为安全的调试等待逻辑
    在android_main开头加sleep(5)可能打乱Android应用初始化时序——部分系统服务或全局对象可能因主线程阻塞超时,导致后续拿到空指针。可以替换为动态检查调试器是否附加的逻辑:

    // 替换sleep(5),等待调试器附加
    while (!DebuggerIsAttached()) {
        usleep(100000); // 每100ms检查一次
    }
    

    其中DebuggerIsAttached()可通过Android NDK接口实现:

    #include <android/api-level.h>
    #include <android/debug.h>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
     
    bool DebuggerIsAttached() {
        #if __ANDROID_API__ >= 28
        return android_get_debugger_status() != ANDROID_DEBUGGER_STATUS_NONE;
        #else
        // 低版本通过检查/proc/self/status的TracerPid字段
        FILE* fp = fopen("/proc/self/status", "r");
        if (!fp) return false;
        char buf[256];
        while (fgets(buf, sizeof(buf), fp)) {
            if (strstr(buf, "TracerPid:") && atoi(buf+10) != 0) {
                fclose(fp);
                return true;
            }
        }
        fclose(fp);
        return false;
        #endif
    }
    
  • 临时忽略信号(仅调试用)
    若确认该SIGSEGV是调试环境导致的假崩溃(正常运行不会触发),可让lldb忽略该信号:

    (lldb) process handle -s false SIGSEGV
    

    执行后再continue即可让应用继续运行,但这只是临时绕过,建议优先排查根本原因。

  • 检查子线程初始化依赖
    崩溃发生在thread #19(非主线程),说明可能是子线程依赖的全局对象因主线程被sleep阻塞未完成初始化。可通过以下命令排查:

    (lldb) thread list
    (lldb) thread select 19
    (lldb) bt
    

    确认子线程执行的代码,检查是否存在依赖主线程初始化的资源。

内容的提问来源于stack exchange,提问作者user18514618

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 21:45:38