Skip to content

Commit dcace0f

Browse files
committed
adding memory access count and proper scan for read d. races
1 parent 35caea6 commit dcace0f

File tree

3 files changed

+69
-26
lines changed

3 files changed

+69
-26
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
project(sample)
22
add_library(myclient SHARED instrument.c error_detector.c)
33
target_include_directories(myclient PRIVATE ${include/})
4-
find_package(DynamoRIO PATHS ../DynamoRIO/cmake)
4+
find_package(DynamoRIO PATHS ../Libs/DynamoRIO-AArch64-Linux-9.0.1/cmake)
55
if (NOT DynamoRIO_FOUND)
66
message(FATAL_ERROR "DynamoRIO package required to build")
77
endif(NOT DynamoRIO_FOUND)

buildAndRun.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
bash build.sh
2-
../DynamoRIO/bin64/drrun -c build/libmyclient.so -- basicMultiThread.elf -lpthread
2+
../Libs//DynamoRIO-AArch64-Linux-9.0.1/bin64/drrun -c build/libmyclient.so -- basicMultiThread.elf -lpthread

error_detector.c

+67-24
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ typedef struct MemoryAccess {
1313
u16 opcode;
1414
u64 size;
1515
u64 callee_thread_id;
16+
u64 memory_access_count;
1617
} MemoryAccess;
1718

1819
typedef enum LockWritability {
@@ -28,10 +29,19 @@ typedef struct LockState {
2829
usize unlock_count;
2930
} LockState;
3031

32+
33+
typedef struct LockAccess {
34+
LockWritability state;
35+
usize addr;
36+
u64 callee_thread_id;
37+
u64 memory_access_count;
38+
} LockAccess;
39+
3140
typedef struct MemoryAllocation {
3241
usize addr;
3342
u64 size;
3443
u64 callee_thread_id;
44+
u64 memory_access_count;
3545
} MemoryAllocation;
3646

3747
typedef struct ThreadState {
@@ -44,9 +54,18 @@ typedef struct ThreadState {
4454
u64 mem_write_set_capacity;
4555
u64 mem_write_set_len;
4656

57+
4758
LockState *lock_state_set;
4859
u64 lock_state_set_capacity;
4960
u64 lock_state_set_len;
61+
62+
LockAccess *lock_write_held_set;
63+
u64 lock_write_held_set_capacity;
64+
u64 lock_write_held_set_len;
65+
66+
LockAccess *lock_read_held_set;
67+
u64 lock_read_held_set_capacity;
68+
u64 lock_read_held_set_len;
5069
} ThreadState;
5170

5271

@@ -57,6 +76,7 @@ u64 n_allocs = 0;
5776
ThreadState threads[MAX_THREADS] = {};
5877
u64 n_threads = 0;
5978

79+
u64 memory_access_counter = 0;
6080

6181
// util fns..
6282
void *increase_set_capacity(void *set, u64 *set_capacity) {
@@ -75,6 +95,16 @@ i64 find_thread_by_tid(u64 tid) {
7595
return -1;
7696
}
7797

98+
i64 find_lockset_by_memory_access_count(LockAccess *lock_set, u64 lock_set_len, u64 access_count) {
99+
u64 i;
100+
for (i = 0; i <= lock_set_len; i++) {
101+
if (lock_set[i].memory_access_count == access_count) {
102+
return i;
103+
}
104+
}
105+
return -1;
106+
}
107+
78108
u32 is_in_range(u64 num, u64 min, u64 max) {
79109
return (min <= num && num <= max);
80110
}
@@ -97,6 +127,8 @@ void mem_analyse_exit() {
97127
free(threads[j].mem_write_set);
98128
free(threads[j].mem_read_set);
99129
free(threads[j].lock_state_set);
130+
free(threads[j].lock_write_held_set);
131+
free(threads[j].lock_read_held_set);
100132
}
101133
}
102134

@@ -131,6 +163,20 @@ u32 mem_analyse_new_thread_init(void *drcontext) {
131163
return 0;
132164
}
133165

166+
threads[n_threads].lock_write_held_set = (LockAccess*)malloc(sizeof(LockAccess) * linear_set_size_increment);
167+
threads[n_threads].lock_write_held_set_capacity = linear_set_size_increment;
168+
if (threads[n_threads].lock_write_held_set == NULL) {
169+
printf("set allocation error \n");
170+
return 0;
171+
}
172+
173+
threads[n_threads].lock_read_held_set = (LockAccess*)malloc(sizeof(LockAccess) * linear_set_size_increment);
174+
threads[n_threads].lock_read_held_set_capacity = linear_set_size_increment;
175+
if (threads[n_threads].lock_read_held_set == NULL) {
176+
printf("set allocation error \n");
177+
return 0;
178+
}
179+
134180
n_threads += 1;
135181
return 1;
136182
}
@@ -194,7 +240,17 @@ void wrap_pre_lock(void *wrapcxt, OUT void **user_data) {
194240
}
195241
thread_accessed->lock_state_set[i].lock_count += 1;
196242
if (thread_accessed->lock_state_set[i].lock_count >= thread_accessed->lock_state_set[i].lock_count) {
197-
thread_accessed->lock_state_set[i].state = WriteHeld;
243+
// now the lock is write held
244+
thread_accessed->lock_write_held_set[thread_accessed->lock_write_held_set_len].addr = (usize) addr;
245+
thread_accessed->lock_write_held_set[thread_accessed->lock_write_held_set_len].callee_thread_id = thread_id;
246+
thread_accessed->lock_write_held_set[thread_accessed->lock_write_held_set_len].memory_access_count = memory_access_counter;
247+
thread_accessed->lock_write_held_set_len += 1;
248+
} else {
249+
// read held
250+
thread_accessed->lock_read_held_set[thread_accessed->lock_read_held_set_len].addr = (usize) addr;
251+
thread_accessed->lock_read_held_set[thread_accessed->lock_read_held_set_len].callee_thread_id = thread_id;
252+
thread_accessed->lock_read_held_set[thread_accessed->lock_read_held_set_len].memory_access_count = memory_access_counter;
253+
thread_accessed->lock_read_held_set_len += 1;
198254
}
199255
}
200256

