Skip to content

Commit 40fd075

Browse files
Merge pull request #11415 from thetruestblue/blueg/add_dispatch_apply
Cherry Pick Commits for adding interceptor for dispatch apply
2 parents 64e8060 + fe85e2c commit 40fd075

File tree

12 files changed

+287
-75
lines changed

12 files changed

+287
-75
lines changed

compiler-rt/lib/asan/asan_allocator.cpp

Lines changed: 97 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,13 +1007,8 @@ void PrintInternalAllocatorStats() {
10071007
instance.PrintStats();
10081008
}
10091009

1010-
void asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type) {
1011-
instance.Deallocate(ptr, 0, 0, stack, alloc_type);
1012-
}
1013-
1014-
void asan_delete(void *ptr, uptr size, uptr alignment,
1015-
BufferedStackTrace *stack, AllocType alloc_type) {
1016-
instance.Deallocate(ptr, size, alignment, stack, alloc_type);
1010+
void asan_free(void *ptr, BufferedStackTrace *stack) {
1011+
instance.Deallocate(ptr, 0, 0, stack, FROM_MALLOC);
10171012
}
10181013

10191014
void *asan_malloc(uptr size, BufferedStackTrace *stack) {
@@ -1068,16 +1063,15 @@ void *asan_pvalloc(uptr size, BufferedStackTrace *stack) {
10681063
instance.Allocate(size, PageSize, stack, FROM_MALLOC, true));
10691064
}
10701065

1071-
void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack,
1072-
AllocType alloc_type) {
1066+
void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack) {
10731067
if (UNLIKELY(!IsPowerOfTwo(alignment))) {
10741068
errno = errno_EINVAL;
10751069
if (AllocatorMayReturnNull())
10761070
return nullptr;
10771071
ReportInvalidAllocationAlignment(alignment, stack);
10781072
}
10791073
return SetErrnoOnNull(
1080-
instance.Allocate(size, alignment, stack, alloc_type, true));
1074+
instance.Allocate(size, alignment, stack, FROM_MALLOC, true));
10811075
}
10821076

