Pjsip 在多线程中调用它的函数时在 android 上崩溃

Posted

技术标签:

【中文标题】Pjsip 在多线程中调用它的函数时在 android 上崩溃【英文标题】:Pjsip crashed on android when calling it's functions in multi-threads 【发布时间】:2013-11-08 13:45:26 【问题描述】:

我按照 pjsip 'get started' 文档成功构建了适用于 android 9 的 pjsip 库。但是当我在我的 android 项目中使用它时(尽管 JNI 调用),当我注册用户到 sip sever 或进行调用时,它通常会崩溃。我在主线程中使用 pjsua_create 和 pjsua_init 等 API 创建 pjsua 模块,然后我调用 pjsua_acc_add或者 pjsua_call_make_call 在另一个线程中,它通常会崩溃。但是,它崩溃的点是非常随机的。此外,有时它不会崩溃,但它在 pjsip_resolve 函数上失败。它会生成 sip 消息的目标 IP 和端口信息,例如'192.168.0.1:5060',到一个没有IP信息的字符串,比如':5060'。我已经做了pj线程检查,所以它不会崩溃。有人遇到过这个问题吗?我已经通过 google 和 trac.pjsip.org 进行了搜索,但找不到任何有用的信息。

任何帮助将不胜感激!

********** Crash dump: **********
Build fingerprint: 'Xiaomi/aries/aries:4.1.1/JRO03L/JLB22.0:user/release-keys'
pid: 3927, tid: 4082, name: Thread-1052  >>> com.ailiao.vp <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000017
Stack frame #00  pc 0013c124  /data/data/com.ailiao.vp/lib/libsua.so: Routine ioqueue_on_accept_complete in ../src/pj/activesock.c:916
Stack frame #01  pc 0013c3e4  /data/data/com.ailiao.vp/lib/libsua.so (pj_hash_get_lower+76): Routine pj_array_erase in ../src/pj/array.c:46
Crash dump is completed

********** Crash dump: **********
Build fingerprint: 'Xiaomi/aries/aries:4.1.1/JRO03L/JLB22.0:user/release-keys'
pid: 4387, tid: 4415, name: Thread-1051  >>> com.ailiao.vp <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000f09 
Stack frame #00  pc 0013c124/data/data/com.ailiao.vp/lib/libsua.so: Routine ioqueue_on_accept_complete in ../src/pj/activesock.c:916
Stack frame #01  pc 0013c3e4  /data/data/com.ailiao.vp/lib/libsua.so (pj_hash_get_lower+76): Routine pj_array_erase in ../src/pj/array.c:46
Crash dump is completed

********** Crash dump: **********
Build fingerprint: 'Xiaomi/aries/aries:4.1.1/JRO03L/JLB22.0:user/release-keys'
pid: 4532, tid: 4613, name: Thread-1060  >>> com.ailiao.vp <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000038
Stack frame #00  pc 0013c124  /data/data/com.ailiao.vp/lib/libsua.so: Routine ioqueue_on_accept_complete in ../src/pj/activesock.c:916
Stack frame #01  pc 0013c468  /data/data/com.ailiao.vp/lib/libsua.so: Routine pj_array_find in ../src/pj/array.c:60
Crash dump is completed

