您的位置:首页 > 其它

armhf sig bus error

2016-01-29 16:21 295 查看
(gdb) run
Starting program: /htslib-1.2.1/test/sam test/ce.fa
[Thread debugging using libthread_db enabled]
Using host libthread_db library
"/lib/arm-linux-gnueabihf/libthread_db.so.1".

Program received signal SIGBUS, Bus error.
0x00025640 in bam_aux2f (
s=0xa967e "\333\017I@XddiW\024\213\n\277\005@XZZHello, world!",
s@entry=0xa967d "f\333\017I@XddiW\024\213\n\277\005@XZZHello, world!")
at sam.c:1181
1181        else if (type == 'f') return *(float*)s;
(gdb)

This is an alignment issue. VFP requires floating point loads and stores
to be naturally aligned but s is only aligned to 2 bytes whiile a float
is 4 bytes. Looking further at the code reveals the reason for the
unalignment. It seems that the code is reading from a data format where
values are prefixed with single bytes practically gauranteeing that many
of the accesses will be unaligned.

In portable code unaligned accesses should be avoided. Sometimes they
will give the right result, sometimes they will give bus errors,
sometimes they will silently give wrong answers. To a large extent the
behaviour is driven by architecture (and sometimes version of the
architecture) but it can also be driven by what instructions the
compiler choses to use. Even if it does the right thing it may do so
very slowly. x86 tends to be the most forgiving architecture when it
comes to unaligned accesses.

The attatched patch replaces a number of unaligned accesses in sam.c
with memcpy calls. It resulted in a successful build on raspbian
stretch. I did not include any conditional logic but it would be easy to
add conditional logic to only use memcpy on non-x86 targets if that was
considered desirable (I do not if memcpy is faster or slower than
letting the x86 cpu fixup the unaligned accesses in hardware and if-so
whether the difference is likely to be significant).

[htslib.debdiff (text/plain, attachment)]

+@@ -1177,8 +1183,8 @@ double bam_aux2f(const uint8_t *s)
+ {
+     int type;
+     type = *s++;
+-    if (type == 'd') return *(double*)s;
+-    else if (type == 'f') return *(float*)s;
++    if (type == 'd') return READUNALIGNED(s,double);
++    else if (type == 'f') return READUNALIGNED(s,float);
+     else return 0.0;
+ }


++#define READUNALIGNED(ptr,type) ({ \
++    type tmp;\
++    memcpy(&tmp,ptr,sizeof(type));\
++    tmp;\
++})
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: