asar coverage - build #


src/asar/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
55 of 62, 0 excluded
88.7%
Functions:
10 of 10, 0 excluded
100.0%
Branches:
26 of 76, 0 excluded
34.2%

platform/generic/thread-helpers-pthread.h
Line Branch Exec Source
1 #pragma once
2
3 #include <stdint.h>
4 #include <pthread.h>
5
6 struct function_pointer_wrapper /*have this struct at global level*/
7 {
8 static void* (*thread_callback)(void*);
9 160 static void* execute_thread(void* parameter) { return thread_callback(parameter); }
10 };
11
12 void* (*function_pointer_wrapper::thread_callback)(void*) = nullptr;
13
14 template <typename functor>
15 160 bool run_as_thread(functor&& callback) {
16 struct thread_wrapper {
17 functor& callback;
18 bool result;
19
20 160 void* execute() {
21 160 result = callback();
22
5/10
run_as_thread<asar_patch::{lambda()#1}&>(asar_patch::{lambda()#1}&)::thread_wrapper::execute():
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 157 times.
✓ Branch 10 → 11 taken 119 times.
✓ Branch 10 → 12 taken 38 times.
run_as_thread<main::{lambda()#1}&>(main::{lambda()#1}&)::thread_wrapper::execute():
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 3 times.
✓ Branch 10 → 11 taken 3 times.
✗ Branch 10 → 12 not taken.
160 if (result)
23 122 pthread_exit(NULL);
24 else
25 38 pthread_exit(reinterpret_cast<void*>((uintptr_t)-1));
26 }
27
28 160 } wrapper{ callback, false };
29
30 160 function_pointer_wrapper::thread_callback = [](void* parameter) {
31 160 return reinterpret_cast<thread_wrapper*>(parameter)->execute();
32 };
33
34 160 pthread_attr_t settings;
35 160 pthread_t thread_id;
36 int ret;
37
38
2/4
bool run_as_thread<asar_patch::{lambda()#1}&>(asar_patch::{lambda()#1}&):
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 157 times.
bool run_as_thread<main::{lambda()#1}&>(main::{lambda()#1}&):
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 3 times.
160 ret = pthread_attr_init(&settings);
39
2/6
bool run_as_thread<asar_patch::{lambda()#1}&>(asar_patch::{lambda()#1}&):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 7 not taken.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 15 taken 157 times.
bool run_as_thread<main::{lambda()#1}&>(main::{lambda()#1}&):
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 15 taken 3 times.
160 if (ret == -1){
40 return callback();
41 }
42
43
2/4
bool run_as_thread<asar_patch::{lambda()#1}&>(asar_patch::{lambda()#1}&):
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 157 times.
bool run_as_thread<main::{lambda()#1}&>(main::{lambda()#1}&):
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 3 times.
160 ret = pthread_attr_setstacksize(&settings, 16 * 1024 * 1024);
44
2/6
bool run_as_thread<asar_patch::{lambda()#1}&>(asar_patch::{lambda()#1}&):
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 11 not taken.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 22 taken 157 times.
bool run_as_thread<main::{lambda()#1}&>(main::{lambda()#1}&):
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 22 taken 3 times.
160 if (ret == -1){
45 return callback();
46 }
47
48
4/8
bool run_as_thread<asar_patch::{lambda()#1}&>(asar_patch::{lambda()#1}&):
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 24 taken 157 times.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 157 times.
bool run_as_thread<main::{lambda()#1}&>(main::{lambda()#1}&):
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 24 taken 3 times.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 3 times.
160 ret = pthread_create(&thread_id, &settings, &function_pointer_wrapper::execute_thread, &wrapper);
49
2/6
bool run_as_thread<asar_patch::{lambda()#1}&>(asar_patch::{lambda()#1}&):
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 15 not taken.
✗ Branch 27 → 28 not taken.
✓ Branch 27 → 31 taken 157 times.
bool run_as_thread<main::{lambda()#1}&>(main::{lambda()#1}&):
✗ Branch 27 → 28 not taken.
✓ Branch 27 → 31 taken 3 times.
160 if (ret == -1){
50 return callback();
51 }
52
53 160 void* thread_ret;
54
2/6
bool run_as_thread<asar_patch::{lambda()#1}&>(asar_patch::{lambda()#1}&):
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 19 not taken.
✓ Branch 32 → 33 taken 157 times.
✗ Branch 32 → 41 not taken.
bool run_as_thread<main::{lambda()#1}&>(main::{lambda()#1}&):
✓ Branch 32 → 33 taken 3 times.
✗ Branch 32 → 41 not taken.
160 pthread_join(thread_id, &thread_ret);
55
56
2/4
bool run_as_thread<asar_patch::{lambda()#1}&>(asar_patch::{lambda()#1}&):
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 35 taken 157 times.
bool run_as_thread<main::{lambda()#1}&>(main::{lambda()#1}&):
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 35 taken 3 times.
160 return wrapper.result;
57 }
58
59 #ifndef NO_USE_THREADS
60 void* stack_bottom = nullptr;
61 470 void init_stack_use_check() {
62 470 pthread_t self = pthread_self();
63 #ifdef __APPLE__
64 stack_bottom = (char*)pthread_get_stackaddr_np(self) - pthread_get_stacksize_np(self);
65 #else
66 470 pthread_attr_t attrs;
67 470 size_t stack_size = 0;
68 470 pthread_getattr_np(self, &attrs);
69 470 pthread_attr_getstack(&attrs, &stack_bottom, &stack_size);
70 470 pthread_attr_destroy(&attrs);
71 #endif
72 470 }
73 465 void deinit_stack_use_check() {
74 465 stack_bottom = nullptr;
75 465 }
76 72963 bool have_enough_stack_left() {
77 #if defined(__clang__) || defined(__GNUC__)
78 // this is a GCC extension, but it's necessary for this function to work in ASan
79 // (regular local variables are banished to the shadow realm or some shit,
80 // so their addresses don't tell us anything about "real" stack usage)
81 72963 void* stack_top = __builtin_frame_address(0);
82 #else
83 // using a random local as a rough estimate for current top-of-stack
84 char stackvar;
85 void* stack_top = &stackvar;
86 #endif
87 72963 ssize_t stack_left = (char*)stack_top - (char*)stack_bottom;
88
3/4
✓ Branch 3 → 4 taken 72954 times.
✓ Branch 3 → 5 taken 9 times.
✓ Branch 4 → 5 taken 72954 times.
✗ Branch 4 → 6 not taken.
72963 return stack_bottom == nullptr || stack_left >= 32768;
89 }
90 #endif
91