[tsan] Return 0 from malloc_size for non-malloc'd pointers
In http://reviews.llvm.org/D19100, I introduced a bug: On OS X, existing programs rely on malloc_size() to detect whether a pointer comes from heap memory (malloc_size returns non-zero) or not. We have to distinguish between a zero-sized allocation (where we need to return 1 from malloc_size, due to other binary compatibility reasons, see http://reviews.llvm.org/D19100), and pointers that are not returned from malloc at all. Differential Revision: http://reviews.llvm.org/D19653 llvm-svn: 268157
This commit is contained in:
parent
eb5bd02a7e
commit
9ccde5ace4
@ -53,8 +53,7 @@ using namespace __tsan;
|
||||
SCOPED_INTERCEPTOR_RAW(free, ptr); \
|
||||
user_free(thr, pc, ptr)
|
||||
#define COMMON_MALLOC_SIZE(ptr) \
|
||||
uptr size = user_alloc_usable_size(ptr); \
|
||||
if (size == 0) size = 1;
|
||||
uptr size = user_alloc_usable_size(ptr);
|
||||
#define COMMON_MALLOC_FILL_STATS(zone, stats)
|
||||
#define COMMON_MALLOC_REPORT_UNKNOWN_REALLOC(ptr, zone_ptr, zone_name) \
|
||||
(void)zone_name; \
|
||||
|
||||
@ -164,7 +164,11 @@ uptr user_alloc_usable_size(const void *p) {
|
||||
if (p == 0)
|
||||
return 0;
|
||||
MBlock *b = ctx->metamap.GetBlock((uptr)p);
|
||||
return b ? b->siz : 0;
|
||||
if (!b)
|
||||
return 0; // Not a valid pointer.
|
||||
if (b->siz == 0)
|
||||
return 1; // Zero-sized allocations are actually 1 byte.
|
||||
return b->siz;
|
||||
}
|
||||
|
||||
void invoke_malloc_hook(void *ptr, uptr size) {
|
||||
|
||||
@ -6,18 +6,50 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <malloc/malloc.h>
|
||||
|
||||
int main() {
|
||||
void *p = malloc(0);
|
||||
|
||||
size_t s = malloc_size(p);
|
||||
printf("size = 0x%zx\n", s);
|
||||
int some_global;
|
||||
|
||||
void describe_zone(void *p) {
|
||||
malloc_zone_t *z = malloc_zone_from_ptr(p);
|
||||
if (z)
|
||||
printf("z = %p\n", z);
|
||||
else
|
||||
printf("no zone\n");
|
||||
if (z) {
|
||||
fprintf(stderr, "zone = %p\n", z);
|
||||
} else {
|
||||
fprintf(stderr, "zone = no zone\n");
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: z = 0x{{[0-9a-f]+}}
|
||||
// CHECK-NOT: no zone
|
||||
int main() {
|
||||
void *p;
|
||||
size_t s;
|
||||
|
||||
p = malloc(0x40);
|
||||
s = malloc_size(p);
|
||||
fprintf(stderr, "size = 0x%zx\n", s);
|
||||
// CHECK: size = 0x40
|
||||
describe_zone(p);
|
||||
// CHECK: zone = 0x{{[0-9a-f]+}}
|
||||
|
||||
p = malloc(0);
|
||||
s = malloc_size(p);
|
||||
fprintf(stderr, "size = 0x%zx\n", s);
|
||||
// CHECK: size = 0x1
|
||||
describe_zone(p);
|
||||
// CHECK: zone = 0x{{[0-9a-f]+}}
|
||||
|
||||
p = &some_global;
|
||||
s = malloc_size(p);
|
||||
fprintf(stderr, "size = 0x%zx\n", s);
|
||||
// CHECK: size = 0x0
|
||||
describe_zone(p);
|
||||
// CHECK: zone = no zone
|
||||
|
||||
p = mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
|
||||
if (!p) {
|
||||
fprintf(stderr, "mmap failed\n");
|
||||
exit(1);
|
||||
}
|
||||
s = malloc_size(p);
|
||||
fprintf(stderr, "size = 0x%zx\n", s);
|
||||
// CHECK: size = 0x0
|
||||
describe_zone(p);
|
||||
// CHECK: zone = no zone
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user