10831077
void *asan_aligned_alloc(uptr alignment, uptr size, BufferedStackTrace *stack) {
@@ -1117,6 +1111,99 @@ uptr asan_malloc_usable_size(const void *ptr, uptr pc, uptr bp) {
11171111
return usable_size;
11181112
}
11191113

1114+
namespace {
1115+
1116+
void *asan_new(uptr size, BufferedStackTrace *stack, bool array) {
1117+
return SetErrnoOnNull(
1118+
instance.Allocate(size, 0, stack, array ? FROM_NEW_BR : FROM_NEW, true));
1119+
}
1120+
1121+
void *asan_new_aligned(uptr size, uptr alignment, BufferedStackTrace *stack,
1122+
bool array) {
1123+
if (UNLIKELY(alignment == 0 || !IsPowerOfTwo(alignment))) {
1124+
errno = errno_EINVAL;
1125+
if (AllocatorMayReturnNull())
1126+
return nullptr;
1127+
ReportInvalidAllocationAlignment(alignment, stack);
1128+
}
1129+
return SetErrnoOnNull(instance.Allocate(
1130+
size, alignment, stack, array ? FROM_NEW_BR : FROM_NEW, true));
1131+
}
1132+
1133+
void asan_delete(void *ptr, BufferedStackTrace *stack, bool array) {
1134+
instance.Deallocate(ptr, 0, 0, stack, array ? FROM_NEW_BR : FROM_NEW);
1135+
}
1136+
1137+
void asan_delete_aligned(void *ptr, uptr alignment, BufferedStackTrace *stack,
1138+
bool array) {
1139+
instance.Deallocate(ptr, 0, alignment, stack, array ? FROM_NEW_BR : FROM_NEW);
1140+
}
1141+
1142+
void asan_delete_sized(void *ptr, uptr size, BufferedStackTrace *stack,
1143+
bool array) {
1144+
instance.Deallocate(ptr, size, 0, stack, array ? FROM_NEW_BR : FROM_NEW);
1145+
}
1146+
1147+
void asan_delete_sized_aligned(void *ptr, uptr size, uptr alignment,
1148+
BufferedStackTrace *stack, bool array) {
1149+
instance.Deallocate(ptr, size, alignment, stack,
1150+
array ? FROM_NEW_BR : FROM_NEW);
1151+
}
1152+
1153+
} // namespace
1154+
1155+
void *asan_new(uptr size, BufferedStackTrace *stack) {
1156+
return asan_new(size, stack, /*array=*/false);
1157+
}
1158+
1159+
void *asan_new_aligned(uptr size, uptr alignment, BufferedStackTrace *stack) {
1160+
return asan_new_aligned(size, alignment, stack, /*array=*/false);
1161+
}
1162+
1163+
void *asan_new_array(uptr size, BufferedStackTrace *stack) {
1164+
return asan_new(size, stack, /*array=*/true);
1165+
}
1166+
1167+
void *asan_new_array_aligned(uptr size, uptr alignment,
1168+
BufferedStackTrace *stack) {
1169+
return asan_new_aligned(size, alignment, stack, /*array=*/true);
1170+
}
1171+
1172+
void asan_delete(void *ptr, BufferedStackTrace *stack) {
1173+
asan_delete(ptr, stack, /*array=*/false);
1174+
}
1175+
1176+
void asan_delete_aligned(void *ptr, uptr alignment, BufferedStackTrace *stack) {
1177+
asan_delete_aligned(ptr, alignment, stack, /*array=*/false);
1178+
}
1179+
1180+
void asan_delete_sized(void *ptr, uptr size, BufferedStackTrace *stack) {
1181+
asan_delete_sized(ptr, size, stack, /*array=*/false);
1182+
}
1183+
1184+
void asan_delete_sized_aligned(void *ptr, uptr size, uptr alignment,
1185+
BufferedStackTrace *stack) {
1186+
asan_delete_sized_aligned(ptr, size, alignment, stack, /*array=*/false);
1187+
}
1188+
1189+
void asan_delete_array(void *ptr, BufferedStackTrace *stack) {
1190+
asan_delete(ptr, stack, /*array=*/true);
1191+
}
1192+
1193+
void asan_delete_array_aligned(void *ptr, uptr alignment,
1194+
BufferedStackTrace *stack) {
1195+
asan_delete_aligned(ptr, alignment, stack, /*array=*/true);
1196+
}
1197+
1198+
void asan_delete_array_sized(void *ptr, uptr size, BufferedStackTrace *stack) {
1199+
asan_delete_sized(ptr, size, stack, /*array=*/true);
1200+
}
1201+
1202+
void asan_delete_array_sized_aligned(void *ptr, uptr size, uptr alignment,
1203+
BufferedStackTrace *stack) {
1204+
asan_delete_sized_aligned(ptr, size, alignment, stack, /*array=*/true);
1205+
}
1206+
11201207
uptr asan_mz_size(const void *ptr) {
11211208
return instance.AllocationSize(reinterpret_cast<uptr>(ptr));
11221209
}

compiler-rt/lib/asan/asan_allocator.h

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,8 @@ struct AsanThreadLocalMallocStorage {
270270
AsanThreadLocalMallocStorage() {}
271271
};
272272

273-
void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack,
274-
AllocType alloc_type);
275-
void asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type);
276-
void asan_delete(void *ptr, uptr size, uptr alignment,
277-
BufferedStackTrace *stack, AllocType alloc_type);
273+
void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack);
274+
void asan_free(void *ptr, BufferedStackTrace *stack);
278275

279276
void *asan_malloc(uptr size, BufferedStackTrace *stack);
280277
void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack);
@@ -289,6 +286,23 @@ int asan_posix_memalign(void **memptr, uptr alignment, uptr size,
289286
BufferedStackTrace *stack);
290287
uptr asan_malloc_usable_size(const void *ptr, uptr pc, uptr bp);
291288

