Bug 21192 - Incorrect/Undefined behavior when watching member variables in multi threaded environments
Summary: Incorrect/Undefined behavior when watching member variables in multi threaded...
Status: UNCONFIRMED
Alias: None
Product: gdb
Classification: Unclassified
Component: breakpoints (show other bugs)
Version: 7.11.1
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-02-22 03:47 UTC by ubergotenks
Modified: 2017-02-22 19:45 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description ubergotenks 2017-02-22 03:47:51 UTC
When attempting to watch a member variable so that it breaks when written to, normally i would use 'watch <varname>'. This works in single threaded code and for local variables, but in multithreaded code, it will cause undefined behavior, even if the variable is only ever changed in the main thread. Using 'watch this.<varname>' instead solves this issue.

Here is a simple test program using QT that demonstrates this behavior:
//main.cpp
int main(int argc, char* argv[])
{
    QApplication applicationInstance(argc, argv);
    testGDBCrash crasher;
    if (crasher.exec() != QDialog::Accepted)
        return 0;
    return applicationInstance.exec();
}
//testGDBCrash.h
#ifndef TESTGDBCRASH_H
#define TESTGDBCRASH_H
#include <QDialog>
#include <QObject>
class testGDBCrash : public QDialog
{
    Q_OBJECT
public: 
    testGDBCrash(QWidget * parent=0);
    Q_SLOT void TestCrash();
    bool m_foo; 
};
#endif // TESTGDBCRASH_H
//testGDBCrash.cpp
#include "testGDBCrash.h"
#include <QPushButton>
#include <QHBoxLayout>
testGDBCrash::testGDBCrash(QWidget* parent):QDialog(parent)
{
    resize(200,100);
    QHBoxLayout * layout=new QHBoxLayout(this);
    QPushButton * pb=new QPushButton("crash",this);
    layout->addWidget(pb);
    setLayout(layout);
    show();
    m_foo=false;
    
    connect(pb,SIGNAL(clicked()),this,SLOT(TestCrash()));
}
void testGDBCrash::TestCrash()
{
    if(m_foo)
        return;
    m_foo=false;
    m_foo=true;
    m_foo=false;
}

Steps to crash:
1. Run
2. put a breakpoint on line 18 of testGDBCrash.cpp (the if statement)
3. hit the 'crash' button
4. watch m_foo
5. Continue
GDB will either do strange stuff like tell you 'this' isnt defined, or it will just not ever break. Note, changing step 4 to 'watch this.m_foo' will resolve the behavior and work as intended.
Comment 1 Aetf 2017-02-22 19:45:26 UTC
This also affects the machine interface used by KDevelop which get confused when GDB outputs two responses for a single command.

Detailed description can be found at https://bugs.kde.org/show_bug.cgi?id=376595#c15