Results 1 to 5 of 5

Thread: [QThread] ptrace in thread

  1. #1
    Join Date
    Jan 2009
    Posts
    51
    Thanks
    28
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default [QThread] ptrace in thread

    I'm writting an application which will be doing something with memory of other process.
    These actions may take some time, so I decided to place them in another thread.
    Here's the simplified class of this thread:
    Qt Code:
    1. Thread : public QThread{
    2. public:
    3. int pid;
    4. void run();
    5. };
    To copy to clipboard, switch view to plain text mode 
    and run() function:
    Qt Code:
    1. void Thread::run(){
    2. ptrace(PTRACE_ATTACH, pid);
    3. sleep(60);
    4. ptrace(PTRACE_DETACH, pid);
    5. }
    To copy to clipboard, switch view to plain text mode 
    Of course i put those sleep for example only, in my program there are another functions, but it doesn't matter.

    User can start or stop this thread by clicking on buttons - Start, and Cancel.
    I have no problems with starting this thread, here's the simplified code:
    Qt Code:
    1. connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(startThread()));
    2.  
    3. (...)
    4.  
    5. void MainWindow::startThread(){
    6. thread.pid=getPid();
    7. thread.start();
    8. }
    To copy to clipboard, switch view to plain text mode 
    But problem appears, when user clicks on Cancel button.
    Before doing anything with memory of other process it's needed to attach this process.
    As you see, I'm doing it at the beggining of run() function.
    But when process is attached it's impossible to use it - it must be detached first.
    That's why i added the last line to run():
    Qt Code:
    1. ptrace(PTRACE_DETACH, pid);
    To copy to clipboard, switch view to plain text mode 
    But when user clicks Cancel process also need to be detached, so I overloaded terminate() function:
    Qt Code:
    1. void Thread::terminate(){
    2. ptrace(PTRACE_DETACH, pid);
    3. QThread::terminate();
    4. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(stopThread()));
    2.  
    3. (...)
    4.  
    5. void MainWindow::stopThread(){
    6. thread.terminate();
    7. }
    To copy to clipboard, switch view to plain text mode 
    I think that should work fine, but it doesn't.
    When user doesn't click Cancel, 60 seconds passess and process is detaching.
    But when user click Cancel detaching fails.
    How is it possible?
    The same function, called in exactly the same way, and first works but second doesn't.

    Thanks in advance and sorry for bad english!
    Last edited by Macok; 7th February 2009 at 18:55.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: [QThread] ptrace in thread

    I would do it differently. I would not use another thread but instead I would call ::waitpid() with the WNOHANG option to make it return immediately. This would make sure your parent process never hangs on waitpid() and you don't have to use a thread but instead you can use a simple timer that will call waitpid() periodically and emit a signal or post an event whenever waitpid() returns meaningful data. Of course you can still do it with an external thread (again using WNOHANG and starting an event loop for the thread) which will keep your tracing thread responsive all the time. Then there is no need to call terminate() which you should never ever do. Instead just raise a flag or emit a signal or post an event that will be checked by the tracing thread and let it end itself gracefully.

    Here is a variant without threads:
    Qt Code:
    1. QTimer *t = new QTimer(this);
    2. connect(t, SIGNAL(timeout()), this, SLOT(checkWait()));
    3. t->start(1000); // or whatever else you want here
    4. //...
    5. void X::checkWait(){
    6. int status;
    7. int options = WNOHANG|WUNTRACED; // just a guess...
    8. pid_t pid = ::waitpid(child, &status, options);
    9. if(WIFSTOPPED(status)){
    10. // do tracing here or:
    11. emit childStopped(); // connect to this signal in your tracing method
    12. }
    13. }
    To copy to clipboard, switch view to plain text mode 

    Threaded variant:
    Qt Code:
    1. Thread *thread = new Thread(...);
    2. //...
    3. connect(cancelButton, SIGNAL(clicked()), thread, SLOT(quit()));
    4. thread->start();
    5. thread->moveToThread(thread); // change thread affinity of the thread object
    6. //...
    7. void Thread::run(){
    8. // attach trace
    9. QTimer *t = new QTimer(...); // same as above
    10. exec(); // start event loop and block
    11. // detach trace
    12. }
    To copy to clipboard, switch view to plain text mode 

  3. The following user says thank you to wysota for this useful post:

    Macok (8th February 2009)

  4. #3
    Join Date
    Jan 2009
    Posts
    51
    Thanks
    28
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: [QThread] ptrace in thread

    Thanks for the reply.
    I don't understand your method, so I'll better stay with the threaded variant
    Maybe I write something more about my program:
    It'll be memory addresses searcher, something like CheatEngine for windows.
    User puts process name and value, then program scan whole memory of the process and tells user the memory addresses when this value is placed.

    Your idea with timer seems to be good, but I have a problem with connecting timeout() signal to a proper slot.
    Here's the code:
    Qt Code:
    1. //this function is called when user click Start button
    2. void MainWindow::startThread(){
    3. ui->pushButton_2->setEnabled(true);
    4. thread=new Thread;
    5. connect(ui->pushButton_2, SIGNAL(clicked()), thread, SLOT(quit()));
    6. thread->pid=proc[ui->comboBox->currentIndex()].pid;
    7. thread->start();
    8. thread->moveToThread(thread);
    9. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. void Thread::run(){
    2. ptrace(PTRACE_ATTACH, pid, 0, 0);
    3. ::wait();
    4.  
    5. QTimer *t=new QTimer(this);
    6.  
    7. connect(t, SIGNAL(timeout()), this, SLOT(checkWait()));
    8. t->start(1000);
    9. exec();
    10. ptrace(PTRACE_DETACH, pid, 0, 0);
    11. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. void Thread::checkWait(){
    2. //Here I will place memory scanning
    3. }
    To copy to clipboard, switch view to plain text mode 
    It's compiling without any warnings, but when I run program it write out that in the console:
    Object::connect: No such slot QThread::checkWait()
    What's wrong?

    PS. Why do you use dynamic memory allocation when creating Thread object (thread=new Thread)?
    What diffrence does it make?

  5. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,372
    Thanks
    3
    Thanked 5,019 Times in 4,795 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: [QThread] ptrace in thread

    Quote Originally Posted by Macok View Post
    Qt Code:
    1. void Thread::checkWait(){
    2. //Here I will place memory scanning
    3. }
    To copy to clipboard, switch view to plain text mode 
    Oh, I see your usecase is a bit different. In that case read this article:
    http://doc.trolltech.com/qq/qq27-responsive-guis.html

    By the way, the error means you didn't declare checkWait() as a slot in your class or you forgot the Q_OBJECT macro.

    PS. Why do you use dynamic memory allocation when creating Thread object (thread=new Thread)?
    What diffrence does it make?
    So that it doesn't get destroyed when the method where it is constructed runs out of scope.

  6. The following user says thank you to wysota for this useful post:

    Macok (8th February 2009)

  7. #5
    Join Date
    Jan 2009
    Posts
    51
    Thanks
    28
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: [QThread] ptrace in thread

    Omg, I declared checkWait() as public, instead public slot.
    Thanks a lot!

Similar Threads

  1. GUI and non-GUI thread problem
    By dimaz in forum Qt Programming
    Replies: 3
    Last Post: 18th September 2008, 21:25
  2. Thread, Timer and Socket. Comuication problem
    By ^NyAw^ in forum Qt Programming
    Replies: 6
    Last Post: 17th January 2008, 16:48
  3. KDE/QWT doubt on debian sarge
    By hildebrand in forum KDE Forum
    Replies: 13
    Last Post: 25th April 2007, 06:13
  4. Replies: 10
    Last Post: 20th March 2007, 22:19
  5. Problem closing a QMainWindow in Qt4.2
    By ian in forum Qt Programming
    Replies: 11
    Last Post: 17th October 2006, 00:49

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.