Linux.ChinaUnix.net
ChinaUnix | Linux首页 | 新闻 | 博客 | 文章 | 专栏 | 新手 | 方案 | 图书 | 下载 | 人才 | 手册 | wiki | 搜索     
Linux论坛
  会员: 密码: 免费注册 | 忘记密码 | 会员登录 | 搜索 | 帮助 


奥运快报: 
奥运热点:
 

修改指针值的操作是一个原子操作?
首页 » CU论坛 » Linux » 汇总贴列表 » 内核源码 »  
[打印] [订阅] [收藏] [推荐给朋友] [本帖文本页]
zx_wing   帅哥 (骑着猪的青蛙)
大天使
学徒



UID:499746
注册:2006-12-4
最后登录: 2008-08-29
帖子:1881
精华:3

可用积分:1509 (家境小康)
信誉积分:100
空间积分:0 (白手起家)
专家积分:1 (本版)

来自:成都
状态:...保密...

[资料] [站内短信] [Blog]


顶部
11楼 发表于 2008-5-19 13:17 


QUOTE:
原帖由 iterator 于 2008-5-19 12:48 发表


那个str应该不是32位对齐的呀

对,我刚才想叉了,它没对齐到自然边界,按理是有问题的。
但我在RSIC平台上做了一个实验,在这个平台上,不对齐的访问会引发一个错误。非常意外的发现,结构体内的不对齐的指针赋值没有问题,但自己构造的未对齐指针赋值就有错。下面是程序和结果

QUOTE:
1 #include <stdio.h>
  2 #include <stdlib.h>
  3
  4 struct p
  5 {
  6     char a;
7     char *str;               //这里的指针也没对齐到自然边界
  8     char b;
  9 } __attribute__ ((packed)) x;
10
11 int main()
12 {
13     char buf[10];
14     unsigned long addr = (unsigned long)&x.str;
15     int *pp = (int *)&buf[1];                 //这是个不对齐的数据访问
16     char **str = (char **)&buf[1];        //这个是个不对齐的指针

17
18     *pp = 100;                 //出错
19     *str = "hello";            //出错

20     printf("%d,%#lx\n", sizeof(x), addr);
21     x.str = "hello";           //没问题
22     printf("%s\n", x.str);
23
24 }

下面是运行结果:

QUOTE:
[xin@vti-build tmp]$ ./t_align
t_align(18426): unaligned access to 0x60000fffffffb6a1, ip=0x4000000000000690
t_align(18426): unaligned access to 0x60000fffffffb6a1, ip=0x40000000000006b1

10,0x60000fffffffb691
hello

注意3个地址都是奇数结尾的,都没对齐到自然边界,但结构体内那个操作没出错

糊涂了,大家有什么看法,我也再想想



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________


C调 ---- C语言
都是最喜欢的
空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
zx_wing   帅哥 (骑着猪的青蛙)
大天使
学徒



UID:499746
注册:2006-12-4
最后登录: 2008-08-29
帖子:1881
精华:3

可用积分:1509 (家境小康)
信誉积分:100
空间积分:0 (白手起家)
专家积分:1 (本版)

来自:成都
状态:...保密...

[资料] [站内短信] [Blog]


顶部
12楼 发表于 2008-5-19 14:21 


QUOTE:
原帖由 zx_wing 于 2008-5-19 13:17 发表

对,我刚才想叉了,它没对齐到自然边界,按理是有问题的。
但我在RSIC平台上做了一个实验,在这个平台上,不对齐的访问会引发一个错误。非常意外的发现,结构体内的不对齐的指针赋值没有问题,但自己构造的未 ...

对这个问题我研究了一下,通过反汇编,看出了问题
实际上x.str = "hello"; 这句,编译器保证了对齐访问。
策略可以用下面伪代码表示(我的机器是64bit的):

QUOTE:
unsigned long addr = (unsigned long)"hello";
unsigned long first_write =  (addr >> 8) | (x.a << 56);
unsigned long sec_write = (addr << 8) | (x.b);

*(unsigned long *)&x = first_write;
*(unsigned long *)((void *)&x + 8) = sec_write;

可见,编译器用两次对齐到64bit边界的写操作完成了对未对齐到64bit边界的指针的赋值。
从中我们或许可以得到两个结论:
1、在对齐要求严格的平台上,编译器可以感知结构体内非对齐的访问,将它转换成对齐操作。
2、在x86平台上,未对齐到自然边界的指针赋值,应该是非原子的。

