[英]C blocks extension (libBlocksRuntime) - use custom memory allocator (Boehm GC) for Block_copy()
我正在编写一个 C 程序,它使用 Apple 的 Blocks 扩展来提供词法闭包。 我也在使用 Boehm 垃圾收集器。 我想要的是 Block_copy() 在堆上分配块时使用 GC_MALLOC ,以便它们被垃圾收集。
#include <stdio.h>
#include <Block.h>
#include <GC.h>
int main()
{
int i = 42;
void(^test)(void) = Block_copy(^{printf("Hello %d\n", i);});
test();
}
我使用-DREDIRECT_MALLOC=GC_MALLOC -DREDIRECT_REALLOC=GC_REALLOC -DIGNORE_FREE
从源代码编译 libBlocksRuntime ( https://github.com/mackle/blocksruntime ) 以便让 Boehm 覆盖 malloc() 和 realloc() 调用。
然后我用-fblocks -lBlocksRuntime -l:libgc.so -fsanitize=address
编译了上面的 c 程序,但它表明内存泄漏,因此 Block_copy() 未使用 Boehm 的分配器。
Hello 42
==5885==WARNING: invalid path to external symbolizer!
==5885==WARNING: Failed to use and restart external symbolizer!
=================================================================
==5885==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 36 byte(s) in 1 object(s) allocated from:
#0 0x4961ed (/home/finn/test+0x4961ed)
#1 0x7ff40c7e0c04 (/lib/x86_64-linux-gnu/libBlocksRuntime.so.0+0xc04)
#2 0x7ff40c436cc9 (/lib/x86_64-linux-gnu/libc.so.6+0x26cc9)
SUMMARY: AddressSanitizer: 36 byte(s) leaked in 1 allocation(s).
如何强制 libBlocksRuntime 使用 Boehm 的内存分配器?
编辑:我试图通过使用 malloc 钩子,然后使用 LD_PRELOAD 来解决这个问题,但这些似乎都没有与 libBlocksRuntime(或一般的块)合作。
好的,我终于解决了。 可能有更好的方法来做到这一点,但我能找到的唯一文档是源代码。 首先,您需要#include
Block_private.h
标头以及Block.h
。 这允许访问_Block_use_GC()
函数。 Debian 存储库中的 libBlocksRuntime 版本不适合于此,因为_Block_use_GC()
未编译到其libBlocksRuntime.so
。 然后你需要定义这 5 个函数:
BLOCK_EXPORT void* blk_alloc(const unsigned long size, __attribute__((unused)) const _Bool _, __attribute__((unused)) const _Bool __) { return GC_MALLOC(size); }
BLOCK_EXPORT void blk_setHasRefcount(__attribute__((unused)) const void* _, __attribute__((unused)) const _Bool __) {}
BLOCK_EXPORT void blk_gc_assign_strong(void* src, void** dst) { *dst = src; }
BLOCK_EXPORT void blk_gc_assign_weak(const void* src, void* dst) { *(void**)dst = (void*)src; }
BLOCK_EXPORT void blk_gc_memmove(void* dst, void* src, unsigned long size) { memmove(dst, src, size); }
这些是 libBlocksRuntime 将用于访问垃圾收集器的函数。 在这种情况下,重要的是blk_alloc()
, GC_MALLOC()
调用GC_MALLOC()
。 然而,其他垃圾收集器可能会使用其他功能,您可能可以利用它们来获得更好的性能。 现在我们必须告诉 libBlocksRuntime 像这样使用这些函数:
_Block_use_GC(blk_alloc, blk_setHasRefcount, blk_gc_assign_strong, blk_gc_assign_weak, blk_gc_memmove);
这会通知 libBlocksRuntime 我们正在使用垃圾收集器,这就是如何与之交互。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.