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

Android Studio用自签名证书连服务器触发Wrote stack traces to tombstoned错误

自签名证书登录服务器时出现Signal 3错误的原因分析

问题描述

尝试在App中使用自签名证书登录服务器,登录时出现如下错误:

"Thread[6,tid=17486,WaitingInMainSignalCatcherLoop,Thread*=0xb4000074d0ac6570,peer=0x147c0000,\"Signal Catcher\"]: reacting to signal 3 "
"Wrote stack traces to tombstoned."

搜索过该错误的解决方案但均无效,以下是我的代码:

public class Connection extends AsyncTask{

    @Override
    protected Object doInBackground(Object[] objects) {
        try {
            Connect();
        } catch (CertificateException | IOException | KeyStoreException | NoSuchAlgorithmException | KeyManagementException | NullPointerException e) {
            e.printStackTrace();
            ServerDirectActivity.response = true;
            ServerDirectActivity.responseMsg = String.valueOf(e);
        }
        return null;
    }
}

private void Connect() throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException, NullPointerException {
    CertificateFactory cf = CertificateFactory.getInstance("X.509");

    HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } });
    InputStream caInput = ServerDirectActivity.getmInstanceActivity().getAssets().open("client.csr");
    Certificate ca = null;
    try{
        ca = cf.generateCertificate(caInput);
    }catch (CertificateException e){
        e.printStackTrace();
    }finally {
        caInput.close();
    }

    String keyStoreType = KeyStore.getDefaultType();
    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    keyStore.load(null, null);
    keyStore.setCertificateEntry("ca", ca);

    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
    tmf.init(keyStore);

    context = SSLContext.getInstance("TLS");
    context.init(null, tmf.getTrustManagers(), null);

    URL url = new URL(serverIP);

    HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();

    final String basicAuth = "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes());
    urlConnection.setRequestProperty("Authorization", basicAuth);
    urlConnection.setSSLSocketFactory(context.getSocketFactory());
    System.out.println(urlConnection.getResponseMessage());
    System.out.println(urlConnection.getResponseCode());
    if (urlConnection.getResponseCode() == 200){
        InputStream in = urlConnection.getInputStream();
        String line;
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        StringBuilder out = new StringBuilder();
        while ((line = reader.readLine()) != null){
            out.append(line);
        }
        System.out.println(out);
    }
    ServerDirectActivity.response = true;
    ServerDirectActivity.responseMsg = String.valueOf(urlConnection.getResponseCode());
}

错误原因分析

Signal 3是SIGQUIT信号,它本身不是错误根源,只是系统触发生成堆栈跟踪的信号。真正的问题出在你的证书处理和网络请求逻辑中:

  • 错误加载CSR文件而非有效证书:你加载的client.csr是证书签名请求文件,不是可用于SSL验证的X.509证书。CSR仅包含证书申请信息,无法被CertificateFactory.generateCertificate()解析为有效证书,会导致后续信任管理器初始化失败。
  • 未处理证书解析失败的场景:即使generateCertificate()抛出异常,你仍继续执行后续代码,此时ca为null,调用keyStore.setCertificateEntry("ca", ca)会直接抛出NullPointerException,这是触发崩溃的直接原因。
  • 网络请求环节的未捕获异常:在调用getResponseMessage()和getResponseCode()时,如果连接未建立或出现IO错误,会抛出未被捕获的异常,最终触发系统生成堆栈跟踪。

修复建议

  1. 替换CSR为有效自签名证书
    将client.csr替换为服务器端的自签名证书文件(通常是.crt或.pem格式),确保该证书是服务器SSL连接使用的有效证书。

  2. 增加证书解析失败的终止逻辑
    在证书解析失败时直接终止流程,避免后续使用null证书:

    try{
        ca = cf.generateCertificate(caInput);
        if (ca == null) {
            throw new CertificateException("Failed to parse certificate file");
        }
    }catch (CertificateException e){
        e.printStackTrace();
        throw e; // 抛出异常终止连接流程
    }finally {
        caInput.close();
    }
    
  3. 完善网络请求的异常捕获
    将响应信息的读取逻辑包裹在try-catch块中:

    try {
        int responseCode = urlConnection.getResponseCode();
        System.out.println(urlConnection.getResponseMessage());
        System.out.println(responseCode);
        if (responseCode == 200){
            // 读取响应逻辑
        }
        ServerDirectActivity.responseMsg = String.valueOf(responseCode);
    } catch (IOException e) {
        e.printStackTrace();
        ServerDirectActivity.responseMsg = "Network error: " + e.getMessage();
    }
    
  4. 避免全局设置HostnameVerifier
    全局设置会影响所有HTTPS请求,建议只为当前连接设置:

    urlConnection.setHostnameVerifier((hostname, session) -> true);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 16:57:22