saki4510t / UVCCamera

library and sample to access to UVC web camera on non-rooted Android device
2.99k stars 1.2k forks source link

Open and close Camera repeatedly, the following Crash appears. #519

Open aystshen opened 4 years ago

aystshen commented 4 years ago

2019-10-10 16:46:27.046 15178-15335/? A/libc: invalid pthread_t 0x4010409 passed to libc 2019-10-10 16:46:27.046 15178-15335/? A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 15335 (Timer-1), pid 15178 (ayst.stresstest) 2019-10-10 16:46:27.170 20908-20908/? I/crash_dump32: obtaining output fd from tombstoned, type: kDebuggerdTombstone 2019-10-10 16:46:27.171 352-352/? I//system/bin/tombstoned: received crash request for pid 15178 2019-10-10 16:46:27.171 20908-20908/? I/crash_dump32: performing dump of process 15178 (target tid = 15335) 2019-10-10 16:46:27.171 20908-20908/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 2019-10-10 16:46:27.172 20908-20908/? A/DEBUG: Build fingerprint: 'rockchip/rk3288/rk3288:8.1.0/OPM6.171019.030.K1/141052:userdebug/test-keys' 2019-10-10 16:46:27.172 20908-20908/? A/DEBUG: Revision: '0' 2019-10-10 16:46:27.172 20908-20908/? A/DEBUG: ABI: 'arm' 2019-10-10 16:46:27.172 20908-20908/? A/DEBUG: pid: 15178, tid: 15335, name: Timer-1 >>> com.ayst.stresstest <<< 2019-10-10 16:46:27.172 20908-20908/? A/DEBUG: signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- 2019-10-10 16:46:27.177 20908-20908/? A/DEBUG: Abort message: 'invalid pthread_t 0x4010409 passed to libc' 2019-10-10 16:46:27.177 20908-20908/? A/DEBUG: r0 00000000 r1 00003be7 r2 00000006 r3 00000008 2019-10-10 16:46:27.177 20908-20908/? A/DEBUG: r4 00003b4a r5 00003be7 r6 8ab7e974 r7 0000010c 2019-10-10 16:46:27.177 20908-20908/? A/DEBUG: r8 00000000 r9 8b00fe00 sl 00000000 fp 8ab7ea7c 2019-10-10 16:46:27.177 20908-20908/? A/DEBUG: ip 8ab7ecd8 sp 8ab7e960 lr a7282a2f pc a727c43c cpsr 20030030 2019-10-10 16:46:27.182 20908-20908/? A/DEBUG: backtrace: 2019-10-10 16:46:27.182 20908-20908/? A/DEBUG: #00 pc 0001a43c /system/lib/libc.so (abort+63) 2019-10-10 16:46:27.182 20908-20908/? A/DEBUG: #01 pc 00048027 /system/lib/libc.so (__pthread_internal_find(long)+94) 2019-10-10 16:46:27.182 20908-20908/? A/DEBUG: #02 pc 000480a9 /system/lib/libc.so (pthread_join+24) 2019-10-10 16:46:27.182 20908-20908/? A/DEBUG: #03 pc 0000eed0 /data/app/com.ayst.stresstest-WDheUqEUEOWXgF76IiWuAQ==/lib/arm/libUVCCamera.so (UVCPreview::stopPreview()+56) 2019-10-10 16:46:27.182 20908-20908/? A/DEBUG: #04 pc 000072b4 /data/app/com.ayst.stresstest-WDheUqEUEOWXgF76IiWuAQ==/lib/arm/libUVCCamera.so (UVCCamera::stopPreview()+16) 2019-10-10 16:46:27.182 20908-20908/? A/DEBUG: #05 pc 0000a3ef /data/app/com.ayst.stresstest-WDheUqEUEOWXgF76IiWuAQ==/oat/arm/base.odex (offset 0xa000)

aystshen commented 4 years ago

When do_preview calls uvc_start_streaming_bandwidth() with the following exception:

E/libuvc/stream: [22315*stream.c:1605:uvc_stream_start_bandwidth]:fail
W/libUVCCamera: [22315*diag.c:88:uvc_perror]:failed start_streaming:Unknown error (-99)