********** Crash dump: **********
Build fingerprint: 'Xiaomi/aries/aries:4.1.1/JRO03L/JLB22.0:user/release-keys'
pid: 6317, tid: 6572, name: Thread-1115  >>> com.ailiao.vp <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr e92d4808
Stack frame #00  pc 0013f484  /data/data/com.ailiao.vp/lib/libsua.so: Routine pj_list_insert_nodes_before in ../include/pj/list_i.h:54
Stack frame #01  pc 0013f744  /data/data/com.ailiao.vp/lib/libsua.so (pj_hash_get_lower+76): Routine pj_list_init in ../include/pj/list.h:90
Stack frame #02  pc 0008e80c  /data/data/com.ailiao.vp/lib/libsua.so (pjsip_ua_register_dlg+360): Routine pjsip_ua_destroy in ../src/pjsip/sip_ua_layer.c:230
Stack frame #03  pc 0008934c  /data/data/com.ailiao.vp/lib/libsua.so (pjsip_dlg_create_uac+1880): Routine pjsip_dlg_create_uac in ../src/pjsip/sip_dialog.c:240
Stack frame #04  pc 00032f50  /data/data/com.ailiao.vp/lib/libsua.so (pjsua_call_make_call+1152): Routine on_make_call_med_tp_complete in ../src/pjsua-lib/pjsua_call.c:459
Stack frame #05  pc 00026038  /data/data/com.ailiao.vp/lib/libsua.so (Java_sua_Pjsua_makeCall+728): Routine Java_sua_Pjsua_InnerInit in jni/../src/pjsuawrapper.cc:767
Stack frame #06  pc 0001fb70  /system/lib/libdvm.so (dvmPlatformInvoke+112)
Stack frame #07  pc 0004e8b9  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+360)
Stack frame #08  pc 00050603  /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+174)
Stack frame #09  pc 00029020  /system/lib/libdvm.so
Stack frame #10  pc 0002d7e8  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+180)
Stack frame #11  pc 0005fed5  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+272)
Stack frame #12  pc 0005feff  /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20)
Stack frame #13  pc 00055327  /system/lib/libdvm.so
Stack frame #14  pc 00012e70  /system/lib/libc.so (__thread_entry+48)
Stack frame #15  pc 000125c8  /system/lib/libc.so (pthread_create+172)
Stack frame #16  pc ffffffff  <unknown>: Unable to open symbol file obj\local\armeabi-v7a/<unknown>. Error (123): Unknown error
Crash dump is completed

********** Crash dump: **********
Build fingerprint: 'Xiaomi/aries/aries:4.1.1/JRO03L/JLB22.0:user/release-keys'
pid: 7766, tid: 8023, name: Thread-1123  >>> com.ailiao.vp <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 20e7a813
Stack frame #00  pc 00014682  /system/lib/libc.so (dlmalloc+1589)
Stack frame #01  pc 00016fef  /system/lib/libc.so (malloc+10)
Stack frame #02  pc 0014a728  /data/data/com.ailiao.vp/lib/libsua.so: Routine default_block_alloc in ../src/pj/pool_policy_malloc.c:46

【问题讨论】:

【参考方案1】:

使用NDK_DEBUG=1 构建,您将获得更详细的堆栈跟踪。对我来说,崩溃来自:

: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I: Build fingerprint: 'asus/WW_Z00T/ASUS_Z00T:5.0.2/LRX22G/WW_user_1.17.40.1234_20160304:user/release-keys'
I: Revision: '0'
I: ABI: 'arm64'
I: pid: 5618, tid: 5924, name: OutgoingCall-si  >>> com.siptest.android <<<
I: signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
I: Abort message: '../src/pjsip/sip_ua_layer.c:290: pjsip_ua_register_dlg: assertion "dlg->local.info && dlg->local.info->tag.slen && dlg->local.tag_hval != 0" failed'
I:     x0   0000000000000000  x1   0000000000001724  x2   0000000000000006  x3   000000558de365b0
I:     x4   000000558de365b0  x5   0000000000000005  x6   0000000000000001  x7   0000000000000020
I:     x8   0000000000000083  x9   fefefefeff63646b  x10  7f7f7f7f7f7f7f7f  x11  0000000000000001
I:     x12  0000000000000001  x13  0000000000000000  x14  0000000000000000  x15  002dee82e7a00ada
I:     x16  0000007f7d43e483  x17  0000000000000001  x18  0000000000000000  x19  000000558de365b0
I:     x20  0000007f7d43fbb0  x21  0000007fa017a000  x22  0000000000000058  x23  0000000000000006
I:     x24  00000000130e4360  x25  00000000130785a0  x26  000000558dd88930  x27  00000000130e4a20
I:     x28  00000000130785a0  x29  0000007f7d43e720  x30  0000007fa00f48bc
I:     sp   0000007f7d43e720  pc   0000007fa0139de8  pstate 0000000060000000
I:     #00 pc 000000000005ede8  /system/lib64/libc.so (tgkill+8)
I:     #01 pc 00000000000198b8  /system/lib64/libc.so (pthread_kill+160)
I:     #02 pc 000000000001ae18  /system/lib64/libc.so (raise+28)
I:     #03 pc 000000000001467c  /system/lib64/libc.so (abort+60)
I:     #04 pc 0000000000016ca8  /system/lib64/libc.so (__libc_fatal+128)
I:     #05 pc 0000000000014754  /system/lib64/libc.so (__assert2+40)
I:     #06 pc 00000000001d5ddc  /data/app/com.siptest.android-2/lib/arm64/libpjsua2.so (pjsip_ua_register_dlg+248)
I:     #07 pc 00000000001d1588  /data/app/com.siptest.android-2/lib/arm64/libpjsua2.so (pjsip_dlg_create_uac+1688)
I:     #08 pc 00000000001634a8  /data/app/com.siptest.android-2/lib/arm64/libpjsua2.so (pjsua_call_make_call+1088)
I:     #09 pc 0000000000145ce0  /data/app/com.siptest.android-2/lib/arm64/libpjsua2.so (pj::Call::makeCall(std::string const&, pj::CallOpParam const&)+168)
I:     #10 pc 00000000000fd1f8  /data/app/com.siptest.android-2/lib/arm64/libpjsua2.so (Java_org_pjsip_pjsua2_pjsua2JNI_Call_1makeCall+256)
I:     #11 pc 000000000075b9d4  /data/dalvik-cache/arm64/data@app@com.siptest.android-2@base.apk@classes.dex
W: RecordThread: buffer overflow

