{"id":18654186,"url":"https://github.com/tracktion/rtcheck","last_synced_at":"2025-04-11T17:31:10.889Z","repository":{"id":243664358,"uuid":"802237696","full_name":"Tracktion/rtcheck","owner":"Tracktion","description":"Dynamic library to catch run-time safety violations","archived":false,"fork":false,"pushed_at":"2024-06-18T09:42:06.000Z","size":121,"stargazers_count":19,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-25T16:21:31.977Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Tracktion.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-17T19:50:10.000Z","updated_at":"2025-03-09T00:03:33.000Z","dependencies_parsed_at":"2024-06-10T14:24:32.996Z","dependency_job_id":null,"html_url":"https://github.com/Tracktion/rtcheck","commit_stats":null,"previous_names":["tracktion/rtcheck"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tracktion%2Frtcheck","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tracktion%2Frtcheck/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tracktion%2Frtcheck/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tracktion%2Frtcheck/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Tracktion","download_url":"https://codeload.github.com/Tracktion/rtcheck/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248449701,"owners_count":21105544,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T07:14:16.974Z","updated_at":"2025-04-11T17:31:10.447Z","avatar_url":"https://github.com/Tracktion.png","language":"C++","readme":"[![Build](https://github.com/Tracktion/rtcheck/actions/workflows/build.yml/badge.svg)](https://github.com/Tracktion/rtcheck/actions/workflows/build.yml)\n\n\u003cimg src=\"rtcheck_icon.svg\" width=80 /\u003e\n\n# rtcheck\nDynamic library to catch run-time safety violations heavily inspired by [RADSan](https://github.com/realtime-sanitizer/radsan)\n\n## Contents\n- [Adding rtcheck to a project](#adding-rtcheck-to-a-project)\n- [Using rtcheck](#using-rtcheck)\n- [Disabling checks](#disabling-checks)\n- [Catching your own violations](#catching-your-own-violations)\n- [Error modes](#error-modes)\n\n## Adding rtcheck to a project\n### CMake option 1: Git Submodule\n```\ngit submodule add -b main https://github.com/Tracktion/rtcheck rtcheck\n```\n\nTo update down the road:\n```\ngit submodule update --remote --merge rtcheck\n```\n\n#### Build rtcheck as part of your CMakeLists.txt\n```cmake\nadd_subdirectory(rtcheck)\n```\n\n### CMake option 2: FetchContent\n```cmake\nInclude(FetchContent)\nFetchContent_Declare(rtcheck\n    GIT_REPOSITORY https://github.com/Tracktion/rtcheck.git\n    GIT_TAG origin/main\n    SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/rtcheck)\nFetchContent_MakeAvailable(rtcheck)\n```\n\n### Link rtcheck to your CMake project\n```cmake\ntarget_link_libraries(\"YourProject\" PRIVATE rtcheck)\n```\n\nThen include rtcheck in your source files:\n```c++\n#include \u003crtcheck.h\u003e\n```\n\n## Using rtcheck\nSimply add an instance of `rtc::realtime_context` at the start of the scope you want to check for real-time safety violations like this:  \n```c++\nint main()\n{\n    std::thread t ([]\n    {\n        rtc::realtime_context rc;\n        malloc (1024); // Allocating memory is a real-time safety violation!\n    });\n\n    t.join();\n\n    return 0;\n}\n```\nThe call to malloc in the above code will then be caught and logged as so:\n```\nReal-time violation: intercepted call to real-time unsafe function malloc in real-time context! Stack trace:\n0   librt_check.dylib                   0x000000010543f7d4 _ZN3rtc14get_stacktraceEv + 84\n 1   librt_check.dylib                   0x000000010543f450 _ZN3rtc32log_function_if_realtime_contextEPKc + 300\n  2   librt_check.dylib                   0x000000010543fe00 _Z44log_function_if_realtime_context_and_enabledN3rtc11check_flagsEPKc + 64\n   3   librt_check.dylib                   0x000000010543fe30 wrap_malloc + 32\n    4   fail_malloc                         0x0000000104fcff14 main + 32\n     5   dyld                                0x00000001901760e0 start + 2360\n```\n\n## Disabling checks\nThere are two ways to disable checks. You can either disable all checks, which can be useful if you \nknow you'll be calling a potentially unsafe function but in a safe way (e.g. an un-contented lock), or you want to log something:\n```c++\n{\n    rtc::non_realtime_context nrc;\n    std::cout \u003c\u003c \"need to get this message on the screen!\";\n}\n```\nOr you can selectively disable checks:\n```c++\n{\n    rtc::disable_checks_for_thread (check_flags::threads);\n    mutex.lock(); // I know this is uncontended, don't for get to unlock!\n}\n```\n\n## Catching your own violations\nIf you have some code which you know is non-real-time safe e.g. an unbounded distribution function or some other async call, you can opt-in to let rtcheck catch it by calling the following function:\n```c++\nvoid my_unsafe_function()\n{\n    log_function_if_realtime_context (__func__);\n}\n```\nThis will then get logged if called whilst a `rtc::realtime_context` is alive.\n\n## Error Modes\nThere are two currently supported error modes\n- Exit with error code 1 (default)\n- Log and continue\n\nExiting it useful for CI runs where you want the program to terminate in an obvious way (non-zero exit code) to fail the run.\nIn normal use though, you may just want to log the violation and continue.\n\nYou can change between these globally using the following function:\n```c++\n/** Sets the global error more to determine the behaviour when a real-time\n    violation is detected.\n*/\nvoid set_error_mode (error_mode);\n```\n---\n# Notes:\n## Features\n- [x] Enable in scope\n- [x] Disable in scope\n- [x] Symbolicated stack-trace\n- [x] Run-time options for checks\n- [x] Opt-in for own code\n- [x] linux\n- [x] macOS (malloc unsupported)\n- [ ] Add option to realtime_context constructor to disable checks for that scope\n- [ ] Delay time\n\n## Functions (test = ✔)\n- Time\n  - [x] sleep ✔\n  - [x] nanosleep ✔\n  - [x] usleep ✔\n- Memory\n  - [x] malloc ✔\n  - [x] calloc ✔\n  - [x] realloc ✔\n  - [x] free ✔\n  - [x] reallocf (macOS) ✔\n  - [x] valloc ✔\n  - [x] posix_memalign ✔\n  - [x] mmap ✔\n  - [x] munmap ✔\n- Threads\n  - [x] pthread_create ✔\n  - [x] pthread_mutex_lock ✔\n  - [x] pthread_mutex_unlock ✔\n  - [x] pthread_join ✔\n  - [x] pthread_cond_signal\n  - [x] pthread_cond_broadcast\n  - [x] pthread_cond_wait\n  - [x] pthread_cond_timedwait\n  - [x] pthread_rwlock_rdlock ✔\n  - [x] pthread_rwlock_unlock ✔\n  - [x] pthread_rwlock_wrlock ✔\n  - [x] pthread_spin_lock (linux)\n- Files\n  - [x] open ✔\n  - [x] openat\n  - [ ] close\n  - [x] fopen\n  - [ ] fread\n  - [ ] fwrite\n  - [ ] fclose\n  - [x] fcntl ✔\n  - [ ] creat\n  - [ ] puts\n  - [ ] fputs\n  - [x] stat ✔\n  - [ ] stat64\n  - [x] fstat\n  - [ ] fstat64\n- IO\n  - [ ] socket\n  - [ ] send\n  - [ ] sendmsg\n  - [ ] sendto\n  - [ ] recv\n  - [ ] recvmsg\n  - [ ] recvfrom\n  - [ ] shutdown\n- System calls \n  - [x] syscall ✔\n  - [x] schedule\n  - [x] context_switch\n\n## CI/Tests\n- Failures\n  - [x] Throwing exceptions\n  - [x] Large std::function\n  - [x] Atomic 4*ptr size\n  - [ ] Dynamic loading of a library\n- Passes\n  - [x] Atomic double\n  - [x] Small std::function\n  - [x] thread_local? (pass on linux, fail on macOS)\n- [x] Running on CI Linux\n- [x] Running on CI macOS\n- [x] Tests via CTest (can catch failues)\n\n## Packages\n- [ ] cpack\n- [ ] conan\n- [ ] vcpkg\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftracktion%2Frtcheck","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftracktion%2Frtcheck","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftracktion%2Frtcheck/lists"}