Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
Posts: 139
Registered: ‎05-24-2011
My Device: Z30 running 10.2 and Playbook 4GLTE running OS2.1
My Carrier: rogers
Accepted Solution

RenderFence?

Hi gang,

 

While running my app through momentics, every time i quit the app, i get the following error:

 

Process 286040532 (myApp) terminated SIGSEGV code=1 fltno=11 ip=79599bea(/base/usr/lib/libbbcascades.so.1@_ZN2bb8cascades11RenderFence9setRaisedEb+0x3249) mapaddr=00199bea. ref=081039bc bdslot=1

 I'm not sure how to diagnose this or track down why it crashes instead of exiting cleanly.

 

any suggestions on where to start?

 

thanks,

 

J

bron: a cron-like scheduler for BlackBerry 10
http://apps.oddelement.com
Developer
Posts: 6,152
Registered: ‎07-05-2012
My Device: Playbook, Dev Alpha C, Z10 LE, Z30
My Carrier: Orange

Re: RenderFence?

Most of the time this indicates that you are accessing an invalid part of memory usually due to an invalid pointer or memory allocation problem.

 

This one happens in the Cascades library so I recommend checking that all your controls have their parent set correctly and you are not inadvertently removing one but leaving the parent object still believing it is connected.

 


If you've been helped click on Like Button, if you've been saved buy the app. :smileyhappy:

Developer of stokLocker, Sympatico and Super Sentences.
Developer
Posts: 139
Registered: ‎05-24-2011
My Device: Z30 running 10.2 and Playbook 4GLTE running OS2.1
My Carrier: rogers

Re: RenderFence?

Thanks!

 

when you say controls, do you mean controls on the QML pages?

 

I have a few c++ classes as well, lots of pointers floating around too...  I'm not totally clear on how to check that the parents are set correctly.

 

is there any way to narrow down which object or control is causing this?

 

thx,


J

bron: a cron-like scheduler for BlackBerry 10
http://apps.oddelement.com
Developer
Posts: 6,152
Registered: ‎07-05-2012
My Device: Playbook, Dev Alpha C, Z10 LE, Z30
My Carrier: Orange

Re: RenderFence?

Yes objects or controls within QML pages whether physically present in the QML code or added dynamically by C++ functions. Within the QML files the parent will automatically be set to the container above, but in your C++ if you add your own it can be missed.


If you've been helped click on Like Button, if you've been saved buy the app. :smileyhappy:

Developer of stokLocker, Sympatico and Super Sentences.
Developer
Posts: 139
Registered: ‎05-24-2011
My Device: Z30 running 10.2 and Playbook 4GLTE running OS2.1
My Carrier: rogers

Re: RenderFence?

ok, thanks.  I have gone through the code and anywhere that i create a custom c++ object, i setParent(this).  There is one exception.  I have a class called Job.  I set some properties on instances of this class, and then push them into a QThread, like this:

 

QThread * thread = new QThread(this);
//	qWarning() << "--> thread is: " << thread;
	thread->setObjectName(thisTask->taskName());
	int runInSecs;
	runInSecs = thisTask->nextRun() - QDateTime::currentDateTime().toTime_t();
	Job * thisJob = new Job();    // <-------------------------------------no parent set here
	thisJob->setCommand(thisTask->command());
	thisJob->setInterval(runInSecs);
	thisJob->setTaskName(thisTask->taskName());
	thisJob->setObjectName(thisTask->taskName());
	thisJob->setTaskLabel(thisTask->taskLabel());
	thisJob->moveToThread(thread);

 When I try to set a parent on thisJob, I get an error at the moveToThread() call saying that an object with a parent can't be moved.

 

to compensate, I try to catch any scheduled jobs in the WorkManager deconstructor like this:

 