@@ -226,23 +282,11 @@ void wrap_pre_malloc(void *wrapcxt, OUT void **user_data) {
226282
void check_for_race(ThreadState *thread_state) {
227283
int write_set_i, read_set_i, lock_set_i1, lock_set_i2;
228284
for (write_set_i = 0; write_set_i <= thread_state->mem_write_set_len; write_set_i++) {
229-
for (lock_set_i2 = 0; lock_set_i2 <= thread_state->lock_state_set_len; lock_set_i2++) {
230-
if(thread_state->lock_state_set[lock_set_i2].addr == thread_state->mem_write_set[write_set_i].address_accessed) {
231-
// u32 lock_found = 0;
232-
233-
// for (read_set_i = 0; read_set_i <= thread_state->mem_read_set_len; read_set_i++) {
234-
// if(thread_state->lock_state_set[lock_set_i2].addr == thread_state->mem_read_set[read_set_i].address_accessed) {
235-
// for (lock_set_i1 = 0; lock_set_i1 <= thread_state->lock_state_set_len; lock_set_i1++) {
236-
// if(thread_state->lock_state_set[lock_set_i2].addr == thread_state->lock_state_set[lock_set_i1].addr) {
237-
// lock_found = 1;
238-
// }
239-
// }
240-
// }
241-
// }
242-
243-
// if (lock_found) {
244-
// printf("NO RACE CONDITION \n");
245-
// }
285+
for (read_set_i = 0; read_set_i <= thread_state->mem_read_set_len; read_set_i++) {
286+
if (thread_state->mem_write_set[write_set_i].memory_access_count > thread_state->mem_read_set[read_set_i].memory_access_count) {
287+
if (find_lockset_by_memory_access_count(thread_state->lock_write_held_set, thread_state->lock_write_held_set_len, thread_state->lock_write_held_set[write_set_i].memory_access_count) == -1 || find_lockset_by_memory_access_count(thread_state->lock_write_held_set, thread_state->lock_write_held_set_len, thread_state->mem_read_set[read_set_i].memory_access_count) == -1) {
288+
printf("FOUND!\n");
289+
}
246290
}
247291
}
248292
}
@@ -277,6 +321,8 @@ void memtrace(void *drcontext, u64 thread_id) {
277321
BUF_PTR(data->seg_base) = data->buf_base;
278322
return;
279323
}
324+
memory_access_counter++;
325+
if (memory_access_counter >= LLONG_MAX) DR_ASSERT(false);
280326
u64 thread_id_owning_accessed_addr = allocations[j].callee_thread_id;
281327
// printf("COMING THROUGH %ld \n", thread_id_owning_accessed_addr);
282328

@@ -296,6 +342,7 @@ void memtrace(void *drcontext, u64 thread_id) {
296342
thread_accessed->mem_write_set[thread_accessed->mem_write_set_len].opcode = mem_ref->type;
297343
thread_accessed->mem_write_set[thread_accessed->mem_write_set_len].callee_thread_id = thread_id;
298344
thread_accessed->mem_write_set[thread_accessed->mem_write_set_len].size = mem_ref->size;
345+
thread_accessed->mem_write_set[thread_accessed->mem_write_set_len].memory_access_count = memory_access_counter;
299346
thread_accessed->mem_write_set_len += 1;
300347
} else if(mem_ref->type == 0 || mem_ref->type == 227 || mem_ref->type == 225 || mem_ref->type == 197 || mem_ref->type == 228 || mem_ref->type == 229 || mem_ref->type == 299 || mem_ref->type == 173) {
301348
// mem read
@@ -305,15 +352,11 @@ void memtrace(void *drcontext, u64 thread_id) {
305352
thread_accessed->mem_read_set[thread_accessed->mem_read_set_len].opcode = mem_ref->type;
306353
thread_accessed->mem_read_set[thread_accessed->mem_read_set_len].callee_thread_id = thread_id;
307354
thread_accessed->mem_read_set[thread_accessed->mem_read_set_len].size = mem_ref->size;
355+
thread_accessed->mem_read_set[thread_accessed->mem_read_set_len].memory_access_count = memory_access_counter;
308356
thread_accessed->mem_read_set_len += 1;
309357
}
310-
// else {
311-
// printf("missed %d \n", mem_ref->type);
312-
// }
313-
// // /* We use PIFX to avoid leading zeroes and shrink the resulting file. */
314-
// fprintf(data->logf, "" PIFX ": %2d, %s (%d)\n", (ptr_uint_t)mem_ref->addr, mem_ref->size, (mem_ref->type > REF_TYPE_WRITE) ? decode_opcode_name(mem_ref->type) /* opcode for instr */ : (mem_ref->type == REF_TYPE_WRITE ? "w" : "r"), mem_ref->type);
315-
continue_outer_loop:;
316358
check_for_race(thread_accessed);
359+
continue_outer_loop:;
317360
data->num_refs++;
318361
BUF_PTR(data->seg_base) = data->buf_base;
319362
}

0 commit comments

Comments
 (0)