【发布时间】:2020-08-24 14:03:08
【问题描述】:
在使用 XCode 11.6 的 OSX 上,我将 v8 构建为静态库 (libv8_monolith.a)。在一种情况下,我将它链接到一个可执行文件并且一切都很好,在另一种情况下,我将它链接到一个 Bundle(动态库)并且模板化函数崩溃 EXC_BAD_ACCESS:
例如AllocatePage():
内存分配器.h
template <MemoryAllocator::AllocationMode alloc_mode = kRegular, typename SpaceType> EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
Page* AllocatePage(size_t size, SpaceType* owner, Executability executable);
extern template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
Page* MemoryAllocator::AllocatePage<MemoryAllocator::kRegular, PagedSpace>(size_t size, PagedSpace* owner, Executability executable);
内存分配器.cc
template <MemoryAllocator::AllocationMode alloc_mode, typename SpaceType>
Page* MemoryAllocator::AllocatePage(size_t size, SpaceType* owner, Executability executable) {
MemoryChunk* chunk = nullptr;
if (alloc_mode == kPooled) {
DCHECK_EQ(size, static_cast<size_t>(
MemoryChunkLayout::AllocatableMemoryInMemoryChunk(
owner->identity())));
DCHECK_EQ(executable, NOT_EXECUTABLE);
chunk = AllocatePagePooled(owner);
}
if (chunk == nullptr) {
chunk = AllocateChunk(size, size, executable, owner);
}
if (chunk == nullptr) return nullptr;
return owner->InitializePage(chunk);
}
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
Page* MemoryAllocator::AllocatePage<MemoryAllocator::kRegular, PagedSpace>(size_t size, PagedSpace* owner, Executability executable);
如果我改为将其编写为非模板版本,并重新编译 libv8_monolith.a,则不会崩溃:
Page* AllocatePage2(size_t size, PagedSpace* owner, Executability executable);
Page* MemoryAllocator::AllocatePage2(size_t size, PagedSpace* owner, Executability executable) {
MemoryChunk* chunk = nullptr;
if (chunk == nullptr) {
chunk = AllocateChunk(size, size, executable, owner);
}
if (chunk == nullptr) return nullptr;
return owner->InitializePage(chunk);
}
请注意,这些崩溃的模板化函数都不会暴露在外部(它们不是 v8.h API 的一部分),它们都是 v8 的“内部命名空间”内部的代码。
我缺少一些编译器或链接器标志吗?这甚至是我应该做的事情吗?我是否必须将 v8 编译为动态库才能在另一个动态库中使用它?
【问题讨论】:
-
你的
.cpp文件中有函数模板的实现吗? Why can templates only be implemented in the header file? -
你有调试器吗?你能描述一下崩溃是如何发生的以及在哪里发生的吗? (你应该有一个调用堆栈等)你所说的“暴露在外部”确切是什么意思?
ConcurrentBitmap<>在哪里定义?什么代码调用marking_bitmap?返回值做了什么? -
@Yakk-AdamNevraumont 我用一个更好的例子和崩溃的截图更新了这个问题。