Calling UVCCamera.close() before will cause Crash:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'rockchip/rk3288/rk3288:8.1.0/OPM6.171019.030.K1/230314:userdebug/test-keys'
Revision: '0'
ABI: 'arm'
pid: 17899, tid: 18088, name: Timer-1  >>> com.ayst.stresstest <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'invalid pthread_t 0x4010409 passed to libc'
    r0 00000000  r1 000046a8  r2 00000006  r3 00000008
    r4 000045eb  r5 000046a8  r6 930fe68c  r7 0000010c
    r8 00000000  r9 93610a00  sl 00000000  fp 930fe700
    ip 930fea00  sp 930fe678  lr afe81a2f  pc afe7b43c  cpsr 200b0030
    d0  2064657300000000  d1  930fe8a000000000
    d2  930fe820bd6c8b44  d3  930fe860bf000000
    d4  00000001930fe818  d5  aeb712fd930fe8a4
    d6  aebf0fc9930fe924  d7  aedf077800000001
    d8  0000000000000000  d9  0000000000000000
    d10 0000000000000000  d11 0000000000000000
    d12 0000000000000000  d13 0000000000000000
    d14 0000000000000000  d15 0000000000000000
    d16 930ff5b000000000  d17 0000000000000000
    d18 0000000000000001  d19 00000000000006d6
    d20 000006d6000006d6  d21 0000000000000000
    d22 12f08e0012f291c8  d23 131c04a812f3edc8
    d24 ffffffffffffffff  d25 ffffffffffffffff
    d26 ffffffffffffffff  d27 ffffffffffffffff
    d28 afb96bb0afb96b50  d29 afb96d50afb96ce4
    d30 0000000000cc4c12  d31 afb96facafb96e44
    scr 20000013

backtrace:
    #00 pc 0001a43c  /system/lib/libc.so (abort+63)
    #01 pc 00048027  /system/lib/libc.so (__pthread_internal_find(long)+94)
    #02 pc 000480a9  /system/lib/libc.so (pthread_join+24)
    #03 pc 0000ffac  /data/app/com.ayst.stresstest-9VxpqIyuPDeuYsQ_paBtbg==/lib/arm/libUVCCamera.so (UVCPreview::stopPreview()+60)
    #04 pc 000088c4  /data/app/com.ayst.stresstest-9VxpqIyuPDeuYsQ_paBtbg==/lib/arm/libUVCCamera.so (UVCCamera::stopPreview()+20)
    #05 pc 00016d0f  /data/app/com.ayst.stresstest-9VxpqIyuPDeuYsQ_paBtbg==/oat/arm/base.odex (offset 0x12000)

Position the stack to the code location as follows:

pthread_join(capture_thread, NULL)

int UVCPreview::stopPreview() {
    ENTER();
    bool b = isRunning();
    if (LIKELY(b)) {
        mIsRunning = false;
        pthread_cond_signal(&preview_sync);
        pthread_cond_signal(&capture_sync);
        if (pthread_join(capture_thread, NULL) != EXIT_SUCCESS) {
            LOGW("UVCPreview::terminate capture thread: pthread_join failed");
        }
        if (pthread_join(preview_thread, NULL) != EXIT_SUCCESS) {
            LOGW("UVCPreview::terminate preview thread: pthread_join failed");
        }
        clearDisplay();
    }
...
}

The reasons: The capture_thread was not created because uvc_start_streaming_bandwidth returned an error.

void UVCPreview::do_preview(uvc_stream_ctrl_t *ctrl) {
    ENTER();

    uvc_frame_t *frame = NULL;
    uvc_frame_t *frame_mjpeg = NULL;
    uvc_error_t result = uvc_start_streaming_bandwidth(
        mDeviceHandle, ctrl, uvc_preview_frame_callback, (void *)this, requestBandwidth, 0);

    if (LIKELY(!result)) {
        clearPreviewFrame();
        pthread_create(&capture_thread, NULL, capture_thread_func, (void *)this);
        ...
}