From 3b846986f4502ba068741437ca3ee2a04d82d526 Mon Sep 17 00:00:00 2001 From: Michael Tyson Date: Mon, 13 Jun 2016 12:28:30 +1000 Subject: [PATCH] Added more overrides to AERealtimeWatchdog; simplified header --- .../Utilities/AERealtimeWatchdog.h | 21 +-- .../Utilities/AERealtimeWatchdog.m | 156 +++++++++++++----- 2 files changed, 119 insertions(+), 58 deletions(-) diff --git a/TheAmazingAudioEngine/Utilities/AERealtimeWatchdog.h b/TheAmazingAudioEngine/Utilities/AERealtimeWatchdog.h index eb8e299..de2a57e 100644 --- a/TheAmazingAudioEngine/Utilities/AERealtimeWatchdog.h +++ b/TheAmazingAudioEngine/Utilities/AERealtimeWatchdog.h @@ -26,27 +26,8 @@ // #ifdef DEBUG + // Uncomment the following to enable the realtime watchdog // #define REALTIME_WATCHDOG_ENABLED 1 -#endif - -#ifdef __OBJC__ - -#import - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - * Function called when unsafe activity is noticed on the audio thread - * - * Put a breakpoint here to debug. - */ -void AERealtimeWatchdogUnsafeActivityWarning(); - -#ifdef __cplusplus -} -#endif #endif diff --git a/TheAmazingAudioEngine/Utilities/AERealtimeWatchdog.m b/TheAmazingAudioEngine/Utilities/AERealtimeWatchdog.m index 23c85c3..ace02c4 100644 --- a/TheAmazingAudioEngine/Utilities/AERealtimeWatchdog.m +++ b/TheAmazingAudioEngine/Utilities/AERealtimeWatchdog.m @@ -33,6 +33,7 @@ #import #import #import +#include // Uncomment the following to report every time we spot something bad, not just the first time // #define REPORT_EVERY_INFRACTION @@ -82,76 +83,155 @@ BOOL AERealtimeWatchdogIsOnRealtimeThread() { // Signatures for the functions we'll override typedef void * (*malloc_t)(size_t); typedef void (*free_t)(void*); -typedef id (*objc_storeStrong_t)(id *object, id value); -typedef id (*objc_msgSend_t)(void); typedef int (*pthread_mutex_lock_t)(pthread_mutex_t *); typedef int (*objc_sync_enter_t)(id obj); +typedef id (*objc_storeStrong_t)(id *object, id value); +typedef id (*objc_msgSend_t)(void); +typedef ssize_t (*send_t)(int socket, const void *buffer, size_t length, int flags); +typedef ssize_t (*sendto_t)(int socket, const void *buffer, size_t length, int flags, + const struct sockaddr *dest_addr, socklen_t dest_len); +typedef ssize_t (*recv_t)(int socket, void *buffer, size_t length, int flags); +typedef ssize_t (*recvfrom_t)(int socket, void *restrict buffer, size_t length, int flags, + struct sockaddr *restrict address, socklen_t *restrict address_len); +typedef FILE * (*fopen_t)(const char *restrict filename, const char *restrict mode); +typedef size_t (*fread_t)(void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream); +typedef size_t (*fwrite_t)(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream); +typedef char * (*fgets_t)(char * restrict str, int size, FILE * restrict stream); +typedef ssize_t (*read_t)(int fildes, void *buf, size_t nbyte); +typedef ssize_t (*pread_t)(int d, void *buf, size_t nbyte, off_t offset); +typedef ssize_t (*write_t)(int fildes, const void *buf, size_t nbyte); +typedef ssize_t (*pwrite_t)(int fildes, const void *buf, size_t nbyte, off_t offset); + + +// Overrides void * malloc(size_t sz) { static malloc_t funcptr = NULL; - if ( !funcptr ) { - funcptr = (malloc_t) dlsym(RTLD_NEXT, "malloc"); - } - if ( AERealtimeWatchdogIsOnRealtimeThread() ) { - AERealtimeWatchdogUnsafeActivityWarning("malloc"); - } + if ( !funcptr ) funcptr = (malloc_t) dlsym(RTLD_NEXT, "malloc"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("malloc"); return funcptr(sz); } void free(void *p) { static free_t funcptr = NULL; - if ( !funcptr ) { - funcptr = (free_t) dlsym(RTLD_NEXT, "free"); - }; - if ( AERealtimeWatchdogIsOnRealtimeThread() ) { - AERealtimeWatchdogUnsafeActivityWarning("free"); - } + if ( !funcptr ) funcptr = (free_t) dlsym(RTLD_NEXT, "free"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("free"); funcptr(p); } int pthread_mutex_lock(pthread_mutex_t * mutex) { static pthread_mutex_lock_t funcptr = NULL; - if ( !funcptr ) { - funcptr = (pthread_mutex_lock_t) dlsym(RTLD_NEXT, "pthread_mutex_lock"); - }; - if ( AERealtimeWatchdogIsOnRealtimeThread() ) { - AERealtimeWatchdogUnsafeActivityWarning("pthread_mutex_lock"); - } + if ( !funcptr ) funcptr = (pthread_mutex_lock_t) dlsym(RTLD_NEXT, "pthread_mutex_lock"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("pthread_mutex_lock"); return funcptr(mutex); } int objc_sync_enter(id obj) { static objc_sync_enter_t funcptr = NULL; - if ( !funcptr ) { - funcptr = (objc_sync_enter_t) dlsym(RTLD_NEXT, "objc_sync_enter"); - }; - if ( AERealtimeWatchdogIsOnRealtimeThread() ) { - AERealtimeWatchdogUnsafeActivityWarning("@synchronized block"); - } + if ( !funcptr ) funcptr = (objc_sync_enter_t) dlsym(RTLD_NEXT, "objc_sync_enter"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("@synchronized block"); return funcptr(obj); } id objc_storeStrong(id * object, id value) { static objc_storeStrong_t funcptr = NULL; - if ( !funcptr ) { - funcptr = (objc_storeStrong_t) dlsym(RTLD_NEXT, "objc_storeStrong"); - }; - if ( AERealtimeWatchdogIsOnRealtimeThread() ) { - AERealtimeWatchdogUnsafeActivityWarning("object retain"); - } + if ( !funcptr ) funcptr = (objc_storeStrong_t) dlsym(RTLD_NEXT, "objc_storeStrong"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("object retain"); return funcptr(object,value); } objc_msgSend_t AERealtimeWatchdogLookupMsgSendAndWarn() { // This method is called by our objc_msgSend implementation static objc_msgSend_t funcptr = NULL; - if ( !funcptr ) { - funcptr = (objc_msgSend_t) dlsym(RTLD_NEXT, "objc_msgSend"); - }; - if ( AERealtimeWatchdogIsOnRealtimeThread() ) { - AERealtimeWatchdogUnsafeActivityWarning("message send"); - } + if ( !funcptr ) funcptr = (objc_msgSend_t) dlsym(RTLD_NEXT, "objc_msgSend"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("message send"); return funcptr; } +ssize_t send(int socket, const void *buffer, size_t length, int flags) { + static send_t funcptr = NULL; + if ( !funcptr ) funcptr = (send_t) dlsym(RTLD_NEXT, "send"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("send"); + return funcptr(socket, buffer, length, flags); +} + +ssize_t sendto(int socket, const void *buffer, size_t length, int flags, + const struct sockaddr *dest_addr, socklen_t dest_len) { + static sendto_t funcptr = NULL; + if ( !funcptr ) funcptr = (sendto_t) dlsym(RTLD_NEXT, "sendto"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("sendto"); + return funcptr(socket, buffer, length, flags, dest_addr, dest_len); +} + +ssize_t recv(int socket, void *buffer, size_t length, int flags) { + static recv_t funcptr = NULL; + if ( !funcptr ) funcptr = (recv_t) dlsym(RTLD_NEXT, "recv"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("recv"); + return funcptr(socket, buffer, length, flags); +} + +ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags, + struct sockaddr *restrict address, socklen_t *restrict address_len) { + static recvfrom_t funcptr = NULL; + if ( !funcptr ) funcptr = (recvfrom_t) dlsym(RTLD_NEXT, "recvfrom"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("recvfrom"); + return funcptr(socket, buffer, length, flags, address, address_len); +} + +FILE * fopen(const char *restrict filename, const char *restrict mode) { + static fopen_t funcptr = NULL; + if ( !funcptr ) funcptr = (fopen_t) dlsym(RTLD_NEXT, "fopen"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("fopen"); + return funcptr(filename, mode); +} + +size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream) { + static fread_t funcptr = NULL; + if ( !funcptr ) funcptr = (fread_t) dlsym(RTLD_NEXT, "fread"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("fread"); + return funcptr(ptr, size, nitems, stream); +} + +size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream) { + static fwrite_t funcptr = NULL; + if ( !funcptr ) funcptr = (fwrite_t) dlsym(RTLD_NEXT, "fwrite"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("fwrite"); + return funcptr(ptr, size, nitems, stream); +} + +char * fgets(char * restrict str, int size, FILE * restrict stream) { + static fgets_t funcptr = NULL; + if ( !funcptr ) funcptr = (fgets_t) dlsym(RTLD_NEXT, "fgets"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("fgets"); + return funcptr(str, size, stream); +} + +ssize_t read(int fildes, void *buf, size_t nbyte) { + static read_t funcptr = NULL; + if ( !funcptr ) funcptr = (read_t) dlsym(RTLD_NEXT, "read"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("read"); + return funcptr(fildes, buf, nbyte); +} + +ssize_t pread(int d, void *buf, size_t nbyte, off_t offset) { + static pread_t funcptr = NULL; + if ( !funcptr ) funcptr = (pread_t) dlsym(RTLD_NEXT, "pread"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("pread"); + return funcptr(d, buf, nbyte, offset); +} + +ssize_t write(int fildes, const void *buf, size_t nbyte) { + static write_t funcptr = NULL; + if ( !funcptr ) funcptr = (write_t) dlsym(RTLD_NEXT, "write"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("write"); + return funcptr(fildes, buf, nbyte); +} + +ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset) { + static pwrite_t funcptr = NULL; + if ( !funcptr ) funcptr = (pwrite_t) dlsym(RTLD_NEXT, "pwrite"); + if ( AERealtimeWatchdogIsOnRealtimeThread() ) AERealtimeWatchdogUnsafeActivityWarning("pwrite"); + return funcptr(fildes, buf, nbyte, offset); +} + #endif