@@ -13,6 +13,7 @@ typedef struct MemoryAccess {
13
13
u16 opcode ;
14
14
u64 size ;
15
15
u64 callee_thread_id ;
16
+ u64 memory_access_count ;
16
17
} MemoryAccess ;
17
18
18
19
typedef enum LockWritability {
@@ -28,10 +29,19 @@ typedef struct LockState {
28
29
usize unlock_count ;
29
30
} LockState ;
30
31
32
+
33
+ typedef struct LockAccess {
34
+ LockWritability state ;
35
+ usize addr ;
36
+ u64 callee_thread_id ;
37
+ u64 memory_access_count ;
38
+ } LockAccess ;
39
+
31
40
typedef struct MemoryAllocation {
32
41
usize addr ;
33
42
u64 size ;
34
43
u64 callee_thread_id ;
44
+ u64 memory_access_count ;
35
45
} MemoryAllocation ;
36
46
37
47
typedef struct ThreadState {
@@ -44,9 +54,18 @@ typedef struct ThreadState {
44
54
u64 mem_write_set_capacity ;
45
55
u64 mem_write_set_len ;
46
56
57
+
47
58
LockState * lock_state_set ;
48
59
u64 lock_state_set_capacity ;
49
60
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 ;
50
69
} ThreadState ;
51
70
52
71
@@ -57,6 +76,7 @@ u64 n_allocs = 0;
57
76
ThreadState threads [MAX_THREADS ] = {};
58
77
u64 n_threads = 0 ;
59
78
79
+ u64 memory_access_counter = 0 ;
60
80
61
81
// util fns..
62
82
void * increase_set_capacity (void * set , u64 * set_capacity ) {
@@ -75,6 +95,16 @@ i64 find_thread_by_tid(u64 tid) {
75
95
return -1 ;
76
96
}
77
97
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
+
78
108
u32 is_in_range (u64 num , u64 min , u64 max ) {
79
109
return (min <= num && num <= max );
80
110
}
@@ -97,6 +127,8 @@ void mem_analyse_exit() {
97
127
free (threads [j ].mem_write_set );
98
128
free (threads [j ].mem_read_set );
99
129
free (threads [j ].lock_state_set );
130
+ free (threads [j ].lock_write_held_set );
131
+ free (threads [j ].lock_read_held_set );
100
132
}
101
133
}
102
134
@@ -131,6 +163,20 @@ u32 mem_analyse_new_thread_init(void *drcontext) {
131
163
return 0 ;
132
164
}
133
165
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
+
134
180
n_threads += 1 ;
135
181
return 1 ;
136
182
}
@@ -194,7 +240,17 @@ void wrap_pre_lock(void *wrapcxt, OUT void **user_data) {
194
240
}
195
241
thread_accessed -> lock_state_set [i ].lock_count += 1 ;
196
242
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 ;
198
254
}
199
255
}
200
256
@@ -226,23 +282,11 @@ void wrap_pre_malloc(void *wrapcxt, OUT void **user_data) {
226
282
void check_for_race (ThreadState * thread_state ) {
227
283
int write_set_i , read_set_i , lock_set_i1 , lock_set_i2 ;
228
284
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
+ }
246
290
}
247
291
}
248
292
}
@@ -277,6 +321,8 @@ void memtrace(void *drcontext, u64 thread_id) {
277
321
BUF_PTR (data -> seg_base ) = data -> buf_base ;
278
322
return ;
279
323
}
324
+ memory_access_counter ++ ;
325
+ if (memory_access_counter >= LLONG_MAX ) DR_ASSERT (false);
280
326
u64 thread_id_owning_accessed_addr = allocations [j ].callee_thread_id ;
281
327
// printf("COMING THROUGH %ld \n", thread_id_owning_accessed_addr);
282
328
@@ -296,6 +342,7 @@ void memtrace(void *drcontext, u64 thread_id) {
296
342
thread_accessed -> mem_write_set [thread_accessed -> mem_write_set_len ].opcode = mem_ref -> type ;
297
343
thread_accessed -> mem_write_set [thread_accessed -> mem_write_set_len ].callee_thread_id = thread_id ;
298
344
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 ;
299
346
thread_accessed -> mem_write_set_len += 1 ;
300
347
} 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 ) {
301
348
// mem read
@@ -305,15 +352,11 @@ void memtrace(void *drcontext, u64 thread_id) {
305
352
thread_accessed -> mem_read_set [thread_accessed -> mem_read_set_len ].opcode = mem_ref -> type ;
306
353
thread_accessed -> mem_read_set [thread_accessed -> mem_read_set_len ].callee_thread_id = thread_id ;
307
354
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 ;
308
356
thread_accessed -> mem_read_set_len += 1 ;
309
357
}
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 :;
316
358
check_for_race (thread_accessed );
359
+ continue_outer_loop :;
317
360
data -> num_refs ++ ;
318
361
BUF_PTR (data -> seg_base ) = data -> buf_base ;
319
362
}
0 commit comments