0x10814
0x10818
0x1081c
0x10820
0x10824
0x10828
0x1082c
0x10830
0x10834
0x10838
0x1083c
0x10840
0x10844
0x10848
0x1084c
0x10850
0x10854
0x10858
0x1085c
0x10860
End of assembler dump.
(gdb) i r pc
pc 0x1084c 67660
(gdb) i r o0
o0 0xffbefbdd -4260899
(gdb) x/3bx 0xffbefbdd
0xffbefbdd: 0x34 0x56 0x78
(gdb)
从C语言来说,执行"*q = 0x0000;"时导致SIGBUS了。从汇编指令来说,执行"clrh [%o0]"
时导致SIGBUS了,寄存器%o0值为0xffbefbdd,这个地址未对齐在双字节边界上。
注意,gcc编译时并未指定-O
的汇编指令有ldw、lduh等等。有人可能碰上读操作也导致SIGBUS,觉得不可理解,
其实读写导致SIGBUS没有本质区别,比如ldw只能读4字节边界上的地址。
bus.c是显式的未对齐。程序员实际最容易面对的是隐式未对齐,主要来自指针的强
制类型转换。下面举例说明这种情形。
--------------------------------------------------------------------------
/*
* Test: SPARC/Solaris 8 64-bit kernel mode
* gcc -Wall -pipe -g -o other_bus other_bus.c
*/
#include
#include
int main ( int argc, char * argv[] )
{
unsigned int i = 0x12345678;
unsigned short int j = 0x0000;
j = *( ( unsigned short int * )( ( ( unsigned char * )&i ) + 1 ) );
return( EXIT_SUCCESS );
} /* end of main */
--------------------------------------------------------------------------
$ ./other_bus
总线错误 (core dumped)
$ gdb ./other_bus core
GNU gdb 5.0
#0 main (argc=1, argv=0xffbefc44) at other_bus.c:13
13 j = *( ( unsigned short int * )( ( ( unsigned char * )&i ) + 1 ) );
(gdb) disas main
Dump of assembler code for function main:
0x10810
0x10814
0x10818
0x1081c
0x10820
0x10824
0x10828
0x1082c
0x10830
0x10834
0x10838
0x1083c
0x10840
0x10844
End of assembler dump.
(gdb) i r pc
pc 0x1082c 67628
(gdb)
因此在SPARC架构上编程,一定要留神强制类型转换,务必清楚自己正在干什么,有
没有隐患。
D: yuhuan@SMTH 2004-01-30 11:48
参Linux的mmap(2)手册页
--------------------------------------------------------------------------
使用映射可能涉及到如下信号
SIGSEGV
试图对只读映射区域进行写操作
SIGBUS
试图访问一块无文件内容对应的内存区域,比如超过文件尾的内存区域,或者以
前有文件内容对应,现在为另一进程截断过的内存区域。