gpt4 book ai didi

c - 访问 .rodata 部分中的特定数据时应用程序崩溃

转载 作者:太空宇宙 更新时间:2023-11-04 07:43:38 25 4
gpt4 key购买 nike

我不得不完全改写这个问题及其标题,因为我的初步分析结果是错误的(感谢所有提示和建议!)。问题的旧标题是:

GCC -O3 打乱二进制文件并产生数据垃圾

事实证明它与优化级别无关,我也不确定数据是否是垃圾。

无论如何,这些是我正在使用的 SDK 代码的相关片段。显然我不能在这里发布整个 SDK 代码。

首先我有两个常量:

static const usb_device_controller_interface_struct_t s_UsbDeviceEhciInterface = {
USB_DeviceEhciInit, USB_DeviceEhciDeinit, USB_DeviceEhciSend,
USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl};

static const usb_device_class_map_t s_UsbDeviceClassInterfaceMap[] = {
{USB_DeviceCdcAcmInit, USB_DeviceCdcAcmDeinit, USB_DeviceCdcAcmEvent, kUSB_DeviceClassTypeCdc},
{(usb_device_class_init_call_t)NULL, (usb_device_class_deinit_call_t)NULL, (usb_device_class_event_callback_t)NULL,
(usb_device_class_type_t)0},
};

在我的 main.c 中,看似无关,有这个片段:

if (kStatus_USB_Success != error)
{
usb_echo("kUSB_DeviceCdcEventSetControlLineState error!");
}

现在,如果我使用 -O3 编译,应用程序在访问 s_UsbDeviceEhciInterface 时崩溃,使用 -O0 时,应用程序在访问时崩溃s_UsbDeviceClassInterfaceMap

两次似乎都涉及第三个代码片段。

对于 -O3s_UsbDeviceEhciInterface 反汇编中的数据如下所示:

000066b4 <s_UsbDeviceEhciInterface>:
66b4: 00000479 0000145d 00001499 000014a5 y...]...........
66c4: 000014ad 00001685 4253556b 7665445f ........kUSB_Dev
66d4: 43656369 76456364 53746e65 6f437465 iceCdcEventSetCo
66e4: 6f72746e 6e694c6c 61745365 65206574 ntrolLineState e
66f4: 726f7272 00000021 rror!...

s_UsbDeviceClassInterfaceMap 似乎根本不存在。

-O0 s_UsbDeviceEhciInterface 反汇编中的数据如下所示:

00009164 <s_UsbDeviceEhciInterface>:
9164: 000018b5 00001999 00006ebb 00006eed .........n...n..
9174: 00001a21 00001c35 !...5...

对于s_UsbDeviceClassInterfaceMap:

0000917c <s_UsbDeviceClassInterfaceMap>:
917c: 00007eb1 00007f49 00002985 00000002 .~..I....)......
...
919c: 00007071 4253556b 7665445f 43656369 qp..kUSB_DeviceC
91ac: 76456364 53746e65 6f437465 6f72746e dcEventSetContro
91bc: 6e694c6c 61745365 65206574 726f7272 lLineState error
91cc: ffff0021 !...

在映射文件中,我们两次都看到 const 后面的 main.c 数据——正如反汇编所建议的那样。对于 -O3:

 .rodata.s_UsbDeviceEhciInterface
0x00000000000066b4 0x18 ./usb/device/source/usb_device_dci.o
.rodata.USB_DeviceCdcVcomCallback.str1.4
0x00000000000066cc 0x30 ./source/main.o

对于-O0:

.rodata.s_UsbDeviceEhciInterface
0x0000000000009164 0x18 ./usb/device/source/usb_device_dci.o
.rodata.s_UsbDeviceClassInterfaceMap
0x000000000000917c 0x20 ./usb/device/class/usb_device_class.o
.rodata 0x000000000000919c 0x32 ./source/main.o

回顾一下:当从 main.c 访问常量字符串之前的常量时,应用程序总是崩溃

我尝试启动编译器警告,但在 SDK 代码中只得到一些未使用的参数


为了完整起见,这里是原始问题:


已过时(见上文)

所以,我有这段代码:

static const usb_device_controller_interface_struct_t s_UsbDeviceEhciInterface = {
USB_DeviceEhciInit, USB_DeviceEhciDeinit, USB_DeviceEhciSend,
USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl};

在其他地方,在另一个文件中,看似无关,我有这个片段:

if (kStatus_USB_Success != error)
{
usb_echo("kUSB_DeviceCdcEventSetControlLineState error!");
}

现在,访问 s_UsbDeviceEhciInterface 会使应用程序崩溃。查看反汇编文件,我发现以下内容:

00006674 <s_UsbDeviceEhciInterface>:
6674: 00000479 0000145d 00001499 000014a5 y...]...........
6684: 000014ad 00001685 4253556b 7665445f ........kUSB_Dev
6694: 43656369 76456364 53746e65 6f437465 iceCdcEventSetCo
66a4: 6f72746e 6e694c6c 61745365 65206574 ntrolLineState e
66b4: 726f7272 00000021 rror!...

这似乎是两个不相关的代码部分的组合!

如果我删除第二个代码片段访问 s_UsbDeviceEhciInterface 再次工作。反汇编看起来像这样,这更有意义:

000042b4 <s_UsbDeviceEhciInterface>:
42b4: 00000479 00000b0d 00000b49 00000b55 y.......I...U...
42c4: 00000b5d 00000d35 ]...5...

只有在我使用 -O3 优化时才会发生这种情况。当我切换到 -O0 时,一切似乎又好了。

这是如何发生的,有没有办法在仍然使用 -O3 的情况下防止这种情况发生?

编辑:我刚刚意识到它也发生在 -O0 中,只是在数据的另一部分。也许我搞砸了我的链接描述文件?

最佳答案

注意:这不是对您的崩溃的解释,而是试图解释假定的数据垃圾。

您的反汇编似乎是从最终的可执行文件进行的。在这个文件中,所有常量都被收集并附加在 rodata 部分中。静态和常量结构 s_UsbDeviceEhciInterface 显然是只读数据,就像您在它后面找到的字符串文字一样。

两者的区别在于前者有一个用户定义的名称s_UsbDeviceEhciInterface,而后者没有。这就是为什么反汇编将名称显示为起始标签,而不显示字符串的原因。

您可以生成映射文件(链接器的选项 -Map)并查看多个对象及其位置。

所以,-O3不会产生数据垃圾。

由于您发现 -O0 也会导致崩溃,因此您需要从另一个方向进行调查。想想段溢出、悬空指针、未初始化的变量等等。将所有警告级别提高到最大!

关于c - 访问 .rodata 部分中的特定数据时应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58581622/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com