gpt4 book ai didi

c - 将未对齐的数据复制到新位置后未发生 Solaris 总线错误

转载 作者:太空宇宙 更新时间:2023-11-04 03:37:08 24 4
gpt4 key购买 nike

所以,长话短说:我的程序接收到一个代表网络数据包的原始字节 (u_char) 缓冲区。我正在尝试解析该数据包中的信息,并使用系统定义的 header 结构(ether_header、ip、ip6、tcphdr、udphdr)进行解析。我已经在 Linux 和 AIX 上实现了它并且它有效,但由于某种原因,当我在 Solaris 上执行此操作时,我不断收到总线错误。

我获取数据的方式基本上只是将缓冲区的每个部分转换为结构之一并读取数据。例如,如果我有

u_char buffer[] = {...some bytes...};
struct ether_header *ethdr = (struct ether_header *)buffer;
struct ip *iphdr = (struct ip *) (buffer + sizeof(struct ether_header));
etc. etc.

然后我可以获得我需要的信息,例如:

iphdr->ip_v; //to get the version
etc->etc; //to get whatever piece of data I need

通常,在 Linux 和 AIX 上这工作正常(某些结构在系统中有不同的名称,但这不是重点),但是在 Solaris 上尝试运行它时,当它到达 时我不断收到总线错误iphdr->ip_v;struct ip *iphdr = (struct ip *) (buffer + sizeof(struct ether_header)); 之后。经过一番调查,我发现这是由于试图访问未对齐的内存引起的。这是有道理的,因为以太网 header 的大小只有 14 个字节,因此 IP header 在数组中不是字节对齐的。

我尝试解决这个问题的方法是在尝试阅读之前将相关部分复制到一个单独的缓冲区中

memcpy(&buffer_copy, buffer + sizeof(struct ether_header), sizeof(struct ip));
struct ip *iphdr = &buffer_copy;
iphdr->ip_v;
etc.

这行得通,但我不明白为什么。为什么 memcpy 在尝试访问相同的内存位置时不抛出总线错误?我不太喜欢我想出的解决方案,我正在努力更好地了解情况,以便我能想出别的办法。我是不是漏掉了一 block 拼图?

最佳答案

在 SPARC 硬件上,您有两个选择:

  1. 不要编写以导致总线错误的方式访问内存的代码。
  2. Solaris Studio compilers编译并使用 -xmemalign=1i命令行选项。这将导致二进制文件运行速度比二进制文件慢假定内存访问正确对齐。

另见 this question .

关于c - 将未对齐的数据复制到新位置后未发生 Solaris 总线错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31752662/

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