pico-sdk icon indicating copy to clipboard operation
pico-sdk copied to clipboard

call to calloc() deadlocks with clang/picolibc

Open geurtv opened this issue 1 year ago • 2 comments

With clang 18.1.3 (from LLVM-embedded-toolchain-for-Arm) the calloc function in picolibc (so that's __real_calloc) calls malloc, which then deadlocks because __wrap_malloc tries to lock the mutex already owned by __wrap_calloc:

calloc == __wrap_calloc:
    lock mutex
    call __real_calloc

__real_calloc:
    call malloc

malloc == __wrap_malloc:
    lock mutex
    << deadlock >>

My work-around is to replace __wrap_calloc's implementation with a call to __wrap_malloc and then a memset:

void *WRAPPER_FUNC(calloc)(size_t count, size_t size) {
    size *= count;
    void* ptr = WRAPPER_FUNC(malloc)(size);
    memset(ptr, 0, size);
    return ptr;
}

NOTE 1: malloc+memset to replace calloc cannot be used because clang (and also gcc) will replace that code with a call to calloc. NOTE 2: picolibc sources say malloc already 'sets to zero', but it's probably not smart to rely on that.

geurtv avatar Sep 24 '24 14:09 geurtv