- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在最终编译一个跨平台项目后,我在 OSX 上遇到了最奇怪的错误。该程序以不同的方式崩溃(但有时可能会幸存下来以显示它的用户界面)。通过 XCode 调试器,我看到多个地方的子对象的值更改 取决于上下文。这确实是我遇到的问题:
class third
{
public:
int some_data;
void do_something()
{
}
};
class second
{
public:
third * thirdPtr;
second()
: thirdPtr(nullptr)
{
thirdPtr = new third();
printf("second = 0x%X, third = 0x%X", this, thirdPtr);
}
};
class first
{
second * secondInstance;
first()
: secondInstance(nullptr)
{
secondInstance = new second();
printf("second = 0x%X, third = 0x%X", secondInstance, secondInstance->thirdPtr);
// (maybe) crash
secondInstance->thirdPtr->do_something();
}
};
单步执行时,我向第三个指针添加了一个观察点。这是一个示例输出:
Watchpoint 1 hit:
old value: 0x00000001
new value: 0x00000000
Watchpoint 1 hit:
old value: 0x00000000
new value: 0x04821c34
这是程序的标准输出:
second = 0x4821C20, third = 0x4821C34
second = 0x4821C20, third = 0x3404821C
我从来没有见过这样的东西。显然这些结构更复杂并且使用继承,但在初始化时没有其他东西可以访问或写入这些结构。我的源代码中有很多奇怪的故障和问题,所以我认为这个故障是多个地方的问题。请注意,源代码在其他平台上已经完美运行了很长时间,甚至在外部库代码中也会出错(我在该项目中使用 JUCE)。
起初我怀疑 operator new 是假的,但它似乎与对象的组合有关。有趣的是,这两个不同的三分之一似乎有很强的相似性。
我在这里真的不知所措,我已经准备好得出结论,llvm 重新安排了编译单元之间的结构布局(当然,类/结构在单独的文件中).. 之类的。我想我错了 - 但有没有人经历过这样的事情?
我添加了以下代码。(在第二个构造函数中):
{
thirdPtr = new third();
printf("second = 0x%X, third = 0x%X", this, thirdPtr);
printf("position = %d", offsetof(second, thirdPtr);
}
(在第一个构造函数中):
{
secondInstance = new second();
printf("second = 0x%X, third = 0x%X", secondInstance, secondInstance->thirdPtr);
printf("position = %d", offsetof(second, thirdptr));
}
它打印:
13
16
注意:这是完整结构的输出(即不是此处给出的示例)。
但是:结构的布局实际上是不同的,具体取决于我所在的编译/翻译单元。这到底是怎么回事?
所以我决定也检查对齐,这可能是关键问题:
来自第二个构造函数内部的标准输出:
second = 0x3649090, third = 0x36490A4
offset of third in second = 16
sizeof second = 232
align of third = 4, align of second = 4
来自第一个构造函数内部的标准输出:
second = 0x3649090, third = 0xA4036490
offset of second in third = 13
sizeof second = 226
align of third 1, align of second 1
所以翻译单元的对齐方式似乎发生了变化。我可以做些什么来在整个项目中实现标准?
我设法让它“运行”,因为它不会立即崩溃,方法是将 attribute((packed)) 应用于第二个类。但这真的不会让我感到安全,为什么我必须这样做?是否有在翻译单元中操纵此设置的全局设置?
最佳答案
很明显,在使用用户定义的结构打包对齐方式时,重置打包堆栈是多么重要。
visual studio 编译器和 clang 的 llvm 前端都使用 #pragma 指令支持相同的语法,可以在这里研究:
http://msdn.microsoft.com/en-us/library/2e70t5y1.aspx
在我的例子中,包含的 header 有一个不匹配的#pragma pack 指令,如下所示:
#ifdef __MSVC__
#pragma pack(push, 1)
#else
#pragma pack (push, 1)
#endif
....
#if defined(__MSVC__)
#pragma pack(pop)
#endif
打包堆栈会被任何编译器更改,但只有在使用 msvc++ 编译器时才会恢复。这使得包含此文件的翻译单元的打包对齐与不包含此文件的翻译单元不同,即使两个翻译单元看到完全相同的结构定义。为了完整起见,这里是(在我的例子中)更正的#pragma 指令:
#if defined(__MSVC__) || defined (__LLVM__)
#pragma pack (push, 1)
#endif
#if defined(__MSVC__) || defined (__LLVM__)
#pragma pack(pop)
#endif
关于c++ - OSX + llvm/libc++ 上的内存损坏/结构重新排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22509596/
我看到这两个项目非常相关,但它们之间有什么区别?官方网页并没有说明太多。 我知道ABI(Application Binary Interface)用于在不同平台之间提供低级二进制接口(interfac
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 6年前关闭。 Improve thi
现代 glibc 二进制文件在 Linux 中称为 libc.so.6。为什么这里用“6”? libc.so.1 或 libc.so.8 也可以是好名字恕我直言。 维基百科在 http://en.wi
我在我的 Linux Mint 14 Nadia 中安装了 Matlab(a uname -a 显示:Linux Ideapad-Z570 3.5.0-17-generic#28-Ubuntu SMP
我有一个使用 eventfd 和 timerfd 内核系统调用的应用程序。为此,您需要一个现代内核和一个支持它们的 libc,至少是 2.8。 我目前的情况是,我的系统具有正确的内核,但是 2.7.1
我有一个用 musl libc 编译的共享库 $ readelf -d ./libinterop_d.so Dynamic section at offset 0x8ecb0 contains 22
我的问题是,是否总是需要 libc.a,即使我希望链接到 libc.so。我搜索了互联网,它给出了 3 个可能的答案(冲突) 1. c program will require to link to
我安装了多个版本的 libc,我如何在编译时选择要链接的对象? 现在我正在编译 g++ prog.cpp 最佳答案 您的程序将链接到 libc。当您在 gdb 中运行时,libc-dbg 将用于读取符
我在 Ubuntu 16.04 64 位上使用 gcc 5.4.0。当我编译程序时: gcc -o prog prog.c GCC 会自动链接到 C 标准库,因此我不必专门这样做。 我如何查看 gcc
我正在为我的系统安全类编写返回 libc 攻击。一、漏洞代码: //vuln.c #include #include int loadconfig(void){ char buf[1024];
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a software
我正在尝试查找信息,但我没有在 clang 网站上看到它。我想尝试在 Windows 上使用它,但我不知道它是有自己的 libc 还是使用 MS 损坏的 libc? 另一个问题:如果我用 clang
我正在使用 clang 的规定通过插件和 clang 的 LibTooling 开发插件和工具。我能够做以下事情: 从 svn(Linux 和 OSX),通过运行配置脚本(不使用 cmake)按照入门
尝试运行时出现以下错误。 lib/libc.so.6:找不到(test.so)所需的版本“GLIBC_2.7” 要解决这个问题,在编译时静态链接到 libc-2.11.a 是否安全,这样在运行时就不会
首先,我在谷歌上搜索了很多,但没有找到与我的案例相关的任何东西,我有一个ELF可执行文件,我试图在我的Ubuntu WSL中运行它,我已经更改了权限(chmod+x文件),当我运行它时,显示以下错误。
GNU page说: Your program can arrange to run its own cleanup functions if normal termination happens.
我正在尝试在我的路由器上交叉编译 MIPSEL。我在汇编中找到了一些东西,但现在我开始尝试编译基本的 C 代码。 目前只有简单的 hello world c 代码,并使用 mipsel-linux-g
libc 中预期的字符编码是什么?例如,gethostname(char name, size_t namelen);以 char 作为参数。名称参数是否应该以 utf8(保持 ascii 完整)或纯
题 如果我包括 time.h ,更改“源类型参数”并重新包含该 header ,难道不应该添加这些新定义吗?我知道这是由于包括 guard 而发生的。我的问题是:这是 libc 中的错误吗?难道它不能
我正在学习Ubuntu上的动态链接器。我想导入我需要的libc函数,但是它链接了while libc.so文件。我不知道该怎么做,所以我来这里寻求帮助。 最佳答案 如果您将程序链接到动态库(例如 li
我是一名优秀的程序员,十分优秀!