【发布时间】:2018-12-11 20:44:44
【问题描述】:
我们使用 r12b ndk 和 gcc 来构建我们的 c++ 库(使用预构建库并手动指定标志)和我们的依赖项(boost 1.66、openssl...等带有独立工具链)。当我们切换到 clang(在 r18b 和 r12b 中)时,它开始仅在 Nexus 4 上出现 signal 7 (SIGBUS), code 1 (BUS_ADRALN) 崩溃。我在 Nexus 5X 和 LG G6(在 armv7 模式下)上尝试过,它们都没有崩溃。
ndk-stack 说崩溃发生在
Routine aligned at /boost/atomic/detail/storage_type.hpp:91 但来自 Undefined Behavior Sanitizer 的消息表明它在调用 boost 函数之前已经获得了未对齐的地址指针。
runtime error: constructor call on misaligned address 0x9b2a5008 for type 'class1', which requires 16 byte alignment
0x9b2a5008: note: pointer points here
添加 -Wover-aligned 后会弹出这样的消息。
error: type 'test1' requires 16 bytes of alignment and the default allocator only guarantees 8 bytes [-Werror,-Wover-aligned]
和-fnew-alignment=16 -falign-functions -faligned-new -faligned-allocation 标志有助于使警告消失。但它仍然有同样的 sigbus 崩溃。
我想不通。任何猜测,建议都会有所帮助。谢谢。
编辑: 我们为 ndk 使用 api level 21。
【问题讨论】:
-
你能显示一些代码吗?
-
-fnew-alignment是否真的改变了任何东西,或者它只是对编译器的建议?如果是后者,您所做的只是抑制警告而不实际修复它。听起来可能分配了错误的类型,然后转换为正确的类型并在其上调用放置 new?如果是这样的话,那是未定义的行为。几年前,当我们将 AOSP 迁移到 Clang 时,我们点击的每个SIGBUS都是未定义的行为,几乎总是这种形式。 -
@KimKulling Rn 不能。我们正在开发最小的可重现项目。
-
@DanAlbert 在 clang 手册中它说
Specifies the largest alignment guaranteed by ‘::operator new(size_t)’所以我认为它实际上是在做某事。我无法理解的是它只是 nexus 4 (api 22) 中的 sigbus,而不是 nexus 5X (api 23)。他们都使用 krait arm 32bit CPU。 -
是的,错误的类型转换将是我们研究的一个好方向。我确实希望它是编译器级别的东西,因为 gcc 可以工作。
标签: c++ android-ndk clang