- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
原始问题分布在来自不同项目的数十万个 LoC 中。它包含很多成分:内联汇编、虚拟继承、间接级别、不同的编译器和编译器选项。 (这就像一部惊悚片。)我很难简化到这个 SSCCE:
// a.hpp
struct A {
int i;
~A() { asm("" : "=r"(i)); }
};
struct B : public virtual A { };
struct C : public B { };
struct D {
D(C);
};
// a.cpp
#include "a.hpp"
void f(C) {
}
D::D(C c) {
f(c);
}
// main.cpp
#include "a.hpp"
int main() {
C c;
D d(c);
}
使用这些命令行构建:
g++ -O3 -fPIC -c a.cpp
clang++ -O3 -fPIC -c main.cpp
clang++ -fuse-ld=gold main.o a.o -o main
链接器的输出是:
a.o:a.cpp:function D::D(C) [clone .cold]: error: relocation refers to global symbol "construction vtable for B-in-C", which is defined in a discarded section
section group signature: "_ZTV1C"
prevailing definition is from main.o
clang-10: error: linker command failed with exit code 1 (use -v to see invocation)
我相信 gcc、clang 或 gold 中存在错误。 我的问题是它在哪里?(我猜它是金子,但我想在报告错误之前确定一下。)
FWIW:正如我所说,所有成分都很重要,如果例如删除 asm
,问题就会消失。使问题消失的更显着的变化是:
-fuse-ld=gold
)main.cpp
,不带-O3
。-fPIC
编译main.cpp
。a.o
和 main.o
。最佳答案
这似乎是 GCC 中的一个错误,但是内联汇编在 ABI 之外,可以简单地使这成为 GCC 和 Clang 之间不幸的不兼容。
问题是内联汇编让 GCC 认为 ~A::A()
可以引发异常,因此它在 D::D()
中创建异常处理路径,这需要一个用于 B-in-C 的构造 vtable,它放置在还包含 C 的 vtable (_ZV1C
) 的 COMDAT 组。
因为 Clang 不会在 _ZV1C
COMDAT 组中生成构造 vtable,而 GCC 会生成,所以您最终会遇到这样一种情况,即链接器可能会保留 Clang 生成的 COMDAT 组,并丢弃 GCC - 具有构造 vtable 的生成版本。如果您链接到 GCC 生成的需要额外符号定义的代码,则会收到此错误。
在你的链接中反转 main.o 和 a.o 也可以解决这个问题,因为所有三个链接器都会让 COMDAT 组远离 a.o,这是第一个看到的。
这是 GCC 从 a.o 为 D::D() 生成的代码:
0000000000000002 <_ZN1DC1E1C>:
2: 48 83 ec 18 sub $0x18,%rsp
6: 48 8b 06 mov (%rsi),%rax
9: 48 8b 40 e8 mov -0x18(%rax),%rax
d: 8b 04 06 mov (%rsi,%rax,1),%eax
10: 89 44 24 08 mov %eax,0x8(%rsp)
14: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax
17: R_X86_64_REX_GOTPCRELX _ZTV1C-0x4
1b: 48 8d 40 18 lea 0x18(%rax),%rax
1f: 48 89 04 24 mov %rax,(%rsp)
23: 48 89 e7 mov %rsp,%rdi
26: e8 00 00 00 00 callq 2b <_ZN1DC1E1C+0x29>
27: R_X86_64_PLT32 _Z1f1C-0x4
2b: eb 17 jmp 44 <_ZN1DC1E1C+0x42>
2d: 48 89 c7 mov %rax,%rdi
30: 48 8d 05 00 00 00 00 lea 0x0(%rip),%rax
33: R_X86_64_PC32 _ZTC1C0_1B+0x14
37: 48 89 04 24 mov %rax,(%rsp)
3b: 89 44 24 08 mov %eax,0x8(%rsp)
3f: e8 00 00 00 00 callq 44
40: R_X86_64_PLT32 _Unwind_Resume-0x4
44: 48 83 c4 18 add $0x18,%rsp
48: c3 retq
从偏移量 0x2d 到 0x3f 处的 callq
的代码是异常的处理路径,在f(c)
调用过程中发生异常时生成。 0x30 处的 lea
指令引用了 B-in-C 的构造 vtable 中的一个条目 (_ZTC1C0_1B
)。
如果没有内联汇编,GCC 会生成与 clang 相同的代码,没有异常处理路径,也不需要构建 vtable。
用--no-exceptions
编译,问题也消失了。
无论是在 -O0
、-O1
、-O2
还是 -O3 编译 a.cpp,我都看到了同样的问题
。
至少GCC在编译a.cpp和main.cpp的时候是一致的,所以可以有人认为这种情况根本不包括在 C++ ABI 和 GCC 中Clang 可以自由地以不同的方式对待它。我做了一些微不足道的尝试用内联 asm 以外的东西重现,但不能。
至于为什么您从 gold 中收到错误,而不是从 bfd 或 lld 中收到错误,黄金报告可能是一个真正的错误,尽管在这个特殊情况,因为永远不会抛出异常,异常处理代码永远不会执行。但是当你链接bfd ld 或 lld,0x30 处的 lea
指令未重定位,没有警告,程序可能会崩溃调用 f()
时抛出异常。
关于c++ - 链接错误 : construction vtable defined in a discarded section,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64118757/
这个问题在这里已经有了答案: Multi level categories with items on all levels in UITableView (1 个回答) 关闭 6 年前。 标题说明
我想在编译时从代码中删除未使用的函数。然后我写一些代码(main.c): #include const char *get1(); int main() { puts( get1() );
升级到 Xcode 4.4 后,当我尝试在 iPhone 或 iPad 上运行我的(通用)应用程序时,我遇到了这个烦人的链接器错误。如果我在 iOS 模拟器上运行它,我没有问题... 我尝试添加 ar
我以前从未见过这个错误,我搜索了它可能发生的原因,但找不到任何相关信息: CoreData: error: Serious application error. An exception was ca
我正在使用以下内容填充 UITableView 部分的各个部分: fetchedResultsController = NSFetchedResultsController(fetchReques
是标签允许包含在另一个 中标签?它会在 HTML5 中验证吗? 最佳答案 Yes ! w3 鼓励您在分节内容的元素中显式包装节,而不是依赖于在分节内容的一个元素中包含多个标题而生成的隐式节,并且允许
我使用部分来确定页面的不同部分。这些部分的底部边距为 90px,但是当在页面中创建/放置 ID 为“clients-full”的部分时,我希望出现在它之前/上方的任何部分的底部边距为 0。我可以做吗这
我现在有一个第三方提供的c静态库(用arm-gcc编译的)。我不可能(让第三方)重新编译库。 在调查库内容时,我发现 gcc 选项 -ffunction-sections 和 -fdata-secti
大家好,我陷入了一个奇怪的问题,我正在重新加载 tableViewSection,它正在正确地重新加载该部分,但它隐藏了其他部分,直到我向上或向下滚动它。我使用以下代码重新加载 func tabl
在我的项目中,我有扩展 ArrayAdapter 的类并实现 SectionIndexer .实现方法时getPositionForSection和 getSectionForPosition我发现了
我正在尝试编译 scss,以便在它具有 class1 时获得该部分。我不知道如何去做,因为我得到了空间,而且它的工作方式不一样。 当前输出: .class2 > section .class1 {
我正在阅读 Mark Pilgirm 的“Dive into HTML5”和 semantics section ,它讨论了 HTML5 如何引入 和 元素。它说 s 代表通用文档或部分,而 s
我是使用ARM编译器进行Keil Microvision V5.12编程的新手。 我无法编译一个简单的组装项目,但出现此错误: .\Objects\learn.sct(7): error: L6236
这是我第一次在这里问问题,但我不得不说这个网站在过去几个月里给了我巨大的帮助(iphone-dev-wise),我为此表示感谢。 但是,我没有找到解决这个问题的方法:我有一个包含 2 个部分的 UIT
我在 IOS 中实现了一个 TableView (4 个部分)。问题是我刚刚在第一部分添加了一个部分标题。其他部分没有标题。第一部分没有行(行数为 0)。其他部分有多行。当我滚动时,第一部分的标题不粘
我有一个包含多个部分的表格 View 。我希望能够将行从一个部分移动到另一个部分,并在没有行时删除一个部分。我正在尝试通过 moveRowAtIndexPath 执行此操作,但我的代码不起作用并抛出
我正在尝试删除不符合 for 循环条件的行。但是,我收到错误消息:“尝试从第 1 部分删除第 0 行,但更新前只有 1 个部分。”我以前从未见过这个,也不确定为什么会收到它。 我的代码: func
GCC 页面中针对功能部分和数据部分选项的以下内容: -ffunction-sections -fdata-sections Place each function or data item into
我想在安装新数据库之前删除旧数据库,以便为用户更新它。 我有以下情况: 在我的 Components 部分中,我为用户提供了一个选项: [Components] Name: "updateDataba
我从工作区添加了一个测试用例。可能已经一周了,所以我不记得它是来自 Backlog 还是来自董事会。 现在,当我进入测试/测试计划时,它没有出现。我找不到将其添加到测试套件的方法。 我可以通过测试区域
我是一名优秀的程序员,十分优秀!