Results 1 to 7 of 7

Thread: Issue when passing a pointer to a SLOT from a SIGNAL with QObject::connect

  1. #1
    Join Date
    Jan 2021
    Posts
    4
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Unix/X11

    Post Issue when passing a pointer to a SLOT from a SIGNAL with QObject::connect

    Dear All,

    I am using connect in order to send a SIGNAL with 2 variables towards a SLOT. The connect looks like this:

    Qt Code:
    1. const bool connected = QObject::connect(this, &iVoiceCom:: stateCallChangedT,this, &iVoiceCom:: onCallStateChanged, Qt::QueuedConnection);
    2. qDebug() << "Connection established?" << connected;
    To copy to clipboard, switch view to plain text mode 

    In the main I am defining the variables to be passed from
    Qt Code:
    1. qRegisterMetaType<pjsua_call_id>("pjsua_call_id");
    2. qRegisterMetaType<pjsip_event*>("pjsip_event");
    To copy to clipboard, switch view to plain text mode 

    Then in this function I run the emit with the 2 varialbes, one int and a pointer:

    Qt Code:
    1. void iVoiceCom:: on_call_state(pjsua_call_id call_id, pjsip_event *e)
    2. {
    3. //callStateChanged(call_id,e);
    4. emit stateCallChangedT(call_id, e);
    5. }
    To copy to clipboard, switch view to plain text mode 

    The SIGNAL is emited OK and the function below is run, but the "e" pointer is passed until a certain point

    Qt Code:
    1. e->type OK
    2. e->body.tsx_state.type OK
    To copy to clipboard, switch view to plain text mode 

    BUT

    Qt Code:
    1. e->body.tsx_state.src.rdata->msg_info.msg; is LOST and I do not understand why, the back trace from gdb:
    To copy to clipboard, switch view to plain text mode 

    Program received signal SIGSEGV, Segmentation fault.
    0x00000000004226da in iVoiceCom:: onCallStateChanged (this=0x7fffffffc9d0, call_id=0, e=0x7fffc7ffdfe0) at iVoiceCom.cpp:1605
    1605 int code = msg->line.status.code;
    (gdb) p e->type
    $1 = PJSIP_EVENT_TSX_STATE
    (gdb) p e->body.tsx_state.type
    $2 = PJSIP_EVENT_RX_MSG
    (gdb) p e->body.tsx_state.src.rdata->msg_info
    $7 = {msg_buf = 0x0, len = 0, msg = 0x0, info = 0x0, cid = 0x0, from = 0x0, to = 0x0, via = 0x0, cseq = 0x0, max_fwd = 0x0, route = 0x0, record_route = 0x0, ctype = 0x0, clen = 0x0, require = 0x0,
    supported = 0x0, parse_err = {prev = 0x0, next = 0x0, except_code = 0, line = 0, col = 0, hname = {ptr = 0x0, slen = 0}}}
    (gdb)

    The slot/function:
    Qt Code:
    1. void iVoiceCom:: onCallStateChanged(pjsua_call_id call_id, pjsip_event *e)
    2. {
    3. ....
    4. if (e->type == PJSIP_EVENT_TSX_STATE)
    5. {
    6. pjsip_msg *msg;
    7.  
    8. if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
    9. {
    10. msg = e->body.tsx_state.src.rdata->msg_info.msg;
    11. }
    12. else {
    13. msg = e->body.tsx_state.src.tdata->msg;
    14. }
    15.  
    16. int code = msg->line.status.code;
    17. ...
    18. }
    To copy to clipboard, switch view to plain text mode 

    Can you please help me to understand what am I doing wrong.

    Thank You!
    Teo

  2. #2
    Join Date
    Jan 2006
    Location
    Bremen, Germany
    Posts
    554
    Thanked 86 Times in 81 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Issue when passing a pointer to a SLOT from a SIGNAL with QObject::connect

    Why do you use a queued connection? Are you sure the pointer is still valid when the slot is executed? I would guess no.

  3. #3
    Join Date
    Jan 2021
    Posts
    4
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: Issue when passing a pointer to a SLOT from a SIGNAL with QObject::connect

    Thank You for your reply Christian!

    I have tried with: const bool connected = QObject::connect(this, &iVoiceCom::stateCallChangedT,this, &iVoiceCom:nCallStateChanged, Qt:irectConnection); and also calling directly the function and I receive:

    ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x7fff780008c0. Receiver 'pushButton_call' (of type 'QPushButton') was created in thread 0x0x8cdad0", file /home/teodor/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp, line 578

    I have one more thread that is managed by boost, that I am still trying to understand how to access and send my connection towards it but I have not managed yet.

    From this function I am trying to change the GUI button, when I use "ui->pushButton_call->setText(action);" everything works but when I try to run setStyleSheet and change the color I get the error above.

    Qt Code:
    1. ui->pushButton_call->setText("End");
    2. ui->pushButton_call->setStyleSheet("color: black;background-color: #c7cece;");
    To copy to clipboard, switch view to plain text mode 

    I still do not get the whole picture of the connect and boost, I will read some more this days.

    For now I do not know how to check if the pointer is still valid but more important is to figure out how to keep it valid when until the function has finished the execution or add it to the right thread ...

    It is strage for me that the e->body.tsx_state.type pointer is OK but the rest (e->body.tsx_state.src.rdata->msg_info.msg) is not valid.

    Thank You!
    Teo

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,246
    Thanks
    304
    Thanked 866 Times in 853 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Issue when passing a pointer to a SLOT from a SIGNAL with QObject::connect

    For now I do not know how to check if the pointer is still valid
    It is good practice to either do a runtime check like this or to add an assert for debugging purposes like this:

    Qt Code:
    1. if ( e != nullptr )
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. assert( e != nullptr )
    To copy to clipboard, switch view to plain text mode 

    This doesn't help if the pointer is non-null but also not valid (in other words, you pass a pointer variable that has not been initialized).

    The assert will result in your program stopping at that point when you run it in the debugger. From that point, you can use the debugger to trace back through the call stack to find where things went wrong.

    If you don't know how to use a debugger, you have to learn. The dump you get from a SEGFAULT when running a realease mode version of your program is pretty much useless for debugging purposes.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. The following user says thank you to d_stranz for this useful post:

    teodor (11th January 2021)

  6. #5
    Join Date
    Jan 2006
    Location
    Bremen, Germany
    Posts
    554
    Thanked 86 Times in 81 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Issue when passing a pointer to a SLOT from a SIGNAL with QObject::connect

    Checking for nullptr doesn't help here since the pointer for sure is a dangling pointer due to the QueuedConnection. Either pass the value or don't use a Queued Connection or make sure the pointer is valid until the slot is executed.

  7. The following 2 users say thank you to ChristianEhrlicher for this useful post:

    d_stranz (9th January 2021), teodor (11th January 2021)

  8. #6
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Issue when passing a pointer to a SLOT from a SIGNAL with QObject::connect

    Quote Originally Posted by teodopjsip_eventr View Post
    It is strage for me that the e->body.tsx_state.type pointer is OK but the rest (e->body.tsx_state.src.rdata->msg_info.msg) is not valid.
    e points at a pjsip_event object that contains a "body" member structure that contains a "tsx_state" structure.
    e->body.tsx_state.type is not a pointer, it is an integer member of the "tsx_state" structure and will have a value.

    The "tsx_state" structure contains child "src" structure with a pointer members "rdata" and "tdata" pointing to other structures. Either or both of these pointers can be either null or pointing at random memory at the time of access. You copy the value of the "msg" pointer from either the "rdata" or "tdata" objects (which might just be random memory). This pointer can be either null or pointing at random memory at the time of access. When you dereference that pointer it is not valid.

    Given that the slot and signal are from different threads the objects being pointed at can become invalid even if they were valid at the time they were received at the slot.

    I suggest that you consider moving this logic from the slot into the routine emitting the signal and then pass the "code" (or whatever else you want from these structures) as the parameters of the signal. If any of those things is a C-string then construct a QString from it and pass that (not the char*).

  9. The following user says thank you to ChrisW67 for this useful post:

    teodor (11th January 2021)

  10. #7
    Join Date
    Jan 2021
    Posts
    4
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: Issue when passing a pointer to a SLOT from a SIGNAL with QObject::connect

    WOW ChrisW67, you kind of nailed it big time. Thank You for making some light into my problem!

    You are right and your idea worked, I have moved the logic directly into the function and emit the signal only with the needed parameters, no pointers that can be affected or dangling.

    Adding the solution maybe it helps someone else:

    Qt Code:
    1. qRegisterMetaType<pjsua_call_id>("pjsua_call_id");
    2. qRegisterMetaType<std::string>("std::string");
    3. qRegisterMetaType<QTextCursor>("QTextCursor");
    4.  
    5. const bool connected2 = QObject::connect(this, SIGNAL(signalCallStateB(std::string,QString, pjsua_call_id, QString)), this, SLOT(slotUpdateButtons(std::string,QString, pjsua_call_id, QString)));
    6. qDebug() << "Connection established?" << connected2;
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. void iVoiceCom:: on_call_state(pjsua_call_id call_id, pjsip_event *e)
    2. {
    3. ...
    4. if (e->type == PJSIP_EVENT_TSX_STATE)
    5. {
    6. pjsip_msg *msg;
    7.  
    8. if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG)
    9. {
    10. msg = e->body.tsx_state.src.rdata->msg_info.msg;
    11. }
    12. else {
    13. msg = e->body.tsx_state.src.tdata->msg;
    14. }
    15.  
    16. int code = msg->line.status.code;
    17. ....
    18. emit signalCallStateB(extNumber,"End", call_id, "color: black;background-color: #4287f5;");
    19. }
    To copy to clipboard, switch view to plain text mode 

    and in the slot I just update the button with the parameters:

    Qt Code:
    1. void iVoiceCom::slotUpdateButtons(std::string extNumber,QString action, pjsua_call_id call_id, QString style)
    2. {
    3. ....
    4. ui->pushButton_call->setText(action);
    5. ui->pushButton_call->setStyleSheet(style);
    6. ...
    7. }
    To copy to clipboard, switch view to plain text mode 

    Thank You ALL for your help!

    I had this problem for a week now and it was great to have your help! I still have a lot to learn ...

Similar Threads

  1. Replies: 0
    Last Post: 9th January 2021, 14:07
  2. Replies: 1
    Last Post: 14th August 2014, 18:08
  3. Passing pointer to object that emits a signal
    By Gadgetman53 in forum Qt Programming
    Replies: 2
    Last Post: 17th April 2011, 22:04
  4. qt signal/slot auto-connect issue
    By parnedo in forum Qt Programming
    Replies: 9
    Last Post: 16th July 2009, 13:55
  5. Passing a pointer in Signal/Slot Connection
    By mclark in forum Qt Programming
    Replies: 4
    Last Post: 6th November 2007, 20:04

Tags for this Thread

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.