SIGBUS on ( double * )

315 views
Skip to first unread message

Marco Bernasocchi

unread,
Oct 23, 2013, 1:12:28 PM10/23/13
to necessit...@kde.org, andro...@googlegroups.com, andro...@googlegroups.com
Hi all, I often get SIGBUS when my code (qgis.org) hits stuff like this:

GEOSCoordSeq_getX( cs, j, ( double * )&mGeometry[position] );

if I change the call to use memcpy like

double a;
memcpy( a, &mGeometry[position])
GEOSCoordSeq_getX( cs, j, &a )

then all works correctly, the issue is that I've a lot of those calls
and If I'm not wrong in the past it used to work). could this be because
of a compiler setting? I'm using necessitas Qt sdk with ndk r8b1
compiling both with -mthumb and without has the same issue.

thanks a lot
Marco
--
Marco Bernasocchi
http://opengis.ch

BogDan Vatra

unread,
Oct 23, 2013, 1:32:35 PM10/23/13
to android-qt, andro...@googlegroups.com, necessit...@kde.org

Hi,

It happens because you are trying to access unaligned memory which on arm is not allowed.

Cheers,
BogDan.

--
You received this message because you are subscribed to the Google Groups "android-qt" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-qt+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Jeffrey Walton

unread,
Oct 23, 2013, 1:45:47 PM10/23/13
to Android NDK List, necessit...@kde.org, andro...@googlegroups.com
> I often get SIGBUS when my code (qgis.org) hits stuff like this:
>
> GEOSCoordSeq_getX( cs, j, ( double * )&mGeometry[position] );
Yes, that's not legal C/C++. Its undefined behavior.

> double a;
> memcpy( a, &mGeometry[position])
> GEOSCoordSeq_getX( cs, j, &a )
>
> then all works correctly,
Yep. And if the buffers overlap, you need to `memmov` it.

> could this be because of a
> compiler setting?
No, its the QT devs doing something they should not be doing. Newer
ARMs are OK with unaligned data, while older ARMs are not. They appear
to be testing on newer ARMs only (ARMv6 or ARMv7, IIRC).

I believe -Wstrict-aliasing or -Wcast-align will catch it at compile
time. See http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html and
https://www.gnu.org/software/gsl/manual/html_node/GCC-warning-options-for-numerical-programs.html#GCC-warning-options-for-numerical-programs.

Jeff

Marco Bernasocchi

unread,
Oct 23, 2013, 2:00:36 PM10/23/13
to nolo...@gmail.com, Android NDK List, andro...@googlegroups.com, necessit...@kde.org
On 10/23/2013 07:45 PM, Jeffrey Walton wrote:
>> I often get SIGBUS when my code (qgis.org) hits stuff like this:
>>
>> GEOSCoordSeq_getX( cs, j, ( double * )&mGeometry[position] );
> Yes, that's not legal C/C++. Its undefined behavior.
how do you mean?
I get SIGBUS also for things like:
tempx = ( double* )ptr;

and replacing with the following does the job:
memcpy( &tempx, ptr, sizeof( tempx ) );
>
>> double a;
>> memcpy( a, &mGeometry[position])
>> GEOSCoordSeq_getX( cs, j, &a )
>>
>> then all works correctly,
> Yep. And if the buffers overlap, you need to `memmov` it.
>
>> could this be because of a
>> compiler setting?
> No, its the QT devs doing something they should not be doing. Newer
> ARMs are OK with unaligned data, while older ARMs are not. They appear
> to be testing on newer ARMs only (ARMv6 or ARMv7, IIRC).
I run my code on ARMv7 after building with:
for debug:
CFLAGS: -DANDROID -Wno-psabi -std=c99 -g -O0 -marm -finline-limit=300
-fno-strict-aliasing -fno-omit-frame-pointer -DDEBUG -D_DEBUG
-march=armv7-a -mfloat-abi=softfp -mfpu=vfp
CXXFLAGS: -DANDROID -Wno-psabi -std=gnu++0x -g -O0 -marm
-finline-limit=300 -fno-strict-aliasing -fno-omit-frame-pointer -DDEBUG
-D_DEBUG
LDFLAGS: -Wl,--fix-cortex-a8

