Skip navigation.
Home
The QNX Community Portal

View topic - SIGBUS error.

SIGBUS error.

For discussion of realtime and/or embedded programming.

Postby Tim » Thu Sep 02, 2010 2:13 pm

Eric,

Looking a bit inside the memAlignTest.h file I see the following:

#pragma pack(1)

proceeding several structures. These structures are included in your clsCTL class which contains the clsMatrix class (the nesting issue that makes everything so confusing).

That pragma pack(1) tells the compiler to align on 1 byte boundaries instead of the default boundaries for your processor. Lord only knows what it's done to your alignment. I highly suspect those packs are causing everything to get misaligned especially since one of the 3 instances of clsMatrix was correctly aligned (I'd bet my life it's the one in the clsPath class which does NOT contain any of the prama packed structures).

As a quick and dirty test, move the clsMatrix declarations in clsCTL so that they are the *first* defined variables in that class before those packed structures. See if that fixes your problem. If it does you know the packing is a problem you'll have to solve.

Tim
Tim
Senior Member
 
Posts: 1390
Joined: Wed Mar 10, 2004 12:28 am

Postby mario » Thu Sep 02, 2010 2:35 pm

pragma pack(1) , that is probably it.
mario
QNX Master
 
Posts: 4132
Joined: Sun Sep 01, 2002 1:04 am

Postby Ericxx » Thu Sep 02, 2010 2:43 pm

Indeed, many thanks! Tim and mario. I just deleted all the "pragma pack" and ran the program, it executed normally now.

Eric
Ericxx
Senior Member
 
Posts: 158
Joined: Mon Jun 09, 2008 1:38 pm

RE: SIGBUS error.

Postby Ericxx » Mon Sep 27, 2010 12:05 pm

Sorry, another SIGBUS error occurs when I tried adding some stuff as follows:
Code: Select all
struct TELEGRAPH {
   int nSize;
   char szTele[512];
};

void clsCMM::MakeTelegraph(TELEGRAPH *pTele, short code, double time, void *pData, int nDataSize)
{
   char *pBuffer = pTele->szTele;

//   (double &)pBuffer[6] = time;
   pBuffer[0] = 0x50 + _HELICOPTER;   //_nHelicopter
   pBuffer[1] = 0x55;            //ground station

   (short &)pBuffer[2] = nDataSize+10;
   (short &)pBuffer[4] = code;
//   (double &)pBuffer[6] = time;
   (float &)pBuffer[6] = (float)time;
   ::memcpy(pBuffer+14, pData, nDataSize);

   (unsigned short &)pBuffer[14+nDataSize] = CheckSum(pBuffer+4, 10+nDataSize);

   pTele->nSize = nDataSize + 16;
}


The cursor stopped at "(float &)pBuffer[6] = (float)time;" the below is the assembly output, look forward to your kind suggestion. Thanks.


