I'm writing a new mulithreaded application in wxWidgets, and I'm encountering a pointer/malloc error that I can't quite figure out. I'm not sure if the problem lies in my wxWidgets code, or the external library that I'm using.
On starting my wxWidgets application, I create an additional thread that runs in the background and handles Modbus communication (the application is the Modbus Master). The thread periodically triggers events in the main application window, which is then updated appropriately with new data etc. Everything works fine, until I close my application, which then throws the following error:
Code: Select all
munmap_chunk(): invalid pointer
Code: Select all
NaswietlanieWiazka [C/C++ Application]
NaswietlanieWiazka [16919] [cores: 2]
Thread #1 [NaswietlanieWia] 16919 [core: 2] (Suspended : Container)
futex_wait_cancelable() at futex-internal.h:88 0x7ffff2ca99f3
__pthread_cond_wait_common() at pthread_cond_wait.c:502 0x7ffff2ca99f3
__pthread_cond_wait() at pthread_cond_wait.c:655 0x7ffff2ca99f3
wxConditionInternal::Wait() at 0x7ffff6e373a3
wxThreadModule::OnExit() at 0x7ffff6e3d0b5
wxModule::DoCleanUpModules() at 0x7ffff6d98820
wxEntryCleanup() at 0x7ffff6d7d0bf
wxUninitialize() at 0x7ffff6d7d12c
wxEntry() at 0x7ffff6d7ddd8
main() at cEntry.cpp:3 0x5555555c522c
Thread #2 [gmain] 16935 [core: 2] (Suspended : Container)
Thread #3 [gdbus] 16936 [core: 2] (Suspended : Container)
Thread #4 [NaswietlanieWia] 16938 [core: 2] (Suspended : Signal : SIGABRT:Aborted)
__GI_raise() at raise.c:51 0x7ffff6330e97
__GI_abort() at abort.c:79 0x7ffff6332801
__libc_message() at libc_fatal.c:181 0x7ffff637b897
malloc_printerr() at malloc.c:5,350 0x7ffff638290a
munmap_chunk() at malloc.c:2,846 0x7ffff6389ecc
__GI___libc_free() at malloc.c:3,117 0x7ffff6389ecc
wxThread::~wxThread() at 0x7ffff6e36555
cThreadRTU::~cThreadRTU() at cModbus.cpp:76 0x5555555d109a
cThreadRTU::~cThreadRTU() at cModbus.cpp:82 0x5555555d10ca
DeleteThread() at 0x7ffff6e3b018
<...more frames...>
Thread #5 [pool] 16940 [core: 2] (Suspended : Container)
gdb (8.1.0.20180409)
Here is my code:
Constructor:
Code: Select all
cThreadRTU::cThreadRTU(cModbus *mbMaster) : wxThread(wxTHREAD_DETACHED)
{
this->mbMaster = mbMaster;
ctx = nullptr;
ct = -1;
//Create new RTU configuration
ctx = modbus_new_rtu(mbMaster->pEntry->mbPort.mb_str(), MB_BAUD, 'E', 8, 1);
modbus_set_slave(ctx, mbMaster->pEntry->mbAddress);
modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS232);
modbus_set_response_timeout(ctx, 1, 0);
modbus_set_byte_timeout(ctx, 0, 100000);
ct = modbus_connect(ctx);
}
Code: Select all
wxThread::ExitCode cThreadRTU::Entry()
{
//Read coils on initialization
if (ct != -1)
{
wxCriticalSectionLocker enter(mbMaster->mb_guard);
mbMaster->mb_mapping->tab_input_registers[10] = modbus_read_bits(ctx, 1, MB_NUM_COILS, mbMaster->mb_mapping->tab_bits);
}
while (!TestDestroy())
{
if (ct != -1)
{
wxCriticalSectionLocker enter(mbMaster->mb_guard);
mbMaster->mb_mapping->tab_input_registers[11] = modbus_read_input_bits(ctx, 10001, MB_NUM_INPUT_BITS, mbMaster->mb_mapping->tab_input_bits);
mbMaster->mb_mapping->tab_input_registers[12] = modbus_read_input_registers(ctx, 30001, MB_NUM_INPUT_REGISTERS, mbMaster->mb_mapping->tab_input_registers);
}
if (mbMaster->pMain != nullptr)
{
//Send event to main window
wxCommandEvent evt(wxEVT_RTU_UPDATE, wxID_ANY);
((wxEvtHandler*) mbMaster->pMain)->AddPendingEvent(evt);
}
wxThread::Sleep(MB_SCANRATE);
}
return (wxThread::ExitCode) 0;
}
Code: Select all
void cModbus::CloseModbus(void)
{
{
wxCriticalSectionLocker enter(mb_guard);
//Delete RTU thread
if (mbThreadRTU)
{
if (mbThreadRTU->Delete() != wxTHREAD_NO_ERROR) wxLogError("Can't delete the thread!");
}
}
while (1)
{
{
wxCriticalSectionLocker enter(mb_guard);
if (!mbThreadRTU) break;
}
wxThread::This()->Sleep(1);
}
}
Code: Select all
cThreadRTU::~cThreadRTU()
{
modbus_close(ctx);
modbus_free(ctx);
mbMaster->mbThreadRTU = NULL;
}
Thank you in advance for your help.
Ksawery