/** * Tested on DPDK 21.11 * DPDK has been build by the following options: * meson setup build --prefix ~/dpdk.tsan --prefer-static --buildtype debug --debug -Denable_driver_sdk=false -Denable_kmods=false -Dc_std=gnu17 -Ddefault_library=static -Db_sanitize=thread -Dplatform=native -Dtests=false -Denable_trace_fp=true -Dc_args="-DRTE_USE_C11_MEM_MODEL=1 -Wno-tsan" -Ddisable_libs=acl,bpf,compressdev,cryptodev,gpudev,security,regexdev,pdump,pcapng,power -Ddisable_drivers=compress/*,crypto/*,event/*,baseband/*,gpu/*,regex/*,net/bnx*,net/qed*,net/ena*,net/af_*,net/cp*,net/id* * * Repro steps: * 1. build & install DPDK (see above) * 2. init test project: meson setup buildDir --debug -Db_sanitize=thread --pkg-config-path ~/dpdk.tsan/lib/x86_64-linux-gnu/pkgconfig/ * 3. build test project: meson compile -C buildDir * 4. run it: meson test -v -C buildDir */ #include #include #include #include #include #include #include #define VISIBLE __attribute__((visibility("default"), used)) #define NO_SANITIZE __attribute__((no_sanitize_address, no_sanitize_thread, no_sanitize_thread)) #ifdef __SANITIZE_THREAD__ const char TSANDefaultOptions[] = "halt_on_error=0:abort_on_error=0:verbosity=2:" "detect_deadlocks=1:second_deadlock_stack=1: report_signal_unsafe=0:" "report_thread_leaks=0:print_suppressions=1:" "force_seq_cst_atomics=0"; // do not enforce CST for atomic ops // The function isn't referenced from the executable itself. Make sure it isn't // stripped by the linker. extern NO_SANITIZE VISIBLE const char* __tsan_default_options(void); // NOLINT NO_SANITIZE VISIBLE const char* __tsan_default_options(void) { return TSANDefaultOptions; } #endif static int worker(void* __rte_unused args) { char name[64] = {0}; RTE_SET_USED(snprintf(name, sizeof(name), "%u", rte_lcore_id())); //struct rte_ring* r = rte_ring_create(name, 4, (int)rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ); char* p = rte_malloc(name, sizeof(name), 0); rte_pause(); RTE_VERIFY(p != NULL); //RTE_VERIFY(r != NULL); //rte_ring_free(r); rte_free(p); return 0; } int main(int argc, char* argv[]) { int ret = rte_eal_init(argc, argv); if (ret < 0) { puts(rte_strerror(rte_errno)); goto cleanup; } void* tmp = rte_malloc(NULL, 64, 0); RTE_VERIFY(tmp != NULL); RTE_SET_USED(tmp); rte_free(tmp); ret = rte_eal_mp_remote_launch(worker, NULL, SKIP_MAIN); if (ret < 0) { puts(rte_strerror(rte_errno)); goto cleanup; } rte_eal_mp_wait_lcore(); cleanup: rte_eal_cleanup(); return ret; }