Bus error

C and PASCAL (or any other high-level languages) in here please

Moderators: simonsunnyboy, Mug UK, Zorro 2, Moderator Team

jury
Captain Atari
Captain Atari
Posts: 370
Joined: Tue Sep 21, 2004 11:11 am
Location: Poland

Bus error

Postby jury » Wed Dec 26, 2018 10:28 am

Below function runs in a loop at 1 pixel step ( x=x+1, y is the bottom line and always stays the same ) for the bitmat with fonts.
Firts fraction of that bitmap looks like below attachement. All goes fine untill x position hits the pixel different than black, no matter what color it is, it gives Bus Error. But when I change declaration of pixel variable from Uint32 to for example unsigned char, there is no Bus Error. Why does it give an error when pixel is declared as Uint32?
And what confuses me more, is that when I use Super Videl it gives no error even when pixel is Uint32.
Whats the magic behind above behaviour?
Resolution is 640x480x8bit

Code: Select all

Uint32 get_pixel( SDL_Surface *surf, int x, int y )
{
    int pos = 0;
    Uint32 pixel = 0;   
   //unsigned char pixel = 0;

    pos = y * surf->pitch + x * surf->format->BytesPerPixel;
    printf ( "x: %d y: %d pos: %d surf->pitch: %d surf->format->bpp: %d\n", x, y, pos, surf->pitch, surf->format->BytesPerPixel );
    memcpy( &pixel, surf->pixels + pos, surf->format->BytesPerPixel );
    return pixel;
}
You do not have the required permissions to view the files attached to this post.

ThorstenOtto
Atari Super Hero
Atari Super Hero
Posts: 742
Joined: Sun Aug 03, 2014 5:54 pm

Re: Bus error

Postby ThorstenOtto » Wed Dec 26, 2018 10:46 am

jury wrote:Whats the magic behind above behaviour?


I guess its because your SDL surface actually has 256 colors, so BytesPerPixel is 1. Your memcpy therefore only copies one byte to your pixel variable. On a big-endian machine like 68k, that will be copied to the most significant byte of your pixel variable. It also explains why you don't get a bus-error if the color is black, assuming the pixel value for black is zero. But if its read for example, and red has a pixel value of 1, the result of your function will be 0x01000000 which is out of the range of your 256 colors. If that value is later used as index into a palette to get the actual colors -> crash.

Solution: you actually have to distinguish between at least 1/2/3/4 bytes-per-pixel format of the surface in your get_pixel function. Also, for 3- or 4 bytes, there might be different results in the order of components, RGBA vs ABGR for example. But that should not give bus errors, only wrong colors if it does not match your expectation.

jury
Captain Atari
Captain Atari
Posts: 370
Joined: Tue Sep 21, 2004 11:11 am
Location: Poland

Re: Bus error

Postby jury » Wed Dec 26, 2018 8:52 pm

Thanks for reply, but I think I do not understand it. Memcpy does not do any interpretation of its data, it just copies given number of bytes from source to destination. And whether I'm on little or big endian it should not matter completely from what I understand.
I declare some variable as 32 bit integer and as long as I do not try to copy there more than 32 bits, all should be fine. Well even if I would copy more than 32 bits it should not throw any error, it just should silently overwrite memory passed my Uint32 and thats it. So it should not give any bus error in the above example, it just should be a simple move of a byte from one place to another. Am I wrong here?
Then how I will interpret this data later on, its a differen case.

mikro
Hardware Guru
Hardware Guru
Posts: 2013
Joined: Sat Sep 10, 2005 11:11 am
Location: Kosice, Slovakia
Contact:

Re: Bus error

Postby mikro » Wed Dec 26, 2018 10:32 pm

Well, you should have posted the whole code, now it's just guess work. What Thorsten says that if the result from get_pixel() is used somewhere (say, as an index), it can easily return bogus values. So it depends what do you do with the result.

ranix
Obsessive compulsive Atari behavior
Obsessive compulsive Atari behavior
Posts: 109
Joined: Sun Jan 14, 2018 8:01 pm

Re: Bus error

Postby ranix » Wed Dec 26, 2018 11:33 pm

jury wrote:whether I'm on little or big endian it should not matter completely from what I understand.
I declare some variable as 32 bit integer and as long as I do not try to copy there more than 32 bits, all should be fine. Am I wrong here?


But Uint32 pixel is 2 bytes long and unsigned char pixel is one byte long. It looks to me like you are copying one byte worth of data into the high byte of the Uint32. You're putting BytesPerPixel (an int I assume, probably 1) worth of data into the memory address pointed to by &pixel. This will mean that Uint32 pixel and unsigned char pixel will have different contents and represent different numbers after the memcpy due to this format difference.

ThorstenOtto
Atari Super Hero
Atari Super Hero
Posts: 742
Joined: Sun Aug 03, 2014 5:54 pm

Re: Bus error

Postby ThorstenOtto » Thu Dec 27, 2018 1:01 am

jury wrote:And whether I'm on little or big endian it should not matter completely from what I understand.


Of course that matters. On a big endian machine, your uint32 occupies 4 bytes in memory, and your memcpy will only fill the most high byte of it. On a little-endian machine, it would fill the least significant byte, and your code would work.

it just should silently overwrite memory passed my Uint32 and thats it. So it should not give any bus error


That depends on what is "silently overwritten". It might as well overwrite the return pc of your function, immediately crashing when you return from it.

jury
Captain Atari
Captain Atari
Posts: 370
Joined: Tue Sep 21, 2004 11:11 am
Location: Poland

Re: Bus error

Postby jury » Thu Dec 27, 2018 4:22 am

Guys, its not the problem with the result ( as nothing is done with it yet ). Its the memcpy which throws the bus error when it tries to copy the pixel different then black. I will check it this evening again and will paste compilable piece of the code.

User avatar
mfro
Atari Super Hero
Atari Super Hero
Posts: 802
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

Re: Bus error

Postby mfro » Thu Dec 27, 2018 7:38 am

From what you show, I would agree to Thorsten: provided the input values are valid, there is nothing wrong with your code that would cause it to crash, except that it will return something else than you expect (the color index in the high byte of a long word with all the lower bits undefined).

I also strongly assume that you do something with the return value and this is the place where the address error happens.


Social Media

     

Return to “C / PASCAL etc.”

Who is online

Users browsing this forum: No registered users and 1 guest