Developer forums (C::B DEVELOPMENT STRICTLY!) > Development

wxsmith assert on wxMathplot control (wxPen::GetWidth)

(1/2) > >>

ollydbg:
I have a CodeBlocks project, which has a wxMathPlot control(gui designer is wxSmith). It is designed under Official C::B 17.12. Now, I open the wxs file with the latest C::B trunk build against wx3.1.2, C::B just hangs.

I just run the C::B under GDB, and see such assert error:

--- Code: ---[debug]> bt 30
[debug]#0  0x66488871 in wxDefaultAssertHandler(wxString const&, int, wxString const&, wxString const&, wxString const&) () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#1  0x66487bad in wxOnAssert(char const*, int, char const*, char const*, wchar_t const*) () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#2  0x666b0e07 in wxPen::GetWidth() const () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#3  0x17f5312d in mpFXY::Plot (this=0x20d73140, dc=..., w=...) at D:\code\cb\cb_sf_git\clean-trunk-for-commit\src\plugins\contrib\wxContribItems\wxmathplot\mathplot.cpp:535
[debug]#4  0x17f58d94 in mpWindow::OnPaint (this=0x20d6bfe8) at D:\code\cb\cb_sf_git\clean-trunk-for-commit\src\plugins\contrib\wxContribItems\wxmathplot\mathplot.cpp:1805
[debug]#5  0x66482d92 in wxAppConsoleBase::HandleEvent(wxEvtHandler*, void (wxEvtHandler::*)(wxEvent&), wxEvent&) const () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#6  0x66483267 in wxAppConsoleBase::CallEventHandler(wxEvtHandler*, wxEventFunctor&, wxEvent&) const () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#7  0x665d9bde in wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&) () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#8  0x665d9d2a in wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*) () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#9  0x665da431 in wxEvtHandler::TryHereOnly(wxEvent&) () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#10 0x665da49a in wxEvtHandler::ProcessEventLocally(wxEvent&) () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#11 0x665da4f3 in wxEvtHandler::ProcessEvent(wxEvent&) () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#12 0x665dc1c2 in wxEvtHandler::SafelyProcessEvent(wxEvent&) () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#13 0x666dc741 in wxWindow::HandlePaint() () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#14 0x666de1ff in wxWindow::MSWHandleMessage(long*, unsigned int, unsigned int, long) () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#15 0x666ce4f0 in wxWindow::MSWWindowProc(unsigned int, unsigned int, long) () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#16 0x666d6292 in wxWndProc(HWND__*, unsigned int, unsigned int, long)@16 () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#17 0x764862fa in gapfnScSendMessage () from C:\windows\syswow64\user32.dll
[debug]#18 0x000208ea in ?? ()
[debug]#19 0x76487316 in USER32!GetDC () from C:\windows\syswow64\user32.dll
[debug]#20 0x666d6220 in wxWindow::SubclassWin(HWND__*) () from D:\code\wxWidgets-3.1.2\lib\gcc_dll\wxmsw312u_gcc_cb.dll
[debug]#21 0x76486de8 in USER32!GetThreadDesktop () from C:\windows\syswow64\user32.dll
[debug]#22 0x00000000 in ?? ()
[debug]>>>>>>cb_gdb:
[debug]> frame 3
[debug]#3  0x17f5312d in mpFXY::Plot (this=0x20d73140, dc=..., w=...) at D:\code\cb\cb_sf_git\clean-trunk-for-commit\src\plugins\contrib\wxContribItems\wxmathplot\mathplot.cpp:535
[debug]D:\code\cb\cb_sf_git\clean-trunk-for-commit\src\plugins\contrib\wxContribItems\wxmathplot\mathplot.cpp:535:17506:beg:0x17f5312d
[debug]>>>>>>cb_gdb:

--- End code ---

The source code of the assert is in the line (m_pen.GetWidth())

