You are not logged in.

Dear visitor, welcome to QtForum.org. If this is your first visit here, please read the Help. It explains in detail how this page works. To use all features of this page, you should consider registering. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

1

Friday, September 25th 2009, 5:37am

Crash on QWidget::update()

Hello all!

I've got an issue that I can't quite figure out. I have a custom widget that displays 16 LEDs on the screen. Each individual LED is either an on or off bitmap. There is a section of code where the update() function is called very rapidly and when this happens XCode tells me I get a EXEC_BAD_ACCESS (it hit's malloc_error_break, where I have a breakpoint set).

Hopefully that makes sense, if anyone has any suggestions that would be wonderful!

Here is the relevant section of the call stack:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
#0	0x95b6128a in malloc_error_break
#1	0x95b62430 in szone_error
#2	0x95b62565 in free_tiny_botch
#3	0x95f77cac in _CFRelease
#4	0x935ab2f2 in HIView::Invalidate
#5	0x9360d1fc in HIView::Invalidate
#6	0x9360d1a9 in HIViewSetNeedsDisplayInRegion
#7	0x0006b0a0 in QWidgetPrivate::update_sys
#8	0x00273e3f in QWidgetPrivate::repaint_sys
#9	0x00112101 in QWidget::update
#10	0x0011218f in QWidget::update
#11	0x0000919f in LEDDevice::Write at LEDDevice.cpp:40


And here is the code that causes the issue:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void LEDDevice::Write( uint32_t address, int count, void *buffer )
{
    if( address == LED_DAT_ADDR )
    {
    ledBar = *(uint16_t *)buffer;
	
	update();
    }
}

void LEDDevice::paintEvent(QPaintEvent *)
{	
	QPainter painter(this);	

	painter.translate(0, 0);
	
	const QImage ledOn = QImage(":/ledOn.bmp");
	const QImage ledOff = QImage(":/ledOff.bmp");
	
	for( int idx = 0; idx < NUM_LEDS; idx++ )
	{		
		const QPoint point = QPoint( idx * ( LED_WIDTH + BORDER_WIDTH ) + BORDER_WIDTH, BORDER_WIDTH );
		
		//Bit set to 1 - LEDs technically inverted
		if( chk_bit( ledBar, (NUM_LEDS - 1) - idx ) == true )
		{
			painter.drawImage(point, ledOff );
		}
		else
		{
			painter.drawImage(point, ledOn );
		}
	}	
}

2

Friday, September 25th 2009, 6:24am

Source code

1
2
const QImage ledOn = QImage(":/ledOn.bmp");
	const QImage ledOff = QImage(":/ledOff.bmp");

Why not QPixmapCache instead or only two QPixmap loaded in the class constructor. QPixmap is optimized for display.
update() function does not repaints the widget immediately. Instead it queues update event to event loop.
You cannot access GUI thread objects (without proper synchronizations) from other threads.
Write an example which will reproduce the error. Maybe with some fake data generator. Then it will be possible to tell something more.
Fighting fire with fire.
Three can keep a secret if two of them are dead.