289+
void *asan_new(uptr size, BufferedStackTrace *stack);
290+
void *asan_new_aligned(uptr size, uptr alignment, BufferedStackTrace *stack);
291+
void *asan_new_array(uptr size, BufferedStackTrace *stack);
292+
void *asan_new_array_aligned(uptr size, uptr alignment,
293+
BufferedStackTrace *stack);
294+
void asan_delete(void *ptr, BufferedStackTrace *stack);
295+
void asan_delete_aligned(void *ptr, uptr alignment, BufferedStackTrace *stack);
296+
void asan_delete_sized(void *ptr, uptr size, BufferedStackTrace *stack);
297+
void asan_delete_sized_aligned(void *ptr, uptr size, uptr alignment,
298+
BufferedStackTrace *stack);
299+
void asan_delete_array(void *ptr, BufferedStackTrace *stack);
300+
void asan_delete_array_aligned(void *ptr, uptr alignment,
301+
BufferedStackTrace *stack);
302+
void asan_delete_array_sized(void *ptr, uptr size, BufferedStackTrace *stack);
303+
void asan_delete_array_sized_aligned(void *ptr, uptr size, uptr alignment,
304+
BufferedStackTrace *stack);
305+
292306
uptr asan_mz_size(const void *ptr);
293307
void asan_mz_force_lock();
294308
void asan_mz_force_unlock();

compiler-rt/lib/asan/asan_mac.cpp

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ void FlushUnneededASanShadowMemory(uptr p, uptr size) {
103103
// dispatch_after()
104104
// dispatch_group_async_f()
105105
// dispatch_group_async()
106+
// dispatch_apply()
107+
// dispatch_apply_f()
106108
// TODO(glider): libdispatch API contains other functions that we don't support
107109
// yet.
108110
//
@@ -128,6 +130,7 @@ typedef void* dispatch_queue_t;
128130
typedef void* dispatch_source_t;
129131
typedef u64 dispatch_time_t;
130132
typedef void (*dispatch_function_t)(void *block);
133+
typedef void (*dispatch_apply_function_t)(void *, size_t);
131134
typedef void* (*worker_t)(void *block);
132135
typedef unsigned long dispatch_mach_reason;
133136
typedef void *dispatch_mach_msg_t;
@@ -147,7 +150,11 @@ typedef void (^dispatch_mach_handler_t)(dispatch_mach_reason reason,
147150
// A wrapper for the ObjC blocks used to support libdispatch.
148151
typedef struct {
149152
void *block;
150-
dispatch_function_t func;
153+
union {
154+
dispatch_function_t dispatch_func;
155+
dispatch_apply_function_t dispatch_apply_func;
156+
static_assert(sizeof(dispatch_func) == sizeof(dispatch_apply_func));
157+
};
151158
u32 parent_tid;
152159
} asan_block_context_t;
153160

@@ -175,8 +182,8 @@ void asan_dispatch_call_block_and_release(void *block) {
175182
block, (void*)pthread_self());
176183
asan_register_worker_thread(context->parent_tid, &stack);
177184
// Call the original dispatcher for the block.
178-
context->func(context->block);
179-
asan_free(context, &stack, FROM_MALLOC);
185+
context->dispatch_func(context->block);
186+
asan_free(context, &stack);
180187
}
181188

182189
} // namespace __asan
@@ -191,7 +198,7 @@ asan_block_context_t *alloc_asan_context(void *ctxt, dispatch_function_t func,
191198
asan_block_context_t *asan_ctxt =
192199
(asan_block_context_t*) asan_malloc(sizeof(asan_block_context_t), stack);
193200
asan_ctxt->block = ctxt;
194-
asan_ctxt->func = func;
201+
asan_ctxt->dispatch_func = func;
195202
asan_ctxt->parent_tid = GetCurrentTidOrInvalid();
196203
return asan_ctxt;
197204
}
@@ -243,13 +250,34 @@ INTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group,
243250
asan_dispatch_call_block_and_release);
244251
}
245252