大家是对的哈,我前面的两个回复错了。

[ 本帖最后由 zx_wing 于 2008-5-19 15:11 编辑 ]



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________


C调 ---- C语言
都是最喜欢的
空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
版主 gvim   帅哥 (日尼 禾尔)
版主-精灵使
我在白宫开房,接见布什到访



UID:192271
注册:2004-10-22
最后登录: 2008-08-29
帖子:3109
精华:5

可用积分:3797 (小富即安)
信誉积分:100
空间积分:0 (白手起家)
专家积分:0 (本版)

来自:成都
状态:...离线...

[资料] [站内短信] [Blog]


顶部
13楼 发表于 2008-5-19 14:24 
>>>但我在RSIC平台上做了一个实验
与risc无关,依赖具体实现和编译器。



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

灵魂说是对的,懵懂间认为我们每个人到这世界上一走,都是上帝安排的锻炼。在尘世间历练一回,经历许多的磨难 快乐 哀伤,是为了领会灵魂的升华。一但是时候了上帝再把我们招回,所以还是安心经历这人世的一招吧。
空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
版主 gvim   帅哥 (日尼 禾尔)
版主-精灵使
我在白宫开房,接见布什到访



UID:192271
注册:2004-10-22
最后登录: 2008-08-29
帖子:3109
精华:5

可用积分:3797 (小富即安)
信誉积分:100
空间积分:0 (白手起家)
专家积分:0 (本版)

来自:成都
状态:...离线...

[资料] [站内短信] [Blog]


顶部
14楼 发表于 2008-5-19 14:27 
*str = "hello";            //出错

???



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

灵魂说是对的,懵懂间认为我们每个人到这世界上一走,都是上帝安排的锻炼。在尘世间历练一回,经历许多的磨难 快乐 哀伤,是为了领会灵魂的升华。一但是时候了上帝再把我们招回,所以还是安心经历这人世的一招吧。
空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
zx_wing   帅哥 (骑着猪的青蛙)
大天使
学徒



UID:499746
注册:2006-12-4
最后登录: 2008-08-29
帖子:1881
精华:3

可用积分:1509 (家境小康)
信誉积分:100
空间积分:0 (白手起家)
专家积分:1 (本版)

来自:成都
状态:...保密...

[资料] [站内短信] [Blog]


顶部
15楼 发表于 2008-5-19 14:35 


QUOTE:
原帖由 gvim 于 2008-5-19 14:24 发表
>>>但我在RSIC平台上做了一个实验
与risc无关,依赖具体实现和编译器。

有关系的,CISC平台,通常是x86,不会引起未对齐错误,因为是硬件自己处理
RISC平台,会产生一个未对齐的异常。通常会报告给出错的程序。
当然,我不知道是不是所有RISC平台都如此。

出错的情况我已经贴出来了。
版主如果在你的平台上发现不同,希望给出你的平台和编译器的行为
我已经解释了在IA64平台上,编译器如何处理。



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________


C调 ---- C语言
都是最喜欢的
空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
zx_wing   帅哥 (骑着猪的青蛙)
大天使
学徒



UID:499746
注册:2006-12-4
最后登录: 2008-08-29
帖子:1881
精华:3

可用积分:1509 (家境小康)
信誉积分:100
空间积分:0 (白手起家)
专家积分:1 (本版)

来自:成都
状态:...保密...

[资料] [站内短信] [Blog]


顶部
16楼 发表于 2008-5-19 14:36 


QUOTE:
原帖由 gvim 于 2008-5-19 14:27 发表
*str = "hello";            //出错

???

对,出错
t_align(18426): unaligned access to 0x60000fffffffb6a1, ip=0x4000000000000690
t_align(18426): unaligned access to 0x60000fffffffb6a1, ip=0x40000000000006b1
对应程序中的:
18     *pp = 100;                 //出错
19     *str = "hello";            //出错



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________


C调 ---- C语言
都是最喜欢的
空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
版主 gvim   帅哥 (日尼 禾尔)
版主-精灵使
我在白宫开房,接见布什到访



UID:192271
注册:2004-10-22
最后登录: 2008-08-29
帖子:3109
精华:5

可用积分:3797 (小富即安)
信誉积分:100
空间积分:0 (白手起家)
专家积分:0 (本版)

来自:成都
状态:...离线...

[资料] [站内短信] [Blog]