for release:
CFLAGS: -DANDROID -Wno-psabi -std=c99 -mthumb -O0 -march=armv7-a
-mfloat-abi=softfp -mfpu=vfp
CXXFLAGS:-DANDROID -Wno-psabi -std=gnu++0x -mthumb -O0 -march=armv7-a
-mfloat-abi=softfp -mfpu=vfp
LDFLAGS: -Wl,--fix-cortex-a8
thanks a lot
> Jeff
>
> On Wed, Oct 23, 2013 at 1:12 PM, Marco Bernasocchi
> <ma...@bernawebdesign.ch> wrote:
>> Hi all, I often get SIGBUS when my code (qgis.org) hits stuff like this:
>>
>> GEOSCoordSeq_getX( cs, j, ( double * )&mGeometry[position] );
>>
>> if I change the call to use memcpy like
>>
>> double a;
>> memcpy( a, &mGeometry[position])
>> GEOSCoordSeq_getX( cs, j, &a )
>>
>> then all works correctly, the issue is that I've a lot of those calls and If
>> I'm not wrong in the past it used to work). could this be because of a
>> compiler setting? I'm using necessitas Qt sdk with ndk r8b1 compiling both
>> with -mthumb and without has the same issue.
>>
>> thanks a lot
>> Marco
> _______________________________________________
> Necessitas-devel mailing list
> Necessit...@kde.org
> https://mail.kde.org/mailman/listinfo/necessitas-devel

Jeffrey Walton

unread,
Oct 23, 2013, 2:38:00 PM10/23/13
to Marco Bernasocchi, Android NDK List, andro...@googlegroups.com, necessit...@kde.org
>> Yes, that's not legal C/C++. Its undefined behavior.
>
> how do you mean?
> I get SIGBUS also for things like:
> tempx = ( double* )ptr;
Its not legal C/C++.

> I run my code on ARMv7 after building with:
That's interesting that you could induce that on an ARMv7. I was
trying to do it for the longest time (for use as a test case, see
http://stackoverflow.com/questions/15233717/linux-x86-x64-turn-off-misaligned-data-fixups).

Jeff

On Wed, Oct 23, 2013 at 2:00 PM, Marco Bernasocchi

Luca Castoro

unread,
Oct 23, 2013, 6:33:21 PM10/23/13
to andro...@googlegroups.com
I think it's quite legal c99 code, not c++.
Maybe you can try to change from inside the method from
*output = value;
to
memcpy( output , (void*)&value , sizeof(double) );

Marco Bernasocchi

unread,
Oct 23, 2013, 1:49:13 PM10/23/13
to BogDan Vatra, andro...@googlegroups.com, andro...@googlegroups.com, necessit...@kde.org
Hi Bogdan, thanks for the quick response. So I was dreaming about the
fact that it used to work? and that it might be a compiler flag?

so is my only option memcpy? here [0] they talk about -malign-double,
could it be of any help?

ciao and thanks a lot
Marco

[0]
http://software.intel.com/en-us/blogs/2011/08/18/understanding-x86-vs-arm-memory-alignment-on-android
>> email to android-qt+unsubscribe@**googlegroups.com<android-qt%2Bunsu...@googlegroups.com>
>> .
>> For more options, visit https://groups.google.com/**groups/opt_out<https://groups.google.com/groups/opt_out>
>> .

BogDan Vatra

unread,
Oct 24, 2013, 7:36:31 AM10/24/13
to Marco Bernasocchi, android-qt, andro...@googlegroups.com, Necessitas
Hi Marco,

On intel is ok to access unaligned memory, but not on ARM, I always
use memcpy to be 100% sure it works.
I have no idea if -malign-double will fix your problem, you can try
it but ... IMHO using memcpy is the safest way.

Cheers,
BogDan.

2013/10/23 Marco Bernasocchi <ma...@bernawebdesign.ch>:

David Given

unread,
Oct 24, 2013, 7:56:26 AM10/24/13
to andro...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 24/10/13 12:36, BogDan Vatra wrote:
[...]
> On intel is ok to access unaligned memory, but not on ARM, I
> always use memcpy to be 100% sure it works. I have no idea if
> -malign-double will fix your problem, you can try it but ... IMHO
> using memcpy is the safest way.

memcpy will avoid this particular problem (although it might be
painfully slow, depending on compiler options), but it's just patching
round the underlying issue that the double variables should be at
unaligned addresses in the first place.

You posted this code:

GEOSCoordSeq_getX( cs, j, ( double * )&mGeometry[position] );

What is mGeometry? Where did it come from?

- --
???? ?????????????? ????? http://www.cowlark.com ?????
?
? "Home is where, when you have to go there, they have to take you in."
? --- Cordelia Naismith (via Robert Frost)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)

