Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Apr 2016 14:39:21 +0930
From:      Shane Ambler <FreeBSD@ShaneWare.Biz>
To:        Dimitry Andric <dim@FreeBSD.org>
Cc:        FreeBSD-ports <freebsd-ports@freebsd.org>
Subject:   Re: Need some help with c++/qt5 code
Message-ID:  <57107781.7040102@ShaneWare.Biz>
In-Reply-To: <CC7B253B-DE3B-4049-96D8-A06DB52A0346@FreeBSD.org>
References:  <570F85E3.6060000@ShaneWare.Biz> <CC7B253B-DE3B-4049-96D8-A06DB52A0346@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 15/04/2016 08:02, Dimitry Andric wrote:
> On 14 Apr 2016, at 13:58, Shane Ambler <FreeBSD@ShaneWare.Biz> wrote:
>>
>> Hi there, while I am comfortable with c and python, I only know a little
>> c++ and could use some help.
> ...
>> class TPanelFactory
>> {
>>     QString m_panelType;
>>     static QMap<QString, TPanelFactory *> m_table;
>>
>> public:
>>     TPanelFactory(QString panelType);
>>     ~TPanelFactory();
>>
>>     QString getPanelType() const { return m_panelType; }
>>
>>     virtual void initialize(TPanel *panel) = 0;
>>     virtual TPanel *createPanel(QWidget *parent);
>>     static TPanel *createPanel(QWidget *parent, QString panelType);
>> };
>>
>> m_table is then in the source file as
>>
>> QMap<QString, TPanelFactory *> TPanelFactory::m_table;
>>
>> The segfault happens in the constructor -
>>
>> TPanelFactory::TPanelFactory(QString panelType)
>>     : m_panelType(panelType)
>> {
>>     assert(m_table.count(panelType) == 0);
>>     m_table[m_panelType] = this;
>> }
>>
>> the last line causes the segfault, if I comment it out then main() is
>> entered, but I expect removing that line will bite back soon enough.
>>
>> How can I get this working?
>>
>> Why would this fail on FreeBSD but not OSX or windows?
>
> Most likely the program depends on the initialization order of global
> constructors.  This is bad practice, and should be avoided.
>

> So what's the value of m_table at this point?  It looks a lot like it
> is still uninitialized.

Yes uninitialised sounds right - what is the right way to fix this?

I get non-zero values for the address of each variable there, but while
they may be allocated I don't think they are initialised as a call to
m_table.count() will cause a segfault.

TPanelFactory::TPanelFactory(QString panelType)
     : m_panelType(panelType)
{
     assert(m_table.count(panelType) == 0);
     std::cout << "m_table.count is " << m_table.count(panelType) << 
std::endl;
     std::cout << "TPanelFactory::m_table is at " << 
&TPanelFactory::m_table << std::endl;
     std::cout << "this is at " << this << std::endl;
     std::cout << "panelType is at " << &panelType << std::endl;
     std::cout << "m_panelType is at " << &m_panelType << std::endl;
     m_table[m_panelType] = this;
}

The output with m_table.count() prevents the other output lines
running, without the m_table.count() line, the others can output
before the segfault.

Without the m_table.count() line -
% ./opentoonz
TPanelFactory::m_table is at 0xc39568
this is at 0xc3a628
panelType is at 0x7fffffffd408
m_panelType is at 0xc3a630
Segmentation fault

With the m_table.count() line -
% lldb opentoonz
Current executable set to 'opentoonz' (x86_64).
(lldb) run
Process 56499 launching
Process 56499 stopped
(lldb) Process 56499 launched: 
'/home/shane/Projects/opentoonz/test_install/bin/opentoonz' (x86_64)
Process 56499 stopped
* (lldb) thread #1: tid = 101441, 0x00000000004f2d7f 
opentoonz`QMapData<QString, TPanelFactory*>::nodeRange(QString const&, 
QMapNode<QString, TPanelFactory*>**, QMapNode<QString, 
TPanelFactory*>**) + 31, stop reason = invalid address (fault address: 0x10)
     frame #0: 0x00000000004f2d7f opentoonz`QMapData<QString, 
TPanelFactory*>::nodeRange(QString const&, QMapNode<QString, 
TPanelFactory*>**, QMapNode<QString, TPanelFactory*>**) + 31
opentoonz`QMapData<QString, TPanelFactory*>::nodeRange(QString const&, 
QMapNode<QString, TPanelFactory*>**, QMapNode<QString, 
TPanelFactory*>**) + 31:
-> 0x4f2d7f:  movq   0x10(%r14), %r15
    0x4f2d83:  addq   $0x8, %r14
    0x4f2d87:  testq  %r15, %r15
    0x4f2d8a:  je     0x4f2e6a                  ; QMapData<QString, 
TPanelFactory*>::nodeRange(QString const&, QMapNode<QString, 
TPanelFactory*>**, QMapNode<QString, TPanelFactory*>**) + 266
(lldb) bt
* thread #1: tid = 101441, 0x00000000004f2d7f 
opentoonz`QMapData<QString, TPanelFactory*>::nodeRange(QString const&, 
QMapNode<QString, TPanelFactory*>**, QMapNode<QString, 
TPanelFactory*>**) + 31, stop reason = invalid address (fault address: 0x10)
   * frame #0: 0x00000000004f2d7f opentoonz`QMapData<QString, 
TPanelFactory*>::nodeRange(QString const&, QMapNode<QString, 
TPanelFactory*>**, QMapNode<QString, TPanelFactory*>**) + 31
     frame #1: 0x00000000004f20d8 
opentoonz`TPanelFactory::TPanelFactory(QString) + 120
     frame #2: 0x000000000057118d 
opentoonz`XsheetViewerFactory::XsheetViewerFactory() + 45
     frame #3: 0x00000000005701d7 opentoonz`_GLOBAL__I_a + 1687
     frame #4: 0x000000000080a1b2 opentoonz`__do_global_ctors_aux + 34
     frame #5: 0x000000000048551e opentoonz`_init + 14
     frame #6: 0x0000000800c03c9f
     frame #7: 0x0000000800c0328e
(lldb) quit


-- 
FreeBSD - the place to B...Software Developing

Shane Ambler




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?57107781.7040102>