顶部
17楼 发表于 2008-5-19 15:44 
>>>RISC平台,会产生一个未对齐的异常。通常会报告给出错的程序。
arm926ej-s
并不是所有的RISC都会抱你说的“未对齐”错误。


>>>*str = "hello";
你可以把它注释掉看看有没有错误。*str引向一个unknown的东西,复值过去当然会错。

[ 本帖最后由 gvim 于 2008-5-19 15:45 编辑 ]



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

灵魂说是对的,懵懂间认为我们每个人到这世界上一走,都是上帝安排的锻炼。在尘世间历练一回,经历许多的磨难 快乐 哀伤,是为了领会灵魂的升华。一但是时候了上帝再把我们招回,所以还是安心经历这人世的一招吧。
空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
zx_wing   帅哥 (骑着猪的青蛙)
大天使
学徒



UID:499746
注册:2006-12-4
最后登录: 2008-08-29
帖子:1881
精华:3

可用积分:1509 (家境小康)
信誉积分:100
空间积分:0 (白手起家)
专家积分:1 (本版)

来自:成都
状态:...保密...

[资料] [站内短信] [Blog]


顶部
18楼 发表于 2008-5-19 16:37 


QUOTE:
原帖由 gvim 于 2008-5-19 15:44 发表
>>>RISC平台,会产生一个未对齐的异常。通常会报告给出错的程序。
arm926ej-s
并不是所有的RISC都会抱你说的“未对齐”错误。


>>>*str = "hello";
你可以把它注释掉看看有没有错误。*str引向一个unkno ...

好的,看来不是所有RISC平台都要求严格对齐的。
注释掉当然没有错误。
*str指向的是buf[1]开始的8个字节内存区域。
给它赋值也就是写buf[1]开始的8个字节,该区域存在于栈上,我们写它完全是合法应用。
不是版主说的unkonw的区域哈,如果是那样,系统会产生segfault,而非未对齐错误。

**str="hello"才是版主说的引用unkonwn区域,而引起segfault。

[ 本帖最后由 zx_wing 于 2008-5-19 16:49 编辑 ]



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________


C调 ---- C语言
都是最喜欢的
空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
zx_wing   帅哥 (骑着猪的青蛙)
大天使
学徒



UID:499746
注册:2006-12-4
最后登录: 2008-08-29
帖子:1881
精华:3

可用积分:1509 (家境小康)
信誉积分:100
空间积分:0 (白手起家)
专家积分:1 (本版)

来自:成都
状态:...保密...

[资料] [站内短信] [Blog]


顶部
19楼 发表于 2008-5-19 16:42 


QUOTE:
原帖由 gvim 于 2008-5-19 15:44 发表
>>>RISC平台,会产生一个未对齐的异常。通常会报告给出错的程序。
arm926ej-s
并不是所有的RISC都会抱你说的“未对齐”错误。


>>>*str = "hello";
你可以把它注释掉看看有没有错误。*str引向一个unkno ...

好奇
arm926ej-s平台如何解决未对齐?
我听说arm也是要严格对齐的啊



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________


C调 ---- C语言
都是最喜欢的
空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
版主 gvim   帅哥 (日尼 禾尔)
版主-精灵使
我在白宫开房,接见布什到访



UID:192271
注册:2004-10-22
最后登录: 2008-08-29
帖子:3109
精华:5

可用积分:3797 (小富即安)
信誉积分:100
空间积分:0 (白手起家)
专家积分:0 (本版)

来自:成都
状态:...离线...

[资料] [站内短信] [Blog]


顶部
20楼 发表于 2008-5-19 17:03 
>>>*str指向的是buf[1]开始的8个字节内存区域。
呵呵,不好意思,是我自己没有初始化-_-;

>>>arm926ej-s平台如何解决未对齐?
也是靠编译器。



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

灵魂说是对的,懵懂间认为我们每个人到这世界上一走,都是上帝安排的锻炼。在尘世间历练一回,经历许多的磨难 快乐 哀伤,是为了领会灵魂的升华。一但是时候了上帝再把我们招回,所以还是安心经历这人世的一招吧。
空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘

首页 » CU论坛 » Linux » 汇总贴列表 » 内核源码 »

 


Copyright © 2001-2008 ChinaUnix.net All Rights Reserved     联系我们:

感谢所有关心和支持过ChinaUnix的朋友们    转载本站内容请注明原作者名及出处

京ICP证041476号


清除 Cookies - Linux时代 - Archiver - WAP - TOP

Processed in 0.092288 second(s), 5 queries , Gzip enabled