这似乎表明注册凭据有问题。我挖掘了C源代码,发现以下字段之一是NULLsip_dialog.c:

/*
 * Create an UAC dialog.
 */
PJ_DEF(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
                      const pj_str_t *local_uri,
                      const pj_str_t *local_contact,
                      const pj_str_t *remote_uri,
                      const pj_str_t *target,
                      pjsip_dialog **p_dlg)

    pj_status_t status;
    pj_str_t tmp;
    pjsip_dialog *dlg;

    /* Check arguments. */
    PJ_ASSERT_RETURN(ua && local_uri && remote_uri && p_dlg, PJ_EINVAL);

我还看到其他用户抱怨 Android 上的多线程存在问题。确保在调用 pjsip 库之前附加 JVM。也许试试:

  ua_cfg.setThreadCnt(1);
  ua_cfg.setMainThreadOnly(true);

然后您将不得不通过该线程任何操作。或者,您可以启用多个线程,然后像这样附加:

  static boolean attachJVM()
  
    // ensure after possibly sleeping on take()
    final Endpoint ep = endpoint();
    try  if (!ep.libIsThreadRegistered()) ep.libRegisterThread(Thread.currentThread().getName()); return true; 
    catch (Exception e)  log().e(e); return false; 
  

我意识到我正在调用我自己的实用程序,但我认为它非常具有自我描述性(即 log() 是一个日志文件,endpoint() 返回您在 init 中构建的 Endpoing 实例)。

【讨论】:

【参考方案2】:

这个库长期以来一直存在一些问题 - 它崩溃了。

在对很好地捕获的错误日志进行一些调查后,我发现了大多数库崩溃的常见原因。 在此处查看我的答案和 cmets(不确定此处是否允许复制粘贴): https://***.com/a/46111654/6248423

【讨论】:

如果是您的答案,您可以从中复制并针对此问题进行调整。

以上是关于Pjsip 在多线程中调用它的函数时在 android 上崩溃的主要内容,如果未能解决你的问题,请参考以下文章

可以在多线程 DLL 的接口函数中创建线程吗?

如何使用Qt和C ++的“接口类”来传递两个线程

在多线程 C 应用程序中嵌入 python

多线程场景设计利器:分离方法的调用和执行——命令模式总结

valgrind 在多线程套接字程序中停止

由“Qt程序运行一段时间后崩溃”引发的“opancv库中Mat::clone()函数”在多线程下的注意事项