C++:__aligned(__alignof__) 导致字符数组数据出现问题?
C++: __aligned(__alignof__) causing problems with char array data?
Tl;dr:我的代码正在访问的字符数组以前指向预期的字符串值,现在在字符串之前有意外的字符。我目前的理论是,这在某种程度上是由字符数组对齐方式的变化引起的,我试图弄清楚我是否正确以及如何修复它。
我正在尝试维护一个用C++编写的 Linux 内核模块。我已经很久没有在C++工作了,所以我有点停留在我目前看到的东西上。
我们在内核 modue 之外有一个单独的实用程序,它讲述了内核密钥环中的密钥。稍后,内核模块会查找该值并将其与预期的键值进行比较。下面是查找方法:
#include <linux/key.h>
#include <keys/user-type.h>
int read_key(char *key_desc, char *expected_key) {
struct key *key;
struct user_key_payload *key_payload;
key = request_key(&key_type_user, key_desc, NULL);
key_payload = rcu_dereference(key->payload.data[0]);
return strncmp(key_payload->data, expected_key, key_payload->datalen));
}
此代码目前适用于我们支持的大多数内核版本。但是最近在一个特定的操作系统中进行了内核升级,现在我的strncmp调用无法找到匹配项。似乎数据以某种方式偏移。就像如果 key_payload->datalen = 16,expected_key = "1234567890123456",那么 key_payload->data = "abcdef1234567890123456"。由于我正在比较前 16 个字符显然不匹配,但如果我从 key_payload->data[6] 开始,则会匹配。到目前为止,key_payload->datalen 仍然是正确的预期字符串长度。它只是在新内核版本上更改的key_payload>数据。
我已经查看了新内核中的一些补丁,我认为可能与问题有关。我发现的一个明显区别是这个。在修补之前,user_key_payload对象如下所示:
struct user_key_payload {
struct rcu_head rcu; /* RCU destructor */
unsigned short datalen; /* length of this data */
char data[0]; /* actual data */
};
但在它看起来像之后:
struct user_key_payload {
struct rcu_head rcu; /* RCU destructor */
unsigned short datalen; /* length of this data */
char data[0] __aligned(__alignof__(u64)); /* actual data */
};
我不知道这是否是真正导致我的问题的原因,但这似乎是一个开始寻找的明显地方。我以前从未使用过对齐或对齐的关键字。我读过一些关于对齐的文章,但它的级别比我多年来一直在工作要低得多。有谁知道是否有办法对齐 user_key_payload.data 可能会弄乱关键数据的预期内存地址,以及如何确定我的预期数据实际在哪里?
char data[0]
表示紧随结构之后的指针。它在内核中广泛用于指示标头之后的可变长度有效负载。
__aligned(__alignof__(u64))
将数据与 8 字节(64 位(边界对齐。这意味着,例如,如果在struct user_key_payload
中存储所有字段所需的大小为 10 个字节,则结构将被填充以占用 16 个字节 (2*8(。
因此,如果内核威胁数据 8 字节对齐,但您的模块 - 没有,那么"abcdef"就是您正在读取的填充。
编译模块时,请始终确保包含用于编译内核的相同版本的头文件。
- C++将文本文件中的数据读取到结构数组中
- 通过JNI传递数据数组的最快方法是什么
- C++数据文件、数组和计算赋值
- 使用指针访问数组中的对象数据成员
- C++ 使用存储在动态数组中的文本文件中的数据查找模式
- C++:__aligned(__alignof__) 导致字符数组数据出现问题?
- 很好的语法来获取对向量/数组数据的大小引用?
- 创建异构顶点数据数组的可移植方法
- 模板 使用数据数组调用函数时扩展参数包
- 如何在 c++ 和 java 之间通过 udp 有效地发送数据数组
- 如何使用模板函数从缓冲区(T* 数据数组)创建 cv::Mat
- 如何连接 2D 数据数组
- 如何使用GStreamer播放PCM数据数组
- P/Invoke使用C#和C++之间的双编组数据数组
- 如何在文件中保存/读取数据数组 (C++)
- Android & JNI 如何将 Byte[] 数据数组传递给 JNI 并取回 Byte []
- C++ 通过多次重复向量来构建数据数组
- 尝试使用pthreads访问共享数据数组时,出现“无法访问内存地址”错误
- Qt存储和访问大数据数组
- 在c++中初始化一些数据数组