graemedouglas / LittleD

A relational database for embedded devices and sensors nodes
Apache License 2.0
726 stars 51 forks source link

Misaligned memory accesses cause hard faults on 32 bit M0 platform #3

Open bradjc opened 9 years ago

bradjc commented 9 years ago

This one took me a while to track down, but things stopped working when I moved code from Linux to the Cortex M0 nRF51822 BLE chip. I tracked this back to db_qmm_falloc() and db_qmm_balloc(). Basically, if something tries to allocate a buffer of a size not a multiple of 4, when the alloc() functions try to write the size to the beginning of the allocated area, it causes a misaligned memory access:

*((db_int*)(mmp->last_back)) = size;

My quick and dirty workaround is to convert size to the next biggest multiple of four:

db_int blob = size+sizeof(db_int);
if (blob % 4 != 0) {
    blob += (4 - (blob % 4));
}
size = blob - sizeof(db_int);

and throw that near the beginning of the alloc() functions.

I have no idea if that actually fixes anything or just masks issues temporarily. I've ran one SELECT statement that I got to work with that change in there, but haven't done any more than that (I wanted to get this posted so I didn't forget). It's entirely possible that this is the best solution and that all later accesses are safe.

graemedouglas commented 9 years ago

I will add automatic alignment as an option (with #define). I've never tested with ARM processors and so alignment was never an issue. Thank you again.

kazetora commented 8 years ago

@bradjc I tried to compile this using arm-gcc for cortex m0, and the size is too big (about 100KB). It seems you made it work with cortex m0, what sort of compiler and options are you using?

graemedouglas commented 8 years ago

Hi @kazetora,

It looks to me as if this isn't the same issue (though you will have the same problem that @bradjc mentions here; copy and paste his code just before lines 61 and 112 in src/dbmm/db_query_mm.c).

If you haven't already, try not compiling with any print statements. The most recent merge should make this simple, or you can use db_ctconf.h and set #define DB_CTCONF_SETTING_FEATURE_ERROR_MESSAGES 0 (presently line 116).

That should make everything work.