246-
#if !defined(MISSING_BLOCKS_SUPPORT)
253+
extern "C" void asan_dispatch_apply_f_work(void *context, size_t iteration) {
254+
GET_STACK_TRACE_THREAD;
255+
asan_block_context_t *asan_ctxt = (asan_block_context_t *)context;
256+
asan_register_worker_thread(asan_ctxt->parent_tid, &stack);
257+
asan_ctxt->dispatch_apply_func(asan_ctxt->block, iteration);
258+
}
259+
260+
INTERCEPTOR(void, dispatch_apply_f, size_t iterations, dispatch_queue_t queue,
261+
void *ctxt, dispatch_apply_function_t work) {
262+
GET_STACK_TRACE_THREAD;
263+
asan_block_context_t *asan_ctxt =
264+
(asan_block_context_t *)asan_malloc(sizeof(asan_block_context_t), &stack);
265+
asan_ctxt->block = ctxt;
266+
asan_ctxt->dispatch_apply_func = work;
267+
asan_ctxt->parent_tid = GetCurrentTidOrInvalid();
268+
REAL(dispatch_apply_f)(iterations, queue, (void *)asan_ctxt,
269+
asan_dispatch_apply_f_work);
270+
}
271+
272+
# if !defined(MISSING_BLOCKS_SUPPORT)
247273
extern "C" {
248274
void dispatch_async(dispatch_queue_t dq, void(^work)(void));
249275
void dispatch_group_async(dispatch_group_t dg, dispatch_queue_t dq,
250276
void(^work)(void));
251277
void dispatch_after(dispatch_time_t when, dispatch_queue_t queue,
252278
void(^work)(void));
279+
void dispatch_apply(size_t iterations, dispatch_queue_t queue,
280+
void (^block)(size_t iteration));
253281
void dispatch_source_set_cancel_handler(dispatch_source_t ds,
254282
void(^work)(void));
255283
void dispatch_source_set_event_handler(dispatch_source_t ds, void(^work)(void));
@@ -332,6 +360,20 @@ INTERCEPTOR(void *, dispatch_mach_create_f, const char *label,
332360
});
333361
}
334362

335-
#endif
363+
INTERCEPTOR(void, dispatch_apply, size_t iterations, dispatch_queue_t queue,
364+
void (^block)(size_t iteration)) {
365+
ENABLE_FRAME_POINTER;
366+
int parent_tid = GetCurrentTidOrInvalid();
367+
368+
void (^asan_block)(size_t) = ^(size_t iteration) {
369+
GET_STACK_TRACE_THREAD;
370+
asan_register_worker_thread(parent_tid, &stack);
371+
block(iteration);
372+
};
373+
374+
REAL(dispatch_apply)(iterations, queue, asan_block);
375+
}
376+
377+
# endif
336378

337379
#endif // SANITIZER_APPLE

compiler-rt/lib/asan/asan_malloc_linux.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,15 @@ INTERCEPTOR(void, free, void *ptr) {
4949
if (DlsymAlloc::PointerIsMine(ptr))
5050
return DlsymAlloc::Free(ptr);
5151
GET_STACK_TRACE_FREE;
52-
asan_free(ptr, &stack, FROM_MALLOC);
52+
asan_free(ptr, &stack);
5353
}
5454

5555
#if SANITIZER_INTERCEPT_CFREE
5656
INTERCEPTOR(void, cfree, void *ptr) {
5757
if (DlsymAlloc::PointerIsMine(ptr))
5858
return DlsymAlloc::Free(ptr);
5959
GET_STACK_TRACE_FREE;
60-
asan_free(ptr, &stack, FROM_MALLOC);
60+
asan_free(ptr, &stack);
6161
}
6262
#endif // SANITIZER_INTERCEPT_CFREE
6363

