launchdarkly / c-client-sdk

LaunchDarkly Client-side SDK for C/C++
Other
7 stars 15 forks source link

Deadlock in LDClientIdentify #75

Closed juancampa closed 2 years ago

juancampa commented 2 years ago

Is this a support request? No

Describe the bug This SDK can deadlock because a couple of rwlocks are being acquired in reverse order.

The two rwlocks involved are:

  1. sharedUserLock
  2. clientLock

The deadlock occurs if LDClientIdentify runs concurrently with LDi_readstream or LDi_fetchfeaturemap. Because:

If both functions are running simultaneously, there's a probability of a deadlock ☠️

Here's an instance where we found that happening:

Thread 19 (Thread 0x7f09e3fff700 (LWP 1041)):
#0  0x00007f0a22a7a57f in futex_abstimed_wait (private=<optimized out>, abstime=0x0, expected=3, futex_word=0x7f0a1b7fe4a8 <globalContext+40>) at ../sysdeps/unix/sysv/linux/futex-internal.h:172
#1  0x00007f0a22a7a57f in __pthread_rwlock_rdlock_full (abstime=0x0, rwlock=0x7f0a1b7fe4a0 <globalContext+32>) at pthread_rwlock_common.c:446
#2  0x00007f0a22a7a57f in __GI___pthread_rwlock_rdlock (rwlock=0x7f0a1b7fe4a0 <globalContext+32>) at pthread_rwlock_rdlock.c:27
#3  0x00007f0a1b4aad83 in LDi_rwlock_rdlock_imp () at <redacted>
#4  0x00007f0a1b4bf601 in LDi_readstream () at <redacted>
#5  0x00007f0a1b4b51fa in LDi_bgfeaturestreamer () at <redacted>
#6  0x00007f0a22a756db in start_thread (arg=0x7f09e3fff700) at pthread_create.c:463
#7  0x00007f0a2279e61f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 1 (Thread 0x7f0a239d3780 (LWP 908)):
#0  0x00007f0a22a7aa74 in futex_abstimed_wait (private=<optimized out>, abstime=0x0, expected=2, futex_word=0x4ad0b08) at ../sysdeps/unix/sysv/linux/futex-internal.h:172
#1  0x00007f0a22a7aa74 in __pthread_rwlock_wrlock_full (abstime=0x0, rwlock=0x4ad0b00) at pthread_rwlock_common.c:803
#2  0x00007f0a22a7aa74 in __GI___pthread_rwlock_wrlock (rwlock=0x4ad0b00) at pthread_rwlock_wrlock.c:27
#3  0x00007f0a1b4aae45 in LDi_rwlock_wrlock_imp () at <redacted>
#4  0x00007f0a1b4af2b9 in LDClientIdentify () at <redacted>
#5  0x00007f0a1b4c18d2 in LDClientCPP::identify(LDUser*) () at <redacted>
#6  0x00007f0a1b25a3c1 in app::SetUser(Napi::CallbackInfo const&) () at <redacted>
#7  0x00007f0a1b29a760 in Napi::details::CallbackData<void (*)(Napi::CallbackInfo const&), void>::Wrapper(napi_env__*, napi_callback_info__*) () at <redacted>
#8  0x00000000009eaa8d in v8impl::(anonymous namespace)::FunctionCallbackWrapper::Invoke(v8::FunctionCallbackInfo<v8::Value> const&) ()
#9  0x0000000000c262eb in v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) ()
#10 0x0000000000c27896 in v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*) ()
#11 0x0000000000c27f16 in v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) ()
#12 0x0000000001448ef9 in Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit ()
#13 0x00000000013df942 in Builtins_InterpreterEntryTrampoline ()
...

To reproduce Be unlucky enough to have the above two functions running at the same time

Expected behavior Not to deadlock

Logs N/A

SDK version 2.4.4

Language version, developer tools C/C++

OS/platform Ubuntu 16.04

Additional context N/A

cwaldren-ld commented 2 years ago

Thank you, @juancampa, for the detailed report. We will investigate this.

Filed internally as 154701.

cwaldren-ld commented 2 years ago

Hi @juancampa , the 2.4.5 release should fix the deadlock. Please re-test and let me know if the issue is resolved.

cwaldren-ld commented 2 years ago

I'm going to go ahead and close this issue as the fix has been released. If you still have any problems, please feel free to open another issue.

Thanks!