(short &)pBuffer[4] = code;
0x0010e9f8 <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+128>: ldr r3, [r11, #-20]
0x0010e9fc <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+132>: add r3, r3, #4 ; 0x4
0x0010ea00 <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+136>: ldrh r2, [r11, #-28]
0x0010ea04 <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+140>: strh r2, [r3]
(float &)pBuffer[6] = (float)time;
0x0010ea08 <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+144>: ldr r3, [r11, #-20]
0x0010ea0c <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+148>: add r4, r3, #6 ; 0x6
0x0010ea10 <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+152>: sub r1, r11, #36 ; 0x24
0x0010ea14 <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+156>: ldm r1, {r0, r1}
0x0010ea18 <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+160>: bl 0x103748 <__truncdfsf2>
0x0010ea1c <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+164>: mov r3, r0
0x0010ea20 <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+168>: str r3, [r4]
::memcpy(pBuffer+14, pData, nDataSize);
0x0010ea24 <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+172>: ldr r3, [r11, #-20]
0x0010ea28 <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+176>: add r2, r3, #14 ; 0xe
0x0010ea2c <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+180>: ldr r3, [r11, #8]
0x0010ea30 <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+184>: mov r0, r2
0x0010ea34 <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+188>: ldr r1, [r11, #4]
0x0010ea38 <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+192>: mov r2, r3
0x0010ea3c <_ZN6clsCMM13MakeTelegraphEP9TELEGRAPHsdPvi+196>: bl 0x103358 <memcpy>
Ericxx
Senior Member
 
Posts: 158
Joined: Mon Jun 09, 2008 1:38 pm

RE: SIGBUS error.

Postby mario » Mon Sep 27, 2010 1:07 pm

Same story, the code is trying to write a float ( which is 4 bytes ) on an 2 bytes boundary can't to that on ARM architecture. You can align the data by moving it to pBuffer[8] instead, but it sounds like you do not have control over the format of the data. Seems like the best option is to use memcpy which works one byte at a time and thus is unaffected by alignement issues.
mario
QNX Master
 
Posts: 4132
Joined: Sun Sep 01, 2002 1:04 am

RE: SIGBUS error.

Postby Ericxx » Tue Sep 28, 2010 1:35 am

Thanks, mario. Works fine with the memcpy method. Another problem is what if i want to decode the same structure on a x86 host machine? The structures defined in armle can be correctly mapped on the x86 machine?

Thanks,
Eric
Ericxx
Senior Member
 
Posts: 158
Joined: Mon Jun 09, 2008 1:38 pm

RE: SIGBUS error.

Postby Ericxx » Tue Sep 28, 2010 9:19 am

For example, i have a structure defined as:

struct PACK {
unsigned char type;

double a;
double b;
double c;

double p;
double q;
double r;

double acx;
double acy;
double acz;

double magx;
double magy;
double magz;

double tmp;
};
Ericxx
Senior Member
 
Posts: 158
Joined: Mon Jun 09, 2008 1:38 pm

RE: SIGBUS error.

Postby mario » Tue Sep 28, 2010 1:47 pm

As far as I know default alignment is the same. The C and C++ language does not defined aligment behavior, as such any program that rely data aligment is NOT portable. Posting the structure definition like you just did means nothing because it depends on compiler options, usage of compiler extention etc. For this structure to work on ARM there must be 3 ( or 7 ) bytes in between variable type and a. However that is not the case with x86.


You can limit and control this with compiler extention (pragma pack, __attribute), and careful coding but it is always going to be a pain. You can use sizeof() and offsetof() to check if everything matches. You can also use code that will copy the data set byte by byte, meaning that the program may use a structure called ABC but when it's type to transfer it over to another machine of different CPU type it's move to a structure ABCNetwork which is well defined packing wise. When it's receive on the x86 size the data ABCNetwork is copied into ABC again which because it's on x856 may not have the same format as ABC on arm (that may include handling endian)

That's a little bit how TCP/IP works and deal with endianness.
mario
QNX Master
 
Posts: 4132
Joined: Sun Sep 01, 2002 1:04 am

Re: RE: SIGBUS error.

Postby Tim » Tue Sep 28, 2010 1:53 pm

Eric,

Ericxx wrote:Another problem is what if i want to decode the same structure on a x86 host machine? The structures defined in armle can be correctly mapped on the x86 machine?


What do you mean by decode? As in passing data directly from one to the other (either via writing to a file that's later read on the other processor or across a serial/Ethernet link etc)

Obviously as a minimum you'd better make sure you have the Endianness set to Little which is how X86 works. I believe you've already done this.

On the X86 side you'll want to have the byte boundaries set the same as those of the Arm processor. You only need to do that for your structure PACK. You can use the '#pragma pack' directive to set the byte boundaries appropriately.

Code: Select all
#pragma pack(push, 4)   // Align on 4 byte boundary
struct PACK {
unsigned char type;

double a;
double b;
double c;

double p;
double q;
double r;

double acx;
double acy;
double acz;

double magx;
double magy;
double magz;

double tmp;
};
#pragma pack(pop)



I've used the above concept to align on 1 byte boundaries before when reading data from a serial device that had no concept of byte alignment.

Tim
Tim
Senior Member
 
Posts: 1390
Joined: Wed Mar 10, 2004 12:28 am

RE: Re: RE: SIGBUS error.

Postby Ericxx » Wed Oct 20, 2010 2:38 pm

Many thanks for all your explanations!
Sorry for so late update. Basically, i collect data and write them into a log file on the armle and then decode on the x86 host. The log data when analyzed in hex format, found that a zero byte is paddled after the unsigned char type, which is not desired on x86 and lead to the incorrect parsing on the x86 with the same data structure PACK as shown above.

From Tim's post, seems that i can change the alignment on x86 by using #pragma pack? I have tried (push,4) and (push,2) but didnot work.. I think i did not get the whole idea..

Regards,
Eric
Ericxx
Senior Member
 
Posts: 158
Joined: Mon Jun 09, 2008 1:38 pm

RE: Re: RE: SIGBUS error.

Postby mario » Wed Oct 20, 2010 4:05 pm

I have add better success with the __attribute__ modifier.

Why don't you make the log file data immune to this, by serialising it, using ascii, or xml etc.
mario
QNX Master
 
Posts: 4132
Joined: Sun Sep 01, 2002 1:04 am

RE: Re: RE: SIGBUS error.

Postby Ericxx » Thu Oct 21, 2010 2:53 pm

Thanks, mario. But will the speed become slower compared with the binary approach? The file write operation consumes quite a lot of cpu time.

Regards,
Eric
Ericxx
Senior Member
 
Posts: 158
Joined: Mon Jun 09, 2008 1:38 pm

RE: Re: RE: SIGBUS error.

Postby mario » Thu Oct 21, 2010 3:42 pm

In general yes it will create bigger files. If you have double value which uses up 8 bytes, and many but if you are carefull about it ( avoiding printf like fct ) you can minimise the impact. If you use Photon you could use PxConfig*.

Depending on the size of the writes, it may be better to use open() then fopen(). Or use fopen() and increase buffer size with setvbuf. Overhead can be reduce drastically. What kind of hardware is this, writing to disk is typicaly done via DMA and doesn't use much CPU.

What is nice about using some soft of ascii based file is that if the creator adds/remove a field, the code that decodes it will not be affected.

Where I work everything is XML based. Our real-time code runs on QNX and all the GUI is on Windows(Java) and all the data exchange is done through XML. It does add overhead CPU wise but it MUCH more easier to deal with.
mario
QNX Master
 
Posts: 4132
Joined: Sun Sep 01, 2002 1:04 am

Re: RE: Re: RE: SIGBUS error.

Postby Tim » Thu Oct 21, 2010 5:06 pm

mario wrote:Where I work everything is XML based. Our real-time code runs on QNX and all the GUI is on Windows(Java) and all the data exchange is done through XML. It does add overhead CPU wise but it MUCH more easier to deal with.


Same here with our differences being that the GUI is in C# and we exchange live data via sockets. But all our configuration files and permanent data storage is done via XML.

Tim
Tim
Senior Member
 
Posts: 1390
Joined: Wed Mar 10, 2004 12:28 am

RE: Re: RE: Re: RE: SIGBUS error.

Postby mario » Thu Oct 21, 2010 11:39 pm

We use the Poco C++ library for that, lovely stuff.
mario
QNX Master
 
Posts: 4132
Joined: Sun Sep 01, 2002 1:04 am

PreviousNext

Return to Realtime and Embedded

Who is online

Users browsing this forum: No registered users and 1 guest