K
Ken
Hi,
I have a little program running on Linux to draw a status bar with
framebuffer, but it has segment fault after it is run several times,
first time is ok usually, 2nd, 3rd times it produces segmentation
fault core dump, it is caused by the line below, could anyone help how
to fix the issue?
*(fbp + location) = 255; /* has segmentation fault sometimes here */
---------------------------------------------------------------
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <stdlib.h>
inline static unsigned short int make16color(unsigned char r, unsigned
char g, unsigned char b)
{
return (
(((r >> 3) & 31) << 11) |
(((g >> 2) & 63) << 5) |
((b >> 3) & 31) );
}
int main(void) {
int fbfd = 0;
struct fb_var_screeninfo vinfo =
{ .xres=0, .yres=0, .bits_per_pixel=0,
.xoffset=0, .yoffset=0 };
struct fb_fix_screeninfo finfo = { .line_length=0 };
long int screensize = 0;
char *fbp = 0;
unsigned x = 0, y = 0;
int guage_height = 20, step = 10;
unsigned int location = 0;
// Open the file for reading and writing
fbfd = open("/dev/fb0", O_RDWR);
if (!fbfd) {
printf("Error: cannot open framebuffer device.\n");
exit(1);
}
printf("The framebuffer device was opened successfully.\n");
// Get fixed screen information
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
printf("Error reading fixed information.\n");
exit(2);
}
// Get variable screen information
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
printf("Error reading variable information.\n");
exit(3);
}
// Figure out the size of the screen in bytes
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
// Map the device to memory
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE,
MAP_SHARED,
fbfd, 0);
if ((int)fbp == -1) {
printf("Error: failed to map framebuffer device to memory.
\n");
exit(4);
}
printf("The framebuffer device was mapped to memory successfully.
\n");
//set to black color first
memset(fbp, 0, screensize);
//draw rectangle
y = (vinfo.yres - guage_height) / 2 - 2; // Where we are
going to put the pixel
for (x = step - 2; x < vinfo.xres - step + 2; x++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
*(fbp + location) = 255; /* has segmentation fault sometimes
here */
}
y = (vinfo.yres + guage_height) / 2 + 2; // Where we are
going to put the pixel
for (x = step - 2; x < vinfo.xres - step + 2; x++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
*(fbp + location) = 255;
}
x = step - 2;
for (y = (vinfo.yres - guage_height) / 2 - 2; y < (vinfo.yres +
guage_height) / 2 + 2; y++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
*(fbp + location) = 255;
}
x = vinfo.xres - step + 2;
for (y = (vinfo.yres - guage_height) / 2 - 2; y < (vinfo.yres +
guage_height) / 2 + 2; y++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
*(fbp + location) = 255;
}
// Figure out where in memory to put the pixel
for ( x = step; x < vinfo.xres - step; x++ ) {
for ( y = (vinfo.yres - guage_height) / 2; y < (vinfo.yres +
guage_height) / 2; y++ ) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
if ( vinfo.bits_per_pixel == 32 ) {
*(fbp + location) = 100; // Some blue
*(fbp + location + 1) = 15+(x-100)/2; // A little
green
*(fbp + location + 2) = 200-(y-100)/5; // A lot of
red
*(fbp + location + 3) = 0; // No transparency
} else { //assume 16bpp
unsigned char b = 255 * x / (vinfo.xres - step);
unsigned char g = 255; // (x - 100)/6 A little
green
unsigned char r = 255; // A lot of red
unsigned short int t = make16color(r, g, b);
*((unsigned short int*)(fbp + location)) = t;
}
}
usleep(200);
}
//clean framebuffer
munmap(fbp, screensize);
close(fbfd);
return 0;
}
---------------------------------------------------------------
I have a little program running on Linux to draw a status bar with
framebuffer, but it has segment fault after it is run several times,
first time is ok usually, 2nd, 3rd times it produces segmentation
fault core dump, it is caused by the line below, could anyone help how
to fix the issue?
*(fbp + location) = 255; /* has segmentation fault sometimes here */
---------------------------------------------------------------
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <stdlib.h>
inline static unsigned short int make16color(unsigned char r, unsigned
char g, unsigned char b)
{
return (
(((r >> 3) & 31) << 11) |
(((g >> 2) & 63) << 5) |
((b >> 3) & 31) );
}
int main(void) {
int fbfd = 0;
struct fb_var_screeninfo vinfo =
{ .xres=0, .yres=0, .bits_per_pixel=0,
.xoffset=0, .yoffset=0 };
struct fb_fix_screeninfo finfo = { .line_length=0 };
long int screensize = 0;
char *fbp = 0;
unsigned x = 0, y = 0;
int guage_height = 20, step = 10;
unsigned int location = 0;
// Open the file for reading and writing
fbfd = open("/dev/fb0", O_RDWR);
if (!fbfd) {
printf("Error: cannot open framebuffer device.\n");
exit(1);
}
printf("The framebuffer device was opened successfully.\n");
// Get fixed screen information
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
printf("Error reading fixed information.\n");
exit(2);
}
// Get variable screen information
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
printf("Error reading variable information.\n");
exit(3);
}
// Figure out the size of the screen in bytes
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
// Map the device to memory
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE,
MAP_SHARED,
fbfd, 0);
if ((int)fbp == -1) {
printf("Error: failed to map framebuffer device to memory.
\n");
exit(4);
}
printf("The framebuffer device was mapped to memory successfully.
\n");
//set to black color first
memset(fbp, 0, screensize);
//draw rectangle
y = (vinfo.yres - guage_height) / 2 - 2; // Where we are
going to put the pixel
for (x = step - 2; x < vinfo.xres - step + 2; x++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
*(fbp + location) = 255; /* has segmentation fault sometimes
here */
}
y = (vinfo.yres + guage_height) / 2 + 2; // Where we are
going to put the pixel
for (x = step - 2; x < vinfo.xres - step + 2; x++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
*(fbp + location) = 255;
}
x = step - 2;
for (y = (vinfo.yres - guage_height) / 2 - 2; y < (vinfo.yres +
guage_height) / 2 + 2; y++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
*(fbp + location) = 255;
}
x = vinfo.xres - step + 2;
for (y = (vinfo.yres - guage_height) / 2 - 2; y < (vinfo.yres +
guage_height) / 2 + 2; y++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
*(fbp + location) = 255;
}
// Figure out where in memory to put the pixel
for ( x = step; x < vinfo.xres - step; x++ ) {
for ( y = (vinfo.yres - guage_height) / 2; y < (vinfo.yres +
guage_height) / 2; y++ ) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
if ( vinfo.bits_per_pixel == 32 ) {
*(fbp + location) = 100; // Some blue
*(fbp + location + 1) = 15+(x-100)/2; // A little
green
*(fbp + location + 2) = 200-(y-100)/5; // A lot of
red
*(fbp + location + 3) = 0; // No transparency
} else { //assume 16bpp
unsigned char b = 255 * x / (vinfo.xres - step);
unsigned char g = 255; // (x - 100)/6 A little
green
unsigned char r = 255; // A lot of red
unsigned short int t = make16color(r, g, b);
*((unsigned short int*)(fbp + location)) = t;
}
}
usleep(200);
}
//clean framebuffer
munmap(fbp, screensize);
close(fbfd);
return 0;
}
---------------------------------------------------------------