WorkManager::~WorkManager() {
	QList<QThread *> threads = findChildren<QThread *>();
	if (!threads.isEmpty()) {
		for (int i = 0; i < threads.size(); i++) {
			qWarning() << "WorkManager::~WorkManager() list of threads: " << threads;
			threads.at(i)->quit();
		}
	}
}

 I *think* the application is terminating before the last scheduled job (which is in it's own thread)  is finished.  I'm not sure how to quit() the thread and wait for it to clean up though... 

 

I can't find any other cases where parents are not set other than this one.

 

FWIW, I have connected the thread's finished() signal to it's own deleteLater() slot like so:

 

	result = connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
	Q_ASSERT(result);

 is there a signal/slot I need to connect perhaps that I'm missing?

 

thanks!

 

J

 

bron: a cron-like scheduler for BlackBerry 10
http://apps.oddelement.com
Developer
Posts: 6,152
Registered: ‎07-05-2012
My Device: Playbook, Dev Alpha C, Z10 LE, Z30
My Carrier: Orange

Re: RenderFence?

Threads do not need to be parented as they won't be connected to any UIObject and your code will need to make sure the thread is closed off before shutting down.
What you have done is correct with connecting the finished signal, you can delay the closing of the app to make sure that the thread has a chance to stop and close off...

http://developer.blackberry.com/native/documentation/cascades/dev/fundamentals/

Take a look at the 'Closing your application' section.

You seem to be a pretty knowledgeable developer to me, so I'm surprised you can't use the debugger to track this down?
Did you not get anything useful from the stack backtrace, or is that how you know it is definitely in the app exit/clearing up of the QML code?
Are you aware of black box testing, another approach to seeing if you can instantiate and delete your classes without issue?

But I would first of all eliminate the threading code (comment it out) as you obviously feel this may be the culprit and see if the app still crashes.
Then work from there.



If you've been helped click on Like Button, if you've been saved buy the app. :smileyhappy:

Developer of stokLocker, Sympatico and Super Sentences.
Developer
Posts: 139
Registered: ‎05-24-2011
My Device: Z30 running 10.2 and Playbook 4GLTE running OS2.1
My Carrier: rogers

Re: RenderFence?

[ Edited ]

Thanks for the compliment!  I still consider myself pretty fresh as far as C++ goes, and i'll openly admit that my debugging skills are not all that deep.  I'll try to get better with the debug perspective and see if i can narrow it down.  Just ran through in the debug view a few times and i just can't tell what's going on.   I still suspect that on shutdown, there's still at least one Job scheduled in a thread and sending it the quit() isn't actually stopping it.  For reference, the thread uses a singleShot timer to sleep until it's time for it to wake up as in:

 

void Job::process() {

	QTimer::singleShot(m_interval * 1000, this, SLOT(runJob()));

}

 When the singleShot fires, the thread calls the runJob() to actually do some work.

 

I'm thinking that quit() won't break this singleShot.

 

Looking at the link you provided, I think what I'll try is to setTerminationEnabled(), and then in the deconstructor for the WorkManager class, I'll thread.at(i)->terminate().

 

EDIT: or maybe, leave the quit() in the deconstructor, and call terminate() in the Application's manualExit() signal handler I'm going to write.  that might be "nicer".

 

thanks for the help so far!

bron: a cron-like scheduler for BlackBerry 10
http://apps.oddelement.com
Developer
Posts: 139
Registered: ‎05-24-2011
My Device: Z30 running 10.2 and Playbook 4GLTE running OS2.1
My Carrier: rogers

Re: RenderFence?

[ Edited ]

fixed!

 

I created a onManualExit() signal handler which finds the WorkManager object and calls a killThreads() function.

 

void WorkManager::killThreads() {
	QList<QThread *> threads = findChildren<QThread *>();
	if (!threads.isEmpty()) {
		qWarning() << "---------> threads size is : " << threads.size();
		for (int i = 0; i < threads.size(); i++) {
			qWarning() << "WorkManager::~WorkManager() list of threads: " << threads;
			qWarning() << "----> i is: " << i;
			threads.at(i)->terminate();
		}
	}
}

 This is largely the same code as i was calling in the deconstructor to begin with, except calling 'threads.at(i).terminate()' instead of 'threads.at(i).quit().'

 

in the ApplicationUI constructor, I connect the manualExit() signal to this onManualExit() signal handler:

 

    result = connect(app, SIGNAL(manualExit()), this, SLOT(onManualExit()));
    Q_ASSERT(result);

 In the main.cpp file, I setAutoExit(false) and manually app.quit() like so:

 

Q_DECL_EXPORT int main(int argc, char **argv)
{
    Application app(argc, argv);
        qInstallMsgHandler(myMessageOutput);  // added by me
    // Create the Application UI object, this is where the main.qml file
    // is loaded and the application scene is set.
    new ApplicationUI(&app);
    app.setAutoExit(false);
    // Enter the application main event loop.
    return Application::exec();
    app.quit();
}

 

so far, no segfaults on closing the app.  yay!

 

EDIT: I think i'm comfortable terminate()'ing the thread because it's largely just sleeping.  I'm guessing that there is potential for some problems even though the work the thread does when it wakes up is safe to throw away... i will ponder on this a little more.

 

 

thank you BBSJdevv for all your help!

 

...now I just need more practice with the debugger!  (pointers to good references would be appreciated!)

bron: a cron-like scheduler for BlackBerry 10
http://apps.oddelement.com
Developer
Posts: 6,152
Registered: ‎07-05-2012
My Device: Playbook, Dev Alpha C, Z10 LE, Z30
My Carrier: Orange

Re: RenderFence?

Glad you solved it and in checking the parenting of your C++ objects you've probably elimated some memory leaks as well. :smileyhappy:

 

As for debugging I haven't found much on Momentics itself but these may help...

 

http://agile.csc.ncsu.edu/SEMaterials/tutorials/eclipse-debugger/

 

http://help.eclipse.org/kepler/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Freference%2Fviews%2Fdeb...

 

Yes it mostly talks about Java but the debugging methodology will be basically the same.

 

Don't forget to set the solution on one of the posts, I suggest your last one.

 


If you've been helped click on Like Button, if you've been saved buy the app. :smileyhappy:

Developer of stokLocker, Sympatico and Super Sentences.
Developer
Posts: 139
Registered: ‎05-24-2011
My Device: Z30 running 10.2 and Playbook 4GLTE running OS2.1
My Carrier: rogers

Re: RenderFence?

I set one as the solution, thank you again.

 

one quick update.  It seems that quit() wasn't working exactly as i expected in the code above.  the active frame would disappear, but the app kept running and couldn't be killed.  only way to get rid of it was reboot - even device manager wouldn't kill it. 

 

*sidebar: it's like a headless app!  No window, but the app was still running.

 

so i changed from quit() to exit(0).  first, i think the quit() was in the wrong place, so i removed that from main.cpp.

 

    // Enter the application main event loop.
    return Application::exec();
    // app.quit();

 then, in my ApplicationUI::smileysurprised:nManualExit(), i clean up the threads and call exit(0);

 

void ApplicationUI::onManualExit() {
	WorkManager * wm;
        wm = this->parent()->findChild<WorkManager *>("myWorkManager");
	wm->killThreads();
	qWarning() << "ApplicationUI::onManualExit(), called killThreads(), about to call exit()...";
	exit(0);
}

 This seems to work better than quit().

 

anyway, thanks again for all your help - and the links!

 

bron: a cron-like scheduler for BlackBerry 10
http://apps.oddelement.com