PDA

View Full Version : Thread problem with windows



vratojr
13th June 2006, 12:11
Hi all, I have a "strange" problem with my program when running it under linux...The programs works this way: I have GUI that, after pressing a button, starts a thread. this programs works fine under linux but crashes under windows... When I press the button. The "strange" adjective comes from the fact that this program used to work under windows also but now (after I reinstalled linux,vmware and windows) it doesn't. AFAIK the only big change i've done is the upgrade to Qt 4.1.3 from 4.1.1 (or 4.1.2 I don't remember)...
Any hint?

Thanks.

wysota
13th June 2006, 12:20
Debug your app and see where the crash occurs.

vratojr
13th June 2006, 12:26
Well,it crashes when i call start()... I don't know more precisely, I have no debugger under windows, right now I'm trying to install the eclipse framework that seems nice. Oh,I'm unsing minGW. Sorry if it seems an "I_don't_want_to_bother_myself_so_I_ask_you" question but I am a bit puzzled about the behavior of a program that runned well... ;)

wysota
13th June 2006, 14:24
Well,it crashes when i call start()... I don't know more precisely, I have no debugger under windows, right now I'm trying to install the eclipse framework that seems nice. Oh,I'm unsing minGW. Sorry if it seems an "I_don't_want_to_bother_myself_so_I_ask_you" question but I am a bit puzzled about the behavior of a program that runned well... ;)

Use gdb to debug your app.

fullmetalcoder
13th June 2006, 14:30
Use gdb to debug your app.
gdb is powerfull but kinda hard to use. Dowload DrMingw (http://jrfonseca.planetaclix.pt/projects/gnu-win32/software/drmingw/index.html#id2253291), set it as default window$ debugger and you'll get the call stack when it crash. That could help, huh?

wysota
13th June 2006, 14:32
gdb is powerfull but kinda hard to use. Dowload DrMingw, set it as default window$ debuggerand you'll get the call stack when it crash. That could help, huh?

What's so hard in a sequence of:
$ gdb appname
run
bt
quit

greencastor
13th June 2006, 16:39
The problem with gdb is that sometimes it could be interesting to see the functions called BEFORE the crash and not only the stack. In my own problem (another post), I know where it crashes (and, as it is an assert, it was not necessary) but I don't know why it crashes.
I remember of another program, the same as gdb but with graphics, it sounded like ddd ...:eek:

wysota
13th June 2006, 17:02
You can do the same with gdb. But in 90% of cases it's enough to have a backtrace to see what went wrong (a vast number of segfaults is caused by dereferencing a null pointer or corrupting the stack frame). In this case the most important is to see where in Qt library the app crashes and what was the call chain that led to the crash.

vratojr
14th June 2006, 09:22
Ok,I have compiled the debug libraries to finally debug the program and now the program works!!! Hrmmm.......bah......:(

wysota
14th June 2006, 10:02
Ok,I have compiled the debug libraries to finally debug the program and now the program works!!! Hrmmm.......bah......:(

Try again with release mode. Just make sure your project is cleaned and recompiled from scratch.

fullmetalcoder
14th June 2006, 16:04
What's so hard in a sequence of:
$ gdb appname
run
bt
quit
Dunno what's hard but I know what's driving me mad. When I use such a command I only get a call stack, and none of the graphical interface to gdb allow me to see the debug symbols from the shared librarieslinked to my program...

vratojr
14th June 2006, 16:45
Well, in fact the in release mode the programs doens't work, it simply stalls as before. The problem is that I don't know how to debug it since it doens't crashes but stalls. Moreover,as I said the debug version runs correctly... How could it be?

fullmetalcoder
15th June 2006, 11:11
Do it the old way ;) : uses QMessageBox::warning(), filled with crucial paramteres at points you consider as potentially problematic... I've always worked that way since I switched to Linux where, even in release mode, qDebug() works fine...:)

wysota
15th June 2006, 11:27
Well, in fact the in release mode the programs doens't work, it simply stalls as before. The problem is that I don't know how to debug it since it doens't crashes but stalls. Moreover,as I said the debug version runs correctly... How could it be?

It could be that you rely on some condition which behaves differently between debug and release (for example debug might be setting all int variables to '0' and release might leave it uninitialised -- of course I don't say that it actually happens).

vratojr
15th June 2006, 12:47
Well I found the problem... But still I don't know why it happens... From the father of UserThread I call:


if(!userThread->isRunning()){
userThread->start();
while(!userThread->inizializzato()); //Stalls here
}
with

void UserThread::run(){
//.......
_inizializzato=TRUE;

exec();
}

bool UserThread::inizializzato() const {return _inizializzato;}

the program stalls in the "while".Now, if i run in debug mode, _inizializzato is correcly set up to TRUE and the program doesn't stall, in release mode, _inizializzato is never set to TRUE (_inzializzato is set to FALSE in the constructor) and the programs stalls.
I suppose I can delete the problem if I wait for a signal coming from the thread instead of using that while but... Is this mine a bad style of programming?
Thanks for the attention and the patience;)!

wysota
15th June 2006, 13:43
Is this mine a bad style of programming?

Yes. You should use a QWaitCondition here.

vratojr
16th June 2006, 09:20
Thanks, but if I am not too annoying, could you explain me why I can't use the while?Is this because I continuosly pool on a member of another thread and this generates a conflict with the owner thread? I mean, theoretically I could resolve this also by placing a mutexlocker in run() and in inzializzato() ?
Excuse me but I want also to learn!;)

wysota
16th June 2006, 09:34
Thanks, but if I am not too annoying, could you explain me why I can't use the while?Is this because I continuosly pool on a member of another thread and this generates a conflict with the owner thread?
It's because you are waiting in a so called "busy loop".
Try to compile such program:

int main(){ while(1); return 0; }
Run it and see the CPU usage. You'll notice that it'll go up to 100%.
Now compile and run this one:

int main(){ while(1) sleep(0); return 0; }
This one won't eat up all your CPU power (and it'll be easier to kill such a task) -- this is called "semi-busy loop". The only difference between those two applications is that the second one forces a context switch of the processor (changes the "active" process) allowing other applications to run. As a result all your applications will run more efficiently.
The "next step" is to use some kind of lock which will suspend your process (thread) and wake it up only where a certain condition is met. A pseudocode follows:

//...
// instead of while(!someEventHappened); -- busy loop
// or instead of while(!someEventHappend) sleep(0); -- semi busy loop
goToSleepUntil(someEventHappend);
doSomething();
//...

I mean, theoretically I could resolve this also by placing a mutexlocker in run() and in inzializzato()?
I think so (depends where exactly you want to put it), but using a wait condition is more "elegant".


Excuse me but I want also to learn!;)
Good for you :cool: