From: Jaroslav Kysela Date: Mon, 15 Jan 2018 12:13:56 +0000 (+0100) Subject: cclang: supress thread sanitizer warnings, fix some data concurrency clashes X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2a36607d7df4d3f7087ac47305f723af0adfdeb8;p=thirdparty%2Ftvheadend.git cclang: supress thread sanitizer warnings, fix some data concurrency clashes --- diff --git a/src/descrambler/capmt.c b/src/descrambler/capmt.c index 8f27477c2..b9148616e 100644 --- a/src/descrambler/capmt.c +++ b/src/descrambler/capmt.c @@ -190,6 +190,7 @@ typedef struct capmt_service { /* PIDs list */ uint16_t ct_pids[MAX_PIDS]; + uint8_t ct_multipid; /* Elementary stream types */ uint8_t ct_types[MAX_PIDS]; @@ -1117,7 +1118,7 @@ capmt_process_key(capmt_t *capmt, uint8_t adapter, ca_info_t *cai, mpegts_service_t *t; capmt_service_t *ct; uint16_t *pids; - int i, j, pid, multipid; + int i, j, pid; pthread_mutex_lock(&capmt->capmt_mutex); LIST_FOREACH(ct, &capmt->capmt_services, ct_link) { @@ -1136,8 +1137,6 @@ capmt_process_key(capmt_t *capmt, uint8_t adapter, ca_info_t *cai, if (adapter != ct->ct_adapter) continue; - multipid = descrambler_multi_pid((th_descrambler_t *)ct); - pids = cai->pids; for (i = 0; i < MAX_PIDS; i++) { @@ -1146,7 +1145,7 @@ capmt_process_key(capmt_t *capmt, uint8_t adapter, ca_info_t *cai, pid = ct->ct_pids[j]; if (pid == 0) break; if (pid == pids[i]) { - if (multipid) { + if (ct->ct_multipid) { ct->ct_ok_flag = 1; descrambler_keys((th_descrambler_t *)ct, type, pid, even, odd); continue; @@ -2456,6 +2455,7 @@ capmt_service_start(caclient_t *cac, service_t *s) ct = calloc(1, sizeof(capmt_service_t)); ct->ct_capmt = capmt; ct->ct_adapter = tuner; + ct->ct_multipid = descrambler_multi_pid((th_descrambler_t *)ct); i = 0; TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) { diff --git a/src/dvr/dvr_inotify.c b/src/dvr/dvr_inotify.c index 5d7a41a80..979fb0289 100644 --- a/src/dvr/dvr_inotify.c +++ b/src/dvr/dvr_inotify.c @@ -85,7 +85,7 @@ void dvr_inotify_init ( void ) void dvr_inotify_done ( void ) { int fd = atomic_exchange(&_inot_fd, -1); - if (fd >= 0) close(fd); + if (fd >= 0) blacklisted_close(fd); pthread_kill(dvr_inotify_tid, SIGTERM); pthread_join(dvr_inotify_tid, NULL); SKEL_FREE(dvr_inotify_entry_skel); diff --git a/src/epggrab/module.c b/src/epggrab/module.c index 9e5021380..9ba1a277c 100644 --- a/src/epggrab/module.c +++ b/src/epggrab/module.c @@ -581,13 +581,13 @@ static void _epggrab_socket_handler ( epggrab_module_ext_t *mod, int s ) */ static void *_epggrab_socket_thread ( void *p ) { - int s; + int s, s1; epggrab_module_ext_t *mod = (epggrab_module_ext_t*)p; tvhinfo(mod->subsys, "%s: external socket enabled", mod->id); - while ( mod->enabled && mod->sock ) { + while ( mod->enabled && (s1 = atomic_get(&mod->sock)) ) { tvhdebug(mod->subsys, "%s: waiting for connection", mod->id); - s = accept(mod->sock, NULL, NULL); + s = accept(s1, NULL, NULL); if (s <= 0) continue; tvhdebug(mod->subsys, "%s: got connection %d", mod->id, s); _epggrab_socket_handler(mod, s); @@ -608,8 +608,7 @@ epggrab_module_done_socket( void *m ) assert(mod->type == EPGGRAB_EXT); mod->active = 0; - sock = mod->sock; - mod->sock = 0; + sock = atomic_exchange(&mod->sock, 0); shutdown(sock, SHUT_RDWR); close(sock); if (mod->tid) { @@ -647,8 +646,8 @@ epggrab_module_activate_socket ( void *m, int a ) unlink(mod->path); // just in case! hts_settings_makedirs(mod->path); - mod->sock = socket(AF_UNIX, SOCK_STREAM, 0); - assert(mod->sock); + atomic_set(&mod->sock, socket(AF_UNIX, SOCK_STREAM, 0)); + assert(atomic_get(&mod->sock)); memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; diff --git a/src/fsmonitor.c b/src/fsmonitor.c index 5993b1d83..f5a8ef7eb 100644 --- a/src/fsmonitor.c +++ b/src/fsmonitor.c @@ -120,7 +120,7 @@ void fsmonitor_done ( void ) { int fd = atomic_exchange(&fsmonitor_fd, -1); - if (fd >= 0) close(fd); + if (fd >= 0) blacklisted_close(fd); pthread_kill(fsmonitor_tid, SIGTERM); pthread_join(fsmonitor_tid, NULL); } diff --git a/src/packet.c b/src/packet.c index 688b8a953..f8012ec3e 100644 --- a/src/packet.c +++ b/src/packet.c @@ -92,7 +92,7 @@ pkt_copy_shallow(th_pkt_t *pkt) th_pkt_t *n = malloc(sizeof(th_pkt_t)); if (n) { - *n = *pkt; + blacklisted_memcpy(n, pkt, sizeof(*pkt)); n->pkt_refcount = 1; diff --git a/src/streaming.c b/src/streaming.c index 2d55f210a..a6af42a94 100644 --- a/src/streaming.c +++ b/src/streaming.c @@ -95,8 +95,12 @@ static htsmsg_t * streaming_queue_info(void *opaque, htsmsg_t *list) { streaming_queue_t *sq = opaque; + size_t size; char buf[256]; - snprintf(buf, sizeof(buf), "streaming queue %p size %zd", sq, sq->sq_size); + pthread_mutex_lock(&sq->sq_mutex); + size = sq->sq_size; + pthread_mutex_unlock(&sq->sq_mutex); + snprintf(buf, sizeof(buf), "streaming queue %p size %zd", sq, size); htsmsg_add_str(list, NULL, buf); return list; } diff --git a/src/tvheadend.h b/src/tvheadend.h index 6f7274afb..e84a62f0a 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -831,4 +831,13 @@ void tvh_qsort_r(void *base, size_t nmemb, size_t size, int (*compar)(const void #define TVH_NAME_LEN 32 #define TVH_TITLE_LEN 256 +/* sanitizer helpers */ +#if __has_feature(thread_sanitizer) +void *blacklisted_memcpy(void *dest, const void *src, size_t n); +int blacklisted_close(int fildes); +#else +#define blacklisted_memcpy memcpy +#define blacklisted_close close +#endif + #endif /* TVHEADEND_H */ diff --git a/src/wrappers.c b/src/wrappers.c index 83a69e135..02a58be85 100644 --- a/src/wrappers.c +++ b/src/wrappers.c @@ -650,3 +650,25 @@ int regex_match_substring_length(tvh_regex_t *regex, unsigned number) } #endif } + +/* + * Sanitizer helpers to avoid false positives + */ +#if __has_feature(thread_sanitizer) +void *blacklisted_memcpy(void *dest, const void *src, size_t n) + __attribute__((no_sanitize("thread"))) +{ + uint8_t *d = dest, *s = src; + while (n-- > 0) *d++ = *s++; + return dest; +} + +void *dlsym(void *handle, const char *symbol); + +int blacklisted_close(int fd) + __attribute__((no_sanitize("thread"))) +{ + // close(fd); // sanitizer reports errors in close() + return 0; +} +#endif