tsan_mman.cc revision 1acfa02e08e6d3316c80f52255cbb7d9e3164128
1603c4be006d8c53905d736bf1f19a49f5ce98276Alexey Samsonov//===-- tsan_mman.cc ------------------------------------------------------===// 27ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// 37ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// The LLVM Compiler Infrastructure 47ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// 57ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// This file is distributed under the University of Illinois Open Source 67ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// License. See LICENSE.TXT for details. 77ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// 87ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//===----------------------------------------------------------------------===// 97ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// 107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// This file is a part of ThreadSanitizer (TSan), a race detector. 117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// 127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//===----------------------------------------------------------------------===// 13f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov#include "sanitizer_common/sanitizer_common.h" 142e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov#include "sanitizer_common/sanitizer_placement_new.h" 157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_mman.h" 167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_rtl.h" 177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_report.h" 187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_flags.h" 197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 204f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov// May be overriden by front-end. 214f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonovextern "C" void WEAK __tsan_malloc_hook(void *ptr, uptr size) { 224f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov (void)ptr; 234f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov (void)size; 244f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov} 254f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov 264f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonovextern "C" void WEAK __tsan_free_hook(void *ptr) { 274f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov (void)ptr; 284f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov} 294f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov 307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanynamespace __tsan { 317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 32ff35f1d82b4f145b3477ef27a7a2e7b63c486988Dmitry Vyukovstatic char allocator_placeholder[sizeof(Allocator)] ALIGNED(64); 33ff35f1d82b4f145b3477ef27a7a2e7b63c486988Dmitry VyukovAllocator *allocator() { 342e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov return reinterpret_cast<Allocator*>(&allocator_placeholder); 352e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov} 362e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov 372e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukovvoid InitializeAllocator() { 382e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov allocator()->Init(); 392e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov} 402e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov 41bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukovvoid AllocatorThreadStart(ThreadState *thr) { 42bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov allocator()->InitCache(&thr->alloc_cache); 43bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov} 44bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov 45bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukovvoid AllocatorThreadFinish(ThreadState *thr) { 46bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov allocator()->DestroyCache(&thr->alloc_cache); 47bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov} 48bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov 49bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukovvoid AllocatorPrintStats() { 50bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov allocator()->PrintStats(); 512e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov} 522e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov 537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void SignalUnsafeCall(ThreadState *thr, uptr pc) { 547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (!thr->in_signal_handler || !flags()->report_signal_unsafe) 557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return; 56158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov Context *ctx = CTX(); 577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany StackTrace stack; 587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany stack.ObtainCurrent(thr, pc); 59fb917e9069ea44f7103f50c658be84a8f66de56cDmitry Vyukov Lock l(&ctx->thread_mtx); 607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ScopedReport rep(ReportTypeSignalUnsafe); 61158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov if (!IsFiredSuppression(ctx, rep, stack)) { 62158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov rep.AddStack(&stack); 63158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov OutputReport(ctx, rep, rep.GetReport()->stacks[0]); 64158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov } 657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 672e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukovvoid *user_alloc(ThreadState *thr, uptr pc, uptr sz, uptr align) { 687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_GT(thr->in_rtl, 0); 692e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov void *p = allocator()->Allocate(&thr->alloc_cache, sz, align); 702e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov if (p == 0) 71efd958213d70188ae6f79afd79fe2c84956d24ffDmitry Vyukov return 0; 72ad9da372f962495b3487685232d09390be841b1cDmitry Vyukov MBlock *b = new(allocator()->GetMetaData(p)) MBlock; 737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany b->size = sz; 74ad9da372f962495b3487685232d09390be841b1cDmitry Vyukov b->head = 0; 75ff35f1d82b4f145b3477ef27a7a2e7b63c486988Dmitry Vyukov b->alloc_tid = thr->unique_id; 76848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov b->alloc_stack_id = CurrentStackId(thr, pc); 777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (CTX() && CTX()->initialized) { 789bbc579e11900741551b81b5e91d22ca47d70b26Dmitry Vyukov MemoryRangeImitateWrite(thr, pc, (uptr)p, sz); 797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 80e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov DPrintf("#%d: alloc(%zu) = %p\n", thr->tid, sz, p); 817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SignalUnsafeCall(thr, pc); 827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return p; 837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid user_free(ThreadState *thr, uptr pc, void *p) { 867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_GT(thr->in_rtl, 0); 877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_NE(p, (void*)0); 887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany DPrintf("#%d: free(%p)\n", thr->tid, p); 892e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov MBlock *b = (MBlock*)allocator()->GetMetaData(p); 909bbc579e11900741551b81b5e91d22ca47d70b26Dmitry Vyukov if (b->head) { 919bbc579e11900741551b81b5e91d22ca47d70b26Dmitry Vyukov Lock l(&b->mtx); 929bbc579e11900741551b81b5e91d22ca47d70b26Dmitry Vyukov for (SyncVar *s = b->head; s;) { 939bbc579e11900741551b81b5e91d22ca47d70b26Dmitry Vyukov SyncVar *res = s; 949bbc579e11900741551b81b5e91d22ca47d70b26Dmitry Vyukov s = s->next; 959bbc579e11900741551b81b5e91d22ca47d70b26Dmitry Vyukov StatInc(thr, StatSyncDestroyed); 969bbc579e11900741551b81b5e91d22ca47d70b26Dmitry Vyukov res->mtx.Lock(); 979bbc579e11900741551b81b5e91d22ca47d70b26Dmitry Vyukov res->mtx.Unlock(); 989bbc579e11900741551b81b5e91d22ca47d70b26Dmitry Vyukov DestroyAndFree(res); 999bbc579e11900741551b81b5e91d22ca47d70b26Dmitry Vyukov } 1009bbc579e11900741551b81b5e91d22ca47d70b26Dmitry Vyukov b->head = 0; 1019bbc579e11900741551b81b5e91d22ca47d70b26Dmitry Vyukov } 1027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (CTX() && CTX()->initialized && thr->in_rtl == 1) { 1037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryRangeFreed(thr, pc, (uptr)p, b->size); 1047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 105ad9da372f962495b3487685232d09390be841b1cDmitry Vyukov b->~MBlock(); 1062e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov allocator()->Deallocate(&thr->alloc_cache, p); 1077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SignalUnsafeCall(thr, pc); 1087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 1097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid *user_realloc(ThreadState *thr, uptr pc, void *p, uptr sz) { 1117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_GT(thr->in_rtl, 0); 1127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *p2 = 0; 1137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // FIXME: Handle "shrinking" more efficiently, 1147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // it seems that some software actually does this. 1157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (sz) { 1167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany p2 = user_alloc(thr, pc, sz); 117efd958213d70188ae6f79afd79fe2c84956d24ffDmitry Vyukov if (p2 == 0) 118efd958213d70188ae6f79afd79fe2c84956d24ffDmitry Vyukov return 0; 1197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (p) { 1207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MBlock *b = user_mblock(thr, p); 1217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany internal_memcpy(p2, p, min(b->size, sz)); 1227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 1237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 1247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (p) { 1257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany user_free(thr, pc, p); 1267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 1277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return p2; 1287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 1297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1307ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyMBlock *user_mblock(ThreadState *thr, void *p) { 1317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_NE(p, (void*)0); 132491d34b7b75c42ac746ce90cda5a124bda038383Dmitry Vyukov Allocator *a = allocator(); 133f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov void *b = a->GetBlockBegin(p); 134f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov CHECK_NE(b, 0); 135f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov return (MBlock*)a->GetMetaData(b); 1367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 1377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1384f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonovvoid invoke_malloc_hook(void *ptr, uptr size) { 1394f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov Context *ctx = CTX(); 1404f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov ThreadState *thr = cur_thread(); 1414f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov if (ctx == 0 || !ctx->initialized || thr->in_rtl) 1424f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov return; 1434f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov __tsan_malloc_hook(ptr, size); 1444f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov} 1454f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov 1464f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonovvoid invoke_free_hook(void *ptr) { 1474f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov Context *ctx = CTX(); 1484f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov ThreadState *thr = cur_thread(); 1494f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov if (ctx == 0 || !ctx->initialized || thr->in_rtl) 1504f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov return; 1514f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov __tsan_free_hook(ptr); 1524f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov} 1534f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov 1547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid *internal_alloc(MBlockType typ, uptr sz) { 1557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ThreadState *thr = cur_thread(); 1567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_GT(thr->in_rtl, 0); 1579ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov if (thr->nomalloc) { 1589ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov thr->nomalloc = 0; // CHECK calls internal_malloc(). 1599ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov CHECK(0); 1609ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov } 161f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov return InternalAlloc(sz); 1627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 1637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid internal_free(void *p) { 1657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ThreadState *thr = cur_thread(); 1667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_GT(thr->in_rtl, 0); 1679ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov if (thr->nomalloc) { 1689ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov thr->nomalloc = 0; // CHECK calls internal_malloc(). 1699ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov CHECK(0); 1709ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov } 171f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov InternalFree(p); 1727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 1737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} // namespace __tsan 17512530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov 17612530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukovusing namespace __tsan; 17712530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov 17812530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukovextern "C" { 17912530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukovuptr __tsan_get_current_allocated_bytes() { 180bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov u64 stats[AllocatorStatCount]; 181bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov allocator()->GetStats(stats); 182bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov u64 m = stats[AllocatorStatMalloced]; 183bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov u64 f = stats[AllocatorStatFreed]; 184bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov return m >= f ? m - f : 1; 18512530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov} 18612530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov 18712530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukovuptr __tsan_get_heap_size() { 188bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov u64 stats[AllocatorStatCount]; 189bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov allocator()->GetStats(stats); 190bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov u64 m = stats[AllocatorStatMmapped]; 191bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov u64 f = stats[AllocatorStatUnmapped]; 192bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov return m >= f ? m - f : 1; 19312530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov} 19412530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov 19512530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukovuptr __tsan_get_free_bytes() { 1961acfa02e08e6d3316c80f52255cbb7d9e3164128Dmitry Vyukov return 1; 19712530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov} 19812530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov 19912530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukovuptr __tsan_get_unmapped_bytes() { 2001acfa02e08e6d3316c80f52255cbb7d9e3164128Dmitry Vyukov return 1; 20112530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov} 20212530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov 20312530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukovuptr __tsan_get_estimated_allocated_size(uptr size) { 20412530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov return size; 20512530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov} 20612530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov 207bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukovbool __tsan_get_ownership(void *p) { 208bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov return allocator()->GetBlockBegin(p) != 0; 20912530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov} 21012530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov 211bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukovuptr __tsan_get_allocated_size(void *p) { 212bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov if (p == 0) 213bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov return 0; 214bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov p = allocator()->GetBlockBegin(p); 215bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov if (p == 0) 216bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov return 0; 217bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov MBlock *b = (MBlock*)allocator()->GetMetaData(p); 218bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov return b->size; 21912530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov} 22012530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov} // extern "C" 221