iD8DBQFSaQrnf9E0noFvlzgRAmD1AJ9OsgRksqi/d4NkssGGiXqgOu1UrgCcCwiN
WISQN4L9QdUpd/TFgDyxnq4=
=rAs/
-----END PGP SIGNATURE-----

Marco Bernasocchi

unread,
Oct 24, 2013, 2:10:47 PM10/24/13
to andro...@googlegroups.com, Marco Bernasocchi, andro...@googlegroups.com, necessit...@kde.org, nolo...@gmail.com
Well, Jeff, I would really be happy _not_ to have managed to do this...
So you suggest on v7 it should actually be ok? do you have any reference I could inform myself a bit more?

thanks

Marco Bernasocchi

unread,
Oct 24, 2013, 2:15:15 PM10/24/13
to andro...@googlegroups.com
Hi David 


On Thursday, 24 October 2013 13:56:26 UTC+2, David Given wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 24/10/13 12:36, BogDan Vatra wrote:
[...]
> On intel is ok to access unaligned memory, but not on ARM, I
> always use memcpy to be 100% sure it works. I have no idea if
> -malign-double will fix your problem, you can try it but ... IMHO
> using memcpy is the safest way.

memcpy will avoid this particular problem (although it might be
painfully slow, depending on compiler options), but it's just patching
round the underlying issue that the double variables should be at
unaligned addresses in the first place.

You posted this code:

GEOSCoordSeq_getX( cs, j, ( double * )&mGeometry[position] ); 

What is mGeometry? Where did it come from?

Jeffrey Walton

unread,
Oct 24, 2013, 3:07:05 PM10/24/13
to Android NDK List
On Thu, Oct 24, 2013 at 2:15 PM, Marco Bernasocchi
<ma...@bernawebdesign.ch> wrote:
> ...
>> GEOSCoordSeq_getX( cs, j, ( double * )&mGeometry[position] );
>>
>>
>> What is mGeometry? Where did it come from?
>
> the code comes from [1] and mGeometry is a mutable unsigned char *
> mGeometry; [0]
>
> [0]
> https://github.com/mbernasocchi/QGIS/blob/android-2_0_1/src/core/qgsgeometry.cpp#L474
> [1]
> https://github.com/mbernasocchi/QGIS/blob/android-2_0_1/src/core/qgsgeometry.cpp#L4995
Change the call to `memalign`:

$ grep -R align
/opt/android-ndk-r8e//platforms/android-14/arch-arm/usr/include/*
...
/opt/android-ndk-r8e//platforms/android-14/arch-arm/usr/include/malloc.h:
extern void* memalign(size_t alignment, size_t bytesize);

Or, make it a member variable and use an attribute:

$ grep -R align
/opt/android-ndk-r8e//platforms/android-14/arch-arm/usr/include/*
...
/opt/android-ndk-r8e//platforms/android-14/arch-arm/usr/include/sys/cdefs.h:
#define __aligned(x) __attribute__((__aligned__(x)))

Jeff

Luca Castoro

unread,
Oct 24, 2013, 6:06:06 PM10/24/13
to andro...@googlegroups.com, nolo...@gmail.com
As stated at http://developer.android.com/tools/sdk/ndk/index.html

Android NDK, Revision 9 (July 2013):
 -
Note: In the GCC 4.7 release and later, ARM compilers generate unaligned access code by default for ARMv6 and higher build targets. You may need to add the -mno-unaligned-access build option when building for kernels that do not support this feature.

I would give it a try :)

Luca Castoro

unread,
Oct 24, 2013, 8:20:34 PM10/24/13
to andro...@googlegroups.com, nolo...@gmail.com
Also you can try to pack your output buffer in a union that *should* force alignment to the bigger type, something like:

union { unsigned char byte; unsigned short word; unsigned long dword; unsigned long long qword; } mGeometry
[ SIZE ];

or

typedef union { unsigned char byte; unsigned short word; unsigned long dword; unsigned long long qword; } anyType; anyType* mGeometry = malloc( etc... etc... );

...
Reply all
Reply to author
Forward
0 new messages