@@ -93,12 +93,12 @@ INTERCEPTOR(void*, reallocarray, void *ptr, uptr nmemb, uptr size) {
9393
#if SANITIZER_INTERCEPT_MEMALIGN
9494
INTERCEPTOR(void*, memalign, uptr boundary, uptr size) {
9595
GET_STACK_TRACE_MALLOC;
96-
return asan_memalign(boundary, size, &stack, FROM_MALLOC);
96+
return asan_memalign(boundary, size, &stack);
9797
}
9898

9999
INTERCEPTOR(void*, __libc_memalign, uptr boundary, uptr size) {
100100
GET_STACK_TRACE_MALLOC;
101-
return asan_memalign(boundary, size, &stack, FROM_MALLOC);
101+
return asan_memalign(boundary, size, &stack);
102102
}
103103
#endif // SANITIZER_INTERCEPT_MEMALIGN
104104

compiler-rt/lib/asan/asan_malloc_mac.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ using namespace __asan;
3131
# define COMMON_MALLOC_FORCE_UNLOCK() asan_mz_force_unlock()
3232
# define COMMON_MALLOC_MEMALIGN(alignment, size) \
3333
GET_STACK_TRACE_MALLOC; \
34-
void *p = asan_memalign(alignment, size, &stack, FROM_MALLOC)
34+
void *p = asan_memalign(alignment, size, &stack)
3535
# define COMMON_MALLOC_MALLOC(size) \
3636
GET_STACK_TRACE_MALLOC; \
3737
void *p = asan_malloc(size, &stack)
@@ -46,10 +46,10 @@ using namespace __asan;
4646
int res = asan_posix_memalign(memptr, alignment, size, &stack);
4747
# define COMMON_MALLOC_VALLOC(size) \
4848
GET_STACK_TRACE_MALLOC; \
49-
void *p = asan_memalign(GetPageSizeCached(), size, &stack, FROM_MALLOC);
49+
void *p = asan_memalign(GetPageSizeCached(), size, &stack);
5050
# define COMMON_MALLOC_FREE(ptr) \
5151
GET_STACK_TRACE_FREE; \
52-
asan_free(ptr, &stack, FROM_MALLOC);
52+
asan_free(ptr, &stack);
5353
# define COMMON_MALLOC_SIZE(ptr) uptr size = asan_mz_size(ptr);
5454
# define COMMON_MALLOC_FILL_STATS(zone, stats) \
5555
AsanMallocStats malloc_stats; \

compiler-rt/lib/asan/asan_malloc_win.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ __declspec(noinline) size_t _msize_base(void *ptr) { return _msize(ptr); }
6969

7070
__declspec(noinline) void free(void *ptr) {
7171
GET_STACK_TRACE_FREE;
72-
return asan_free(ptr, &stack, FROM_MALLOC);
72+
return asan_free(ptr, &stack);
7373
}
7474

7575
__declspec(noinline) void _free_dbg(void *ptr, int) { free(ptr); }
@@ -252,7 +252,7 @@ INTERCEPTOR_WINAPI(BOOL, HeapFree, HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
252252
CHECK((HEAP_FREE_UNSUPPORTED_FLAGS & dwFlags) != 0 && "unsupported flags");
253253
}
254254
GET_STACK_TRACE_FREE;
255-
asan_free(lpMem, &stack, FROM_MALLOC);
255+
asan_free(lpMem, &stack);
256256
return true;
257257
}
258258

@@ -306,7 +306,7 @@ void *SharedReAlloc(ReAllocFunction reallocFunc, SizeFunction heapSizeFunc,
306306
if (replacement_alloc) {
307307
size_t old_size = heapSizeFunc(hHeap, dwFlags, lpMem);
308308
if (old_size == ((size_t)0) - 1) {
309-
asan_free(replacement_alloc, &stack, FROM_MALLOC);
309+
asan_free(replacement_alloc, &stack);
310310
return nullptr;
311311
}
312312
REAL(memcpy)(replacement_alloc, lpMem, old_size);
@@ -331,7 +331,7 @@ void *SharedReAlloc(ReAllocFunction reallocFunc, SizeFunction heapSizeFunc,
331331
old_usable_size = asan_malloc_usable_size(lpMem, pc, bp);
332332
REAL(memcpy)(replacement_alloc, lpMem,
333333
Min<size_t>(dwBytes, old_usable_size));
334-
asan_free(lpMem, &stack, FROM_MALLOC);
334+
asan_free(lpMem, &stack);
335335
}
336336
return replacement_alloc;
337337
}
@@ -429,7 +429,7 @@ INTERCEPTOR_WINAPI(BOOL, RtlFreeHeap, HANDLE HeapHandle, DWORD Flags,
429429
return REAL(RtlFreeHeap)(HeapHandle, Flags, BaseAddress);
430430
}
431431
GET_STACK_TRACE_FREE;
432-
asan_free(BaseAddress, &stack, FROM_MALLOC);
432+
asan_free(BaseAddress, &stack);
433433
return true;
434434
}
435435

0 commit comments

Comments
 (0)