【问题标题】:Why are templated functions in a static library crashing when linked to a dynamic library?为什么静态库中的模板函数在链接到动态库时会崩溃?
【发布时间】: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&lt;&gt; 在哪里定义?什么代码调用marking_bitmap?返回值做了什么?
  • @Yakk-AdamNevraumont 我用一个更好的例子和崩溃的截图更新了这个问题。

标签: c++ xcode


【解决方案1】:

原来 After Effects 内部有自己的 v8 动态库,所以当 After Effects 加载我们的动态库时,一些函数之间存在名称冲突。我现在的解决方案是使用更改的命名空间重新编译 v8 以避免冲突。

【讨论】:

    猜你喜欢
    • 2014-05-05
    • 2011-03-05
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    相关资源
    最近更新 更多