--- Code: ---void mpFXY::Plot(wxDC & dc, mpWindow & w)
{
    if (m_visible) {
        dc.SetPen( m_pen);

        double x, y;
        // Do this to reset the counters to evaluate bounding box for label positioning
        Rewind(); GetNextXY(x, y);
        maxDrawX = x; minDrawX = x; maxDrawY = y; minDrawY = y;
        //drawnPoints = 0;
        Rewind();

        wxCoord startPx = m_drawOutsideMargins ? 0 : w.GetMarginLeft();
        wxCoord endPx   = m_drawOutsideMargins ? w.GetScrX() : w.GetScrX() - w.GetMarginRight();
        wxCoord minYpx  = m_drawOutsideMargins ? 0 : w.GetMarginTop();
        wxCoord maxYpx  = m_drawOutsideMargins ? w.GetScrY() : w.GetScrY() - w.GetMarginBottom();

        wxCoord ix = 0, iy = 0;

        if (!m_continuous)
        {
            // for some reason DrawPoint does not use the current pen,
            // so we use DrawLine for fat pens
            if (m_pen.GetWidth() <= 1)//*****************************crash here
            {
                while (GetNextXY(x, y))
                {
                    ix = w.x2p(x);
                    iy = w.y2p(y);
                    if (m_drawOutsideMargins || ((ix >= startPx) && (ix <= endPx) && (iy >= minYpx) && (iy <= maxYpx))) {
                        dc.DrawPoint(ix, iy);
                        UpdateViewBoundary(ix, iy);
                    };
                }
            }
            else
            {
                while (GetNextXY(x, y))
                {
                    ix = w.x2p(x);
                    iy = w.y2p(y);
                    if (m_drawOutsideMargins || ((ix >= startPx) && (ix <= endPx) && (iy >= minYpx) && (iy <= maxYpx))) {
                        dc.DrawLine(ix, iy, ix, iy);
                        UpdateViewBoundary(ix, iy);
                    }
    //                dc.DrawLine(cx, cy, cx, cy);
                }
            }
        }

--- End code ---

Any one has ideas how this happens? A wrong wxPen? or an empty wxPen?
Because it crash here: https://github.com/wxWidgets/wxWidgets/blob/master/src/msw/pen.cpp

--- Code: ---int wxPen::GetWidth() const
{
    wxCHECK_MSG( IsOk(), -1, wxT("invalid pen") );

    return M_PENDATA->GetWidth();
}

--- End code ---

ollydbg:
From the document, I see:

--- Quote ---virtual bool wxPen::IsOk    (       )    const
   virtual

Returns true if the pen is initialised.

Notice that an uninitialized pen object can't be queried for any pen properties and all calls to the accessor methods on it will result in an assert failure.


--- End quote ---

When looking at the source code of: src\plugins\contrib\wxContribItems\wxmathplot\mathplot.cpp
I see that the member variable m_pen don't have a specific constructor, so maybe the default constructor is used, but, the document said:


--- Quote ---wxPen::wxPen    (       )    

Default constructor.

The pen will be uninitialised, and IsOk() will return false.


--- End quote ---

I don't have an idea on how to solve such issue.
Maybe, we have to add the IsOk check on every m_pen function call?

EDIT:
Oh, the wxPen has correctly initialized, see below:

--- Code: ---mpLayer::mpLayer() : m_type(mpLAYER_UNDEF)
{
    SetPen((wxPen&) *wxBLACK_PEN);
    SetFont((wxFont&) *wxNORMAL_FONT);
    m_continuous = FALSE; // Default
    m_showName   = TRUE;  // Default
    m_drawOutsideMargins = TRUE;
    m_visible = true;
}

--- End code ---

Miguel Gimenez:
I have just tested one of my applications using mathplot with wx312 and works fine. It uses default pens and one custom pen, all work.

Are you using the default pen from mpLayer constructor or have you changed it using SetPen() from your code?. May be this call uses a malformed pen.

ollydbg:

--- Quote from: Miguel Gimenez on January 31, 2019, 09:41:38 am ---I have just tested one of my applications using mathplot with wx312 and works fine. It uses default pens and one custom pen, all work.

Are you using the default pen from mpLayer constructor or have you changed it using SetPen() from your code?. May be this call uses a malformed pen.

--- End quote ---

Hi, thanks for the help. Now, I can reproduce the crash issue by a minimal C::B project created by C::B 17.12. See attachment, you don't need to build the project, just try to open the cbp file under C::B trunk, and try to "review the GUI" under wxsmith.

Miguel Gimenez:
Got it. In line 254 of wxsVector.cpp we have


--- Code: ---wxPen   pen;
--- End code ---

This leaves pen uninitialized. Later, if you define a colour for the vector the pen gets initialized (line 283) and all is fine, but if you don't then the pen is left as is and SetPen() is called (line 284) with the uninitialized pen.

You can see in your wxs file that VECTOR1 has a colour defined but VECTOR2 not.

Patch is attached

Navigation

[0] Message Index

[#] Next page

Go to full version