@@ -27,6 +27,40 @@ static void reportDeallocation(void *ptr) {
27
27
if (__scudo_deallocate_hook)
28
28
__scudo_deallocate_hook (ptr);
29
29
}
30
+ static void reportReallocBegin (void *old_ptr) {
31
+ if (SCUDO_ENABLE_HOOKS)
32
+ if (__scudo_realloc_begin_hook)
33
+ __scudo_realloc_begin_hook (old_ptr);
34
+ }
35
+ static void reportReallocEnd (void *old_ptr) {
36
+ if (SCUDO_ENABLE_HOOKS)
37
+ if (__scudo_realloc_end_hook)
38
+ __scudo_realloc_end_hook (old_ptr);
39
+ }
40
+
41
+ static void *reallocImpl (void *ptr, size_t size) {
42
+ // Given that the reporting of deallocation and allocation are not atomic, we
43
+ // always pretend the old pointer will be released so that the user doesn't
44
+ // need to worry about the false double-use case from the view of hooks.
45
+ //
46
+ // For example, assume that `realloc` releases the old pointer and allocates a
47
+ // new pointer. Before the reporting of both operations has been done, another
48
+ // thread may get the old pointer from `malloc`. It may be misinterpreted as
49
+ // double-use if it's not handled properly on the hook side.
50
+ reportDeallocation (ptr);
51
+ void *NewPtr = SCUDO_ALLOCATOR.reallocate (ptr, size, SCUDO_MALLOC_ALIGNMENT);
52
+ if (NewPtr != nullptr ) {
53
+ // Note that even if NewPtr == ptr, the size has changed. We still need to
54
+ // report the new size.
55
+ reportAllocation (NewPtr, size);
56
+ } else {
57
+ // If `realloc` fails, the old pointer is not released. Report the old
58
+ // pointer as allocated back.
59
+ reportAllocation (ptr, SCUDO_ALLOCATOR.getAllocSize (ptr));
60
+ }
61
+
62
+ return NewPtr;
63
+ }
30
64
31
65
extern " C" {
32
66
@@ -175,25 +209,11 @@ INTERFACE WEAK void *SCUDO_PREFIX(realloc)(void *ptr, size_t size) {
175
209
return nullptr ;
176
210
}
177
211
178
- // Given that the reporting of deallocation and allocation are not atomic, we
179
- // always pretend the old pointer will be released so that the user doesn't
180
- // need to worry about the false double-use case from the view of hooks.
181
- //
182
- // For example, assume that `realloc` releases the old pointer and allocates a
183
- // new pointer. Before the reporting of both operations has been done, another
184
- // thread may get the old pointer from `malloc`. It may be misinterpreted as
185
- // double-use if it's not handled properly on the hook side.
186
- reportDeallocation (ptr);
187
- void *NewPtr = SCUDO_ALLOCATOR.reallocate (ptr, size, SCUDO_MALLOC_ALIGNMENT);
188
- if (NewPtr != nullptr ) {
189
- // Note that even if NewPtr == ptr, the size has changed. We still need to
190
- // report the new size.
191
- reportAllocation (NewPtr, size);
192
- } else {
193
- // If `realloc` fails, the old pointer is not released. Report the old
194
- // pointer as allocated back.
195
- reportAllocation (ptr, SCUDO_ALLOCATOR.getAllocSize (ptr));
196
- }
212
+ reportReallocBegin (ptr);
213
+
214
+ void *NewPtr = reallocImpl (ptr, size);
215
+
216
+ reportReallocEnd (ptr);
197
217
198
218
return scudo::setErrnoOnNull (NewPtr);
199
219
}
0 commit comments