gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Bus errors

#13074 - poslundc - Thu Dec 04, 2003 8:32 pm

What exactly causes these?

I am attempting to link a project that includes a rather large (about 200K) .o file that contains no functions, just data declared as "const" (so it should be put into the ROM section). Everything compiles fine, but when I include the .o file ld chokes and hands me a "bus error".

I've encountered bus errors before and managed to resolve them without too much difficulty (usually something to do with my symbol referencing), but this one is stumping me.

Any ideas?

Thanks,

Dan.

#13077 - tepples - Thu Dec 04, 2003 8:59 pm

"Bus error"? Either there's a bug in ld, or you have bad RAM. Please include the entire error message that ld emits.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#13078 - poslundc - Thu Dec 04, 2003 9:17 pm

It's not exactly informative, but here it is:

Quote:

make: *** [build/main.elf] Bus error
make: *** Deleting file `build/main.elf'


Dan.

#13079 - poslundc - Thu Dec 04, 2003 9:33 pm

GRAARRGH I just figured it out.

I had a small reference table that I stupidly just declared inside a header file instead of putting it into a separate .c file and just putting an extern reference to it in the header file.

My data file was referencing some structs from that header file, which meant multiple C files were including the same header file... bam, multiple definitions of the same symbol.

Meanwhile I was combing furiously through this 1 MB C file that defines my 200K of object data, looking for what could be causing the error. Turns out it was simply the #include statement at the top.

Let this serve as a warning to all newbies: resist the urge to put your const data into .h files! Find a safer way!

And if you get a bus error while linking, be sure to check to make sure you aren't defining a symbol multiple times.

Dan.

#13204 - SmileyDude - Mon Dec 08, 2003 3:15 am

You got a Bus Error? I take it that you aren't using an x86 PC then, right? Typically, a Bus Error occurs when you try to access data that is misallgined (i.e, a 16-bit int that's not on a 16-bit boundary). But, the x86 automatically handles misaligned data -- unlike just about every other processor. When I worked with Sun boxes, it was very easy to get a bus error when dealing with data from PCs. Since the PC didn't care about alignment, and the SPARC did, if you weren't careful, you'd get Bus Errors.

Anyway, like Tepples said, bus errors usually indicate errors in the program. I don't know about the memory problems, but that also seems like a likely culprit (maybe that's the only way you can get a Bus Error on the x86?) If you are on an x86, you would definetly want to check your memory. If it is bad, get memory from Crucial -- they guarentee their memory. And besides, it's not that much more than the cheap stuff.
_________________
dennis

#13205 - tepples - Mon Dec 08, 2003 4:07 am

SmileyDude wrote:
Typically, a Bus Error occurs when you try to access data that is misallgined (i.e, a 16-bit int that's not on a 16-bit boundary).

That's one sort of bus error (FOLDOC definition). But processors used in Macintosh computers (68K and PowerPC) have always distinguished between "bus error" and "address error," and an invalid unaligned access is an "address error." A "bus error" is an access to an address where the chipset's memory controller hasn't mapped anything. But in protected mode operating systems, addresses that would normally cause "bus errors" get mapped as "segmentation violation" errors unless the "bus error" is in fact caused by bad RAM, and even then, some kernels such as Linux can detect bad areas of RAM and mark them as unavailable.

Quote:
But, the x86 automatically handles misaligned data -- unlike just about every other processor.

Know why? All the efficient methods of handling unaligned data accesses in software are patented, which is why the free implementation of the MIPS architecture doesn't handle unaligned data accesses.

Quote:
When I worked with Sun boxes, it was very easy to get a bus error when dealing with data from PCs. Since the PC didn't care about alignment, and the SPARC did, if you weren't careful, you'd get Bus Errors.

Teaches the developer to always serialize and deserialize data byte-by-byte, which is a good practice in general.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#13264 - sgeos - Wed Dec 10, 2003 4:08 am

poslundc wrote:
Let this serve as a warning to all newbies: resist the urge to put your const data into .h files! Find a safer way!


Code does not belong in header files.

blah.h
Code:
#ifndef BLAH_H
#define BLAH_H

extern const unsigned long obj_blah[];
extern const unsigned short pal_blah[];

#endif  /* BLAH_H */


blah.c
Code:
#include "blah.h"

const unsigned long obj_blah[] = {
   0x00111100,
   0x01222210,
   0x12122121,
   0x12222231,
   0x12122131,
   0x12211231,
   0x01233310,
   0x00111100,
};

const unsigned short pal_blah[] = {
   0x0000, 0x0000, 0x03FF, 0x0210,
   0x0000, 0x0000, 0x03FF, 0x0210,
   0x0000, 0x0000, 0x03FF, 0x0210,
   0x0000, 0x0000, 0x03FF, 0x0210,
};


The above is not tested. If the program were compiled with something like this:
gcc -Wall -o blah main.c blah.c

main.h would probably want to #include "blah.h"

Actually, now that I look at it, blah.c may not want to #include "blah.h". Will the extern declaration in the header hurt anything?

-Brendan

#13266 - sajiimori - Wed Dec 10, 2003 6:41 am

Quote:

Will the extern declaration in the header hurt anything?

No, the compiler will consider them the same object, much like having a function prototype before its definition.

#13320 - poslundc - Thu Dec 11, 2003 4:07 am

Just spent about an hour tracking down another bus error... I'll post the details here to hopefully spare someone else the annoyance:

Bus errors can also be caused by questionable initializations of variables. The particular example that was causing my error was just a quick hash table I created in a function:

Code:
unsigned char   channelHash[8] = {0, 4, 5, 1, 2, 6, 7, 3};


This compiled fine with gcc, but generated a bus error on linking. I think it has something to do with trying to address single bytes of IWRAM. I also tried casting each of the elements as unsigned chars and it still didn't work. But when I converted it to an array of unsigned ints instead of unsigned chars, it worked fine.

Hope this helps someone else out.

Dan.