I have a project requiring the use of Maxon EPOS under Linux. They provide libraries and code to integrate under Linux. Links are available below, 2 files libEposCmd.so and libftd2xx.so to copy into /etc/local/lib and /etc/lib and a Definition.h file.
After following the procedure, compiling the file HelloEposCmd.cpp and trying the program to test communication with hardware via USB, the code gets a Segmentation fault.
I have tried the same procedure on other machines, with Ubuntu 14.04 and 16.04 without trouble. So at this point I am not sure what is the problem, my machine, the code, issue with USB or something else.
If that can help, my laptop is a MSI Gl62 and running on Ubuntu 16.04LTS 64 bits. I am not very familiar with Ubuntu.
You can find the 2 library files, Definition.h file and the HelloEposCmd.cpp file.
http://www.maxonmotor.com/medias/sys_master/root/8815100330014/EPOS-Linux-Library-En.zip
And the installation guide: http://www.maxonmotor.com/medias/sys_master/root/8821690073118/EPOS-Command-Library-En.pdf at 9-Integration paragraph.
Here is a sample of the code:
#include <iostream>
#include "Definitions.h"
#include <string.h>
#include <sstream>
#include <unistd.h>
#include <getopt.h>
#include <stdlib.h>
#include <stdio.h>
#include <list>
#include <math.h>
typedef void* HANDLE;
typedef int BOOL;
using namespace std;
void* g_pKeyHandle = 0;
unsigned short g_usNodeId = 1;
string g_deviceName;
string g_protocolStackName;
string g_interfaceName;
string g_portName;
int g_baudrate = 0;
const string g_programName = "HelloEposCmd";
#ifndef MMC_SUCCESS
#define MMC_SUCCESS 0
#endif
#ifndef MMC_FAILED
#define MMC_FAILED 1
#endif
#ifndef MMC_MAX_LOG_MSG_SIZE
#define MMC_MAX_LOG_MSG_SIZE 512
#endif
void LogError(string functionName, int p_lResult, unsigned int p_ulErrorCode);
void LogInfo(string message);
void PrintUsage();
void PrintHeader();
void PrintSettings();
int OpenDevice(unsigned int* p_pErrorCode);
int CloseDevice(unsigned int* p_pErrorCode);
void SetDefaultParameters();
int ParseArguments(int argc, char** argv);
int DemoProfilePositionMode(HANDLE p_DeviceHandle, unsigned short p_usNodeId, unsigned int & p_rlErrorCode);
int Demo(unsigned int* p_pErrorCode);
The function where the Segfault appears:
int OpenDevice(unsigned int* p_pErrorCode)
{
int lResult = MMC_FAILED;
char* pDeviceName = new char[255];
char* pProtocolStackName = new char[255];
char* pInterfaceName = new char[255];
char* pPortName = new char[255];
strcpy(pDeviceName, g_deviceName.c_str());
strcpy(pProtocolStackName, g_protocolStackName.c_str());
strcpy(pInterfaceName, g_interfaceName.c_str());
strcpy(pPortName, g_portName.c_str());
LogInfo("Open device...");
g_pKeyHandle = VCS_OpenDevice(pDeviceName, pProtocolStackName, pInterfaceName, pPortName, p_pErrorCode);
if(g_pKeyHandle!=0 && *p_pErrorCode == 0)
{
unsigned int lBaudrate = 0;
unsigned int lTimeout = 0;
if(VCS_GetProtocolStackSettings(g_pKeyHandle, &lBaudrate, &lTimeout, p_pErrorCode)!=0)
{
if(VCS_SetProtocolStackSettings(g_pKeyHandle, g_baudrate, lTimeout, p_pErrorCode)!=0)
{
if(VCS_GetProtocolStackSettings(g_pKeyHandle, &lBaudrate, &lTimeout, p_pErrorCode)!=0)
{
if(g_baudrate==(int)lBaudrate)
{
lResult = MMC_SUCCESS;
}
}
}
}
}
else
{
g_pKeyHandle = 0;
}
delete []pDeviceName;
delete []pProtocolStackName;
delete []pInterfaceName;
delete []pPortName;
return lResult;
}
The main:
int main(int argc, char** argv)
{
int lResult = MMC_FAILED;
unsigned int ulErrorCode = 0;
PrintHeader();
SetDefaultParameters();
if((lResult = ParseArguments(argc, argv))!=MMC_SUCCESS)
{
return lResult;
}
PrintSettings();
if((lResult = OpenDevice(&ulErrorCode))!=MMC_SUCCESS)
{
LogError("OpenDevice", lResult, ulErrorCode);
return lResult;
}
if((lResult = PrepareDemo(&ulErrorCode))!=MMC_SUCCESS)
{
LogError("PrepareDemo", lResult, ulErrorCode);
return lResult;
}
if((lResult = Demo(&ulErrorCode))!=MMC_SUCCESS)
{
LogError("Demo", lResult, ulErrorCode);
return lResult;
}
if((lResult = CloseDevice(&ulErrorCode))!=MMC_SUCCESS)
{
LogError("CloseDevice", lResult, ulErrorCode);
return lResult;
}
return lResult;
}
The result from gdb backtrace:
~/EPOS_Linux_Library/example/src$ gdb HelloEposCmd coreGNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from HelloEposCmd...(no debugging symbols found)...done.
[New LWP 2436]
[New LWP 2437]
[New LWP 2439]
[New LWP 2440]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./HelloEposCmd'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007fc3eca0a960 in _xend ()
at ../sysdeps/unix/sysv/linux/x86/elision-unlock.c:33
33 ../sysdeps/unix/sysv/linux/x86/elision-unlock.c: No such file or directory.
[Current thread is 1 (Thread 0x7fc3edcbc740 (LWP 2436))]
(gdb) backtrace
#0 0x00007fc3eca0a960 in _xend ()
at ../sysdeps/unix/sysv/linux/x86/elision-unlock.c:33
#1 __lll_unlock_elision (lock=0x10a1138, private=0)
at ../sysdeps/unix/sysv/linux/x86/elision-unlock.c:29
#2 0x00007fc3ec7e2934 in EventDestroy () from /usr/local/lib/libftd2xx.so
#3 0x00007fc3ec7db2e8 in FT_Close () from /usr/local/lib/libftd2xx.so
#4 0x00007fc3ec7e166b in FT_CreateDeviceInfoList ()
from /usr/local/lib/libftd2xx.so
#5 0x00007fc3ed82c911 in CMmcFtd2xxHndlBase::CreateDeviceInfoList(unsigned int*) () from /usr/local/lib/libEposCmd.so
#6 0x00007fc3ed82ca88 in CMmcFtd2xxHndlBase::GetDeviceInfos(std::list<CUsbDeviceInfo*, std::allocator<CUsbDeviceInfo*> >&, unsigned short, unsigned short) ()
from /usr/local/lib/libEposCmd.so
#7 0x00007fc3ed7e2346 in CGatewayUSBToFtd2xxDrv::GetDeviceInfos(std::list<CUsbDeviceInfo*, std::allocator<CUsbDeviceInfo*> >&) ()
from /usr/local/lib/libEposCmd.so
#8 0x00007fc3ed7e2b48 in CGatewayUSBToFtd2xxDrv::InitPortList() ()
from /usr/local/lib/libEposCmd.so
#9 0x00007fc3ed7deed1 in CPort_USB::InitGateway(CStdStr<char>, CGatewayIToDrv*) () from /usr/local/lib/libEposCmd.so
#10 0x00007fc3ed7df232 in CPort_USB::InitPort(CStdStr<char>, CGatewayIToDrv*, CErrorInfo*) () from /usr/local/lib/libEposCmd.so
#11 0x00007fc3ed7cb04f in CInterface_USB::InitPort(CStdStr<char>, CErrorInfo*)
---Type <return> to continue, or q <return> to quit---
() from /usr/local/lib/libEposCmd.so
#12 0x00007fc3ed7cb19e in CInterface_USB::InitInterface(CStdStr<char>, CErrorInfo*) () from /usr/local/lib/libEposCmd.so
#13 0x00007fc3ed7caada in CInterface_USB::InitInterface(CErrorInfo*) ()
from /usr/local/lib/libEposCmd.so
#14 0x00007fc3ed7a6a92 in CInterfaceManager::I_InitInterface(CStdStr<char>, CErrorInfo*) () from /usr/local/lib/libEposCmd.so
#15 0x00007fc3ed7923ec in CProtocolStackBase::InitProtocolStack(CStdStr<char>, CErrorInfo*) () from /usr/local/lib/libEposCmd.so
#16 0x00007fc3ed7646e9 in CProtocolStackManager::PS_InitProtocolStack(CStdStr<char>, CStdStr<char>, CErrorInfo*) () from /usr/local/lib/libEposCmd.so
#17 0x00007fc3ed73ce84 in CDeviceBase::InitDevice(CStdStr<char>, CStdStr<char>, CErrorInfo*) () from /usr/local/lib/libEposCmd.so
#18 0x00007fc3ed6d06de in CDeviceCommandSetManager::DCS_InitDevice(CStdStr<char>, CStdStr<char>, CStdStr<char>, CErrorInfo*) ()
from /usr/local/lib/libEposCmd.so
#19 0x00007fc3ed6aebd6 in CVirtualDeviceBase::InitVirtualDevice(CStdStr<char>, CStdStr<char>, CStdStr<char>, CErrorInfo*) () from /usr/local/lib/libEposCmd.so
#20 0x00007fc3ed684deb in CVirtualCommandSet_Manager::VCS_InitVirtualDevice(CStdStr<char>, CStdStr<char>, CStdStr<char>, CStdStr<char>, CErrorInfo*) ()
from /usr/local/lib/libEposCmd.so
#21 0x00007fc3ed66d112 in CCommunicationModel::CreateVirtualCommandSetManager()
() from /usr/local/lib/libEposCmd.so
---Type <return> to continue, or q <return> to quit---
#22 0x00007fc3ed67ca75 in VCS_OpenDevice () from /usr/local/lib/libEposCmd.so
#23 0x000000000040206e in OpenDevice(unsigned int*) ()
#24 0x0000000000403a6c in main ()
For USB communication, I modified the 99-ftdi.rules file provided:
SUBSYSTEM=="usb|usb_device", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="a8b0", GROUP="dialout", MODE="666", SYMLINK+="ftd2xx%n"
and copied to "/etc/udev/rules.d/" (this works with other machines).
Thanks for the help
Update:
Using the newest version of FTDI (1.3.6) did not help.
Since it is specific to my machine, here are the specs, if that can help:
-Dual boot Windows 10 - Ubuntu 16.04LTS 64bits
- Intel Core i7-6700HQ CPU 2.60GHw
- Nividia GTX950M
I have read issues of elision-unlock with Intel cores and maybe also caused by the graphic card, though I don't fully understand the issues, and how this simple program is related to the graphic card, or even using multiple cores.
Make sure your USB device gets enough power from the USB port. Try supplying external power if possible.
If the device does not have external power supply, try using a USB hub with external power supply.
In my experience, if the USB device draws too much current, it can cause temporary shut down to USB powered device (e.g., 5V supply dips below 3v due to sudden high current draw, causing the device to reset, where the PC thinks it got unplugged).
Related
I'm building a simple utility program that queries a mysql database, and uses regex to isolate strings in the table data.
I'm using MariaDB c++/connector, and the latest versions of MariaDB. The code was copied from the MariaDB website. I have simplified the software to illustrate the problem. See below:
// g++ -o mariadb_connect mariadb_connect.cpp -lmariadbcpp
// From https://mariadb.com/docs/clients/connector-cpp/
// with three additional lines that cause segfault
#include <iostream>
#include <mariadb/conncpp.hpp>
#include <regex> // <-- Added to the example
int main()
{
try
{
// Instantiate Driver
sql::Driver* driver = sql::mariadb::get_driver_instance();
// Configure Connection
// The URL or TCP connection string format is
// ``jdbc:mariadb://host:port/database``.
sql::SQLString url("jdbc:mariadb://localhost:3306/??????");
// Use a properties map for the user name and password
sql::Properties properties({
{"user", "???????"},
{"password", "????????"}
});
// Establish Connection
// Use a smart pointer for extra safety
std::unique_ptr<sql::Connection> conn(driver->connect(url, properties));
// Use Connection
std::cout << "Using the connection" << std::endl; // <-- Added
std::regex regexp("(faststatic.com)(.*)"); // <-- Added (Causes segfault)
// Close Connection
conn->close();
}
// Catch Exceptions
catch (sql::SQLException& e)
{
std::cout << "Error Connecting to MariaDB Platform: "
<< e.what() << std::endl;
// Exit (Failed)
return 1;
}
// Exit (Success)
return 0;
}
(???? used for private data)
Compiled with g++ on an AWS EC2 instance running Amazon Linux 2 AMI.
Compiles fine and runs fine until I added the std::regex regexp(...)
line. It still compiles fine with the addition, but on execution calls
a segfault.
I have used gdb which provides the following output with breakpoint set
to main.
(gdb) b main
Breakpoint 1 at 0x40404b: file mariadb_connect.cpp, line 15.
(gdb) run
Starting program: /home/msellers/proj/preload_images/spike/mariadb_connect
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x000000000064a588 in ?? ()
Here is the output of the gdb bt command after the segfault:
(gdb) bt
#0 0x000000000064a588 in ?? ()
#1 0x0000000000409155 in std::__detail::_Scanner<char>::_M_scan_normal (this=0x7fffffffe018) at /usr/include/c++/7/bits/regex_scanner.tcc:119
#2 0x00000000004084a1 in std::__detail::_Scanner<char>::_M_advance (this=0x7fffffffe018) at /usr/include/c++/7/bits/regex_scanner.tcc:80
#3 0x00007ffff7c3e060 in std::__detail::_Compiler<std::regex_traits<char> >::_M_match_token (this=this#entry=0x7fffffffe000, token=std::__detail::_ScannerBase::_S_token_subexpr_begin) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:541
#4 0x00007ffff7c513a2 in std::__detail::_Compiler<std::regex_traits<char> >::_M_match_token (token=std::__detail::_ScannerBase::_S_token_subexpr_begin, this=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:316
#5 std::__detail::_Compiler<std::regex_traits<char> >::_M_atom (this=this#entry=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:326
#6 0x00007ffff7c515b0 in std::__detail::_Compiler<std::regex_traits<char> >::_M_term (this=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:136
#7 std::__detail::_Compiler<std::regex_traits<char> >::_M_alternative (this=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:118
#8 0x00007ffff7c51809 in std::__detail::_Compiler<std::regex_traits<char> >::_M_disjunction (this=this#entry=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:97
#9 0x00007ffff7c51e18 in std::__detail::_Compiler<std::regex_traits<char> >::_Compiler (this=0x7fffffffe000, __b=<optimized out>, __e=<optimized out>, __traits=..., __flags=<optimized out>)
at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:82
#10 0x00007ffff7c5222d in std::__detail::__compile_nfa<std::regex_traits<char> > (__first=<optimized out>, __last=<optimized out>, __traits=..., __flags=<optimized out>) at /usr/local/include/c++/4.9.4/bits/regex_compiler.h:158
#11 0x00007ffff7c524da in std::basic_regex<char, std::regex_traits<char> >::basic_regex<char const*> (__f=<optimized out>, __last=<optimized out>, __first=<optimized out>, this=0x7ffff7dc2a40 <sql::mariadb::UrlParser::URL_PARAMETER>)
at /usr/local/include/c++/4.9.4/bits/regex.h:540
#12 std::basic_regex<char, std::regex_traits<char> >::basic_regex (this=0x7ffff7dc2a40 <sql::mariadb::UrlParser::URL_PARAMETER>, __p=<optimized out>, __f=<optimized out>) at /usr/local/include/c++/4.9.4/bits/regex.h:452
#13 0x00007ffff7c331ee in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at /home/buildbot/src/src/UrlParser.cpp:34
#14 _GLOBAL__sub_I_UrlParser.cpp(void) () at /home/buildbot/src/src/UrlParser.cpp:444
#15 0x00007ffff7de7dc2 in call_init (l=<optimized out>, argc=argc#entry=1, argv=argv#entry=0x7fffffffe2b8, env=env#entry=0x7fffffffe2c8) at dl-init.c:72
#16 0x00007ffff7de7eb6 in call_init (env=0x7fffffffe2c8, argv=0x7fffffffe2b8, argc=1, l=<optimized out>) at dl-init.c:119
#17 _dl_init (main_map=0x7ffff7ffe130, argc=1, argv=0x7fffffffe2b8, env=0x7fffffffe2c8) at dl-init.c:120
#18 0x00007ffff7dd9f2a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#19 0x0000000000000001 in ?? ()
#20 0x00007fffffffe520 in ?? ()
#21 0x0000000000000000 in ?? ()
(gdb)
Does this help?
Mark
GCC version 7.3.1
In the backtrace, we see that the crash is happening in the GCC-7 regexp implementation:
#1 0x0000000000409155 in std::__detail::_Scanner<char>::_M_scan_normal (this=0x7fffffffe018) at /usr/include/c++/7/bits/regex_scanner.tcc:119
We also see that this crash is happening while some global inside (presumably1) MariaDB connector is being initialized, while using GCC-4.9.4 version of libstdc++:
#12 std::basic_regex<char, std::regex_traits<char> >::basic_regex (this=0x7ffff7dc2a40 <sql::mariadb::UrlParser::URL_PARAMETER>, __p=<optimized out>, __f=<optimized out>) at /usr/local/include/c++/4.9.4/bits/regex.h:452
#13 0x00007ffff7c331ee in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at /home/buildbot/src/src/UrlParser.cpp:34
It is exceedingly likely that this 4.9.4 vs. 7.3.1 mismatch is the cause of the crash, and that either building the app with g++-4.9.4 or building the MariaDB with g++-7.3.1 will fix the problem.
In theory GCC version of libstdc++ should be backwards compatible, but verifying ABI compatibility in C++ is quite hard, and many mistakes have been made. Also, g++4.9.4 is ancient.
Another possible solution is to build the application with clang using libc++ -- this will avoid any possibility of symbol conflicts2.
1 You can verify whether frame #13 is really coming from the MariaDB by executing these GDB commands: frame 13, info symbol $pc.
2 To achieve this, you may need to explicitly tell clang to use libc++, as it may default to using libstdc++. Use clang++ -stdlib=libc++ ... to be sure. Documentation here.
I have a Raspberry Pi 3B+ with my Qt code on it (Qt 5.12.5). When I run my code, it randomly crashes with a Bus Error after a few hours. I am not sure how to work out the exact cause. I cross compile on Ubuntu for the RPi using the latest Raspberry Pi OS (2020-05-27).
The core dump (I have replaced some irrelevant parts with ...)
pi#raspberrypi: $ gdb TEST core
GNU gdb (Raspbian 8.2.1-2) 8.2.1
...
Type "apropos word" to search for commands related to "word"...
Reading symbols from TEST...done.
[New LWP 1233]
...
[New LWP 1226]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
Core was generated by `./TEST'.
Program terminated with signal SIGBUS, Bus error.
#0 0x755b5b7c in QString::arg(long long, int, int, QChar) const () from /usr/local/qt5pi/lib/libQt5Core.so.5
[Current thread is 1 (Thread 0x6feff440 (LWP 1233))]
(gdb) bt full
#0 0x755b5b7c in QString::arg(long long, int, int, QChar) const () at /usr/local/qt5pi/lib/libQt5Core.so.5
#1 0x0001c0bc in QString::arg(int, int, int, QChar) const (this=0x6fefdc78, a=12, fieldWidth=0, base=10, fillChar=...) at ../raspi/qt5pi/include/QtCore/qstring.h:976
#2 0x00039ff8 in StageState::getStateString() (this=0x6fefdf00) at ../TEST/stage.h:35
...
#7 0x00142124 in TEST::timerExpired() (this=0x7ecd4708) at ../TEST/TEST.cpp:51
__PRETTY_FUNCTION__ = "void TEST::timerExpired()"
locker = {val = 2127384345}
#8 0x0015c188 in TEST::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=0x7ecd4708, _c=QMetaObject::InvokeMetaMethod, _id=2, _a=0x6fefe9d8) at moc_TEST.cpp:122
_t = 0x7ecd4708
#9 0x75722b08 in QMetaObject::activate(QObject*, int, int, void**) () at /usr/local/qt5pi/lib/libQt5Core.so.5
#10 0x75730c1c in QTimer::timeout(QTimer::QPrivateSignal) () at /usr/local/qt5pi/lib/libQt5Core.so.5
#11 0x75730fc8 in QTimer::timerEvent(QTimerEvent*) () at /usr/local/qt5pi/lib/libQt5Core.so.5
#12 0x75724194 in QObject::event(QEvent*) () at /usr/local/qt5pi/lib/libQt5Core.so.5
#13 0x768c6b88 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/local/qt5pi/lib/libQt5Widgets.so.5
#14 0x768ce29c in QApplication::notify(QObject*, QEvent*) () at /usr/local/qt5pi/lib/libQt5Widgets.so.5
#15 0x759b62ec in QCoreApplication::self () at /usr/local/qt5pi/lib/libQt5Core.so.5
(gdb)
../TEST/stage.h:35 refers to this code:
return QString("text %1").arg(aInt);
Possible causes and fixes I am considering:
To me, from the stack trace, it looks like the crashes are occurring inside QString, possibly due to a Qt bug? However I am not sure. I can try a newer version of Qt.
I am also using a QTimer in a thread, maybe this could cause a issue, accessing a object from other threads? I am already using QMutex. I could instead only use the gui thread short term and test if crashes still occur.
Searching online, I found a comment to look a the dmesg output (below), maybe my MicroSD card is dying? I am waiting for a new one to arrive.
Anything else?
pi#raspberrypi:~ $ dmesg
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 5.4.44-v7+ (dom#buildbot) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1320 SMP Wed Jun 3 16:07:06 BST 2020
[ 0.000000] CPU: ARMv7 Processor [410fd034] revision 4 (ARMv7), cr=10c5383d
...
[ 17.898294] Bluetooth: BNEP filters: protocol multicast
[ 17.898313] Bluetooth: BNEP socket layer initialized
[16092.809350] Alignment trap: not handling instruction e1903f9f at [<755b5b78>]
[16092.809367] 8<--- cut here ---
[16092.815191] Unhandled fault: alignment exception (0x001) at 0x6f577277
[16092.820865] pgd = 6aa8fcbe
[16092.826468] [6f577277] *pgd=3278c835, *pte=2812175f, *ppte=28121c7f
Here is another bus error that is similar but not quite the same as previously:
pi#raspberrypi:~/TEST/bin $ gdb TEST core
GNU gdb (Raspbian 8.2.1-2) 8.2.1
...
Type "apropos word" to search for commands related to "word"...
Reading symbols from TEST...done.
[New LWP 767]
...
[New LWP 763]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
Core was generated by `./TEST'.
Program terminated with signal SIGBUS, Bus error.
#0 0x7568d470 in QString::fromAscii_helper(char const*, int) () from /usr/local/qt5pi/lib/libQt5Core.so.5
[Current thread is 1 (Thread 0x709bf440 (LWP 767))]
(gdb) bt
#0 0x7568d470 in QString::fromAscii_helper(char const*, int) () at /usr/local/qt5pi/lib/libQt5Core.so.5
#1 0x75830da4 in () at /usr/local/qt5pi/lib/libQt5Core.so.5
#2 0x0001c030 in QString::QString(char const*) (this=0x709be71c, ch=0x15fa88 "[0-9| ]{3}") at ../raspi/qt5pi/include/QtCore/qstring.h:700
#3 0x00029da8 in Measurement::doesRececivedDataFormatMatchRegex(QString) (this=0x709be7f4, receivedData=...) at ../TEST/Measurement.h:103
...
#12 0x7580c58c in QSocketNotifier::activated(int, QSocketNotifier::QPrivateSignal) () at /usr/local/qt5pi/lib/libQt5Core.so.5
#13 0x7580c90c in QSocketNotifier::event(QEvent*) () at /usr/local/qt5pi/lib/libQt5Core.so.5
#14 0x769a2b88 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/local/qt5pi/lib/libQt5Widgets.so.5
#15 0x769aa29c in QApplication::notify(QObject*, QEvent*) () at /usr/local/qt5pi/lib/libQt5Widgets.so.5
#16 0x75a922ec in QCoreApplication::self () at /usr/local/qt5pi/lib/libQt5Core.so.5
Edit: added getStateString() and doesRececivedDataFormatMatchRegex() functions
QString getStateString() {
switch (state) {
case StageState::AEnum:
return QString("text %1").arg(aInt);
...
default:
return QString("Unknown");
}
}
bool Measurement::doesRececivedDataFormatMatchRegex(QString receivedData)
{
QRegExp regExp("[0-9| ]{3}");
return receivedData.indexOf(regExp) != -1;
}
In a simple C++ test app in Code::Blocks on Linux, I have a wxTextCtrl named txtSelect, it contains: 'SELECT * FROM user;'
When I run the following, Crash!
void refreshGrid()
{
wxTextCtrl *txtSelect;
wxString sqlLine = txtSelect->GetValue();
}
The gdb result is below:
(gdb) run
Starting program: /home/dan/Documents/wxW_Projs/wxSQLi_417/bin/Debug/wxSQLi_417
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x0000000000410662 in refreshGrid ()
at /home/dan/Documents/wxW_Projs/wxSQLi_417/wxSQLi_417Main.cpp:199
199 wxString sqlLine = txtSelect->GetValue();
(gdb) bt
#0 0x0000000000410662 in refreshGrid ()
at /home/dan/Documents/wxW_Projs/wxSQLi_417/wxSQLi_417Main.cpp:199
#1 0x0000000000410593 in wxSQLi_417Frame::OnButton2Click (this=0x7143c0,
event=...)
at /home/dan/Documents/wxW_Projs/wxSQLi_417/wxSQLi_417Main.cpp:183
#2 0x00007ffff6d461fe in wxAppConsoleBase::CallEventHandler(wxEvtHandler*, wxEventFunctor&, wxEvent&) const ()
from /usr/lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
#3 0x00007ffff6ecc6e7 in wxEvtHandler::ProcessEventIfMatchedan(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&) ()
from /usr/lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
#4 0x00007ffff6eccace in wxEvtHandler::SearchDynamicEventTable(wxEvent&) ()
from /usr/lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
#5 0x00007ffff6eccb5f in wxEvtHandler::TryHereOnly(wxEvent&) ()
from /usr/lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
#6 0x00007ffff6eccc13 in wxEvtHandler::ProcessEventLocally(wxEvent&) ()
from /usr/lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
#7 0x00007ffff6eccc75 in wxEvtHandler::ProcessEvent(wxEvent&) ()
from /usr/lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
#8 0x00007ffff75f3de8 in wxWindowBase::TryAfter(wxEvent&) ()
from /usr/lib/x86_64-linux-gnu/libwx_gtk2u_core-3.0.so.0
#9 0x00007ffff6ecc9e7 in wxEvtHandler::SafelyProcessEvent(wxEvent&) ()
from /usr/lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0
---Type <return> to continue, or q <return> to quit---
I have another app in the same PC, with a simple password demo that uses the same simple code and works perfectly, and many others.
Any advice greatly appreciated.
txtSelect is pointing to nowhere. You should create an object which the pointer points to and then use it, something like this:
wxTextCtrl *txtSelect = new wxTextCtrl();
wxString sqlLine = txtSelect->GetValue();
If the allocation fails new throws an exception std::bad_alloc
I have a simple multi-threaded version with TBB which works fine on a linux machine but on occasions, not always, gives segmentation fault when executed on windows.
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <math.h>
#include <dirent.h>
#include <string.h>
#include <chrono>
using namespace cv;
std::vector<std::string> fnames;
class Parallel_process : public cv::ParallelLoopBody
{
public:
Parallel_process() {}
void operator()(const cv::Range &r) const {
cv::Mat src, dst, color_dst;
if(!(src=imread(fnames[r.start], 0)).data)
{
return;
}
Canny( src, dst, 50, 200, 3 );
cvtColor( dst, color_dst, CV_GRAY2BGR );
std::vector<Vec4i> lines;
HoughLinesP( dst, lines, 1, CV_PI/180, 80, 30, 10 );
for( size_t i = 0; i < lines.size(); i++ )
line( color_dst, Point(lines[i][0], lines[i][1]), Point(lines[i][2], lines[i][3]), Scalar(0,0,255), 3, 8 );
std::string ext = "_parallel.bmp";
std::size_t found = fnames[r.start].find_last_of("/\\");
std::string fname = fnames[r.start].substr(found+1);
std::string out_fname = fname.substr(0, fname.find(".")) + ext;
cv::imwrite(out_fname.c_str(), color_dst);
}
};
int main()
{
DIR *dir;
struct dirent *ent;
std::string prefix = "c:\\Users\\foo\\Desktop\\sample_code\\imgs";
if ((dir = opendir (prefix.c_str())) != NULL) {
while ((ent = readdir (dir)) != NULL) {
fnames.push_back(prefix + '\\' + std::string(ent->d_name));
}
closedir (dir);
}
auto begin = std::chrono::high_resolution_clock::now();
cv::parallel_for_(cv::Range(0, fnames.size()), Parallel_process());
auto end = std::chrono::high_resolution_clock::now();
std::cout<<std::chrono::duration_cast<std::chrono::seconds>(end-begin).count()<<"secs"<<std::endl;
return(0);
}
Compilation is done using:
g++ -o parallel -I"c:\opencv\mingw_bld\install\include" edge_detection_parallel.cpp -L"c:\opencv\mingw_bld\install\x86\mingw\lib" -lopencv_imgproc300 -lopencv_core300 -lopencv_imgcodecs300 -lopencv_highgui300 -std=c++11
TBB version:
// Marketing-driven product version
#define TBB_VERSION_MAJOR 4
#define TBB_VERSION_MINOR 4
// Engineering-focused interface version
#define TBB_INTERFACE_VERSION 9000
#define TBB_INTERFACE_VERSION_MAJOR TBB_INTERFACE_VERSION/1000
// The oldest major interface version still supported
// To be used in SONAME, manifests, etc.
#define TBB_COMPATIBLE_INTERFACE_VERSION 2
GDB output (two runs; one was fine and the other received the segmentation fault):
gdb parallel.exe
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from C:\Users\foo\Desktop\sample_code\parallel.exe...(no
debugging symbols found)...done.
(gdb) r
Starting program: C:\Users\foo\Desktop\sample_code/parallel.exe
[New Thread 5788.0xb90]
[New Thread 5788.0x144c]
[New Thread 5788.0x168c]
[New Thread 5788.0xd1c]
30secs
[Inferior 1 (process 5788) exited normally]
(gdb) r
Starting program: C:\Users\foo\Desktop\sample_code/parallel.exe
[New Thread 620.0x1450]
[New Thread 620.0xf04]
[New Thread 620.0x100c]
[New Thread 620.0x159c]
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 620.0x159c]
0x777cd9e5 in ?? ()
(gdb) bt
#0 0x777cd9e5 in ?? ()
#1 0x777cd3d8 in ?? ()
#2 0x7787184a in ?? ()
#3 0x778319c7 in ?? ()
#4 0x777cd3d8 in ?? ()
#5 0x7541b0f9 in msvcrt!free () from C:\Windows\system32\msvcrt.dll
#6 0x00740000 in ?? ()
#7 0x6c372f3b in cv::Canny(cv::_InputArray const&, cv::_OutputArray const&, dou
ble, double, int, bool) ()
from C:\opencv\mingw_bld\bin\libopencv_imgproc300.dll
#8 0x00408ef6 in Parallel_process::operator()(cv::Range const&) const ()
#9 0x69824e46 in tbb::interface7::internal::start_for<tbb::blocked_range<int>,
(anonymous namespace)::ProxyLoopBody, tbb::auto_partitioner const>::execute()
() from C:\opencv\mingw_bld\bin\libopencv_core300.dll
#10 0x678d7e49 in tbb::internal::custom_scheduler<tbb::internal::IntelSchedulerT
raits>::local_wait_for_all (this=0x913e80, parent=..., child=0x947620)
at ../../src/tbb/custom_scheduler.h:463
#11 0x678cc94f in tbb::internal::arena::process (this=this#entry=0x93ed00,
s=...) at ../../src/tbb/arena.cpp:114
#12 0x678cbcc1 in tbb::internal::market::process (this=<optimized out>, j=...)
at ../../src/tbb/market.cpp:494
#13 0x678c86dc in tbb::internal::rml::private_worker::run (
this=this#entry=0x93fc00) at ../../src/tbb/private_server.cpp:275
#14 0x678c8893 in tbb::internal::rml::private_worker::thread_routine (
arg=0x93fc00) at ../../src/tbb/private_server.cpp:228
#15 0x75427fb0 in msvcrt!_cexit () from C:\Windows\system32\msvcrt.dll
#16 0x0093fc00 in ?? ()
#17 0x754280f5 in msvcrt!_beginthreadex () from C:\Windows\system32\msvcrt.dll
#18 0x75b04198 in KERNEL32!BaseThreadInitThunk ()
from C:\Windows\system32\kernel32.dll
#19 0x777e445d in ?? ()
#20 0x777e442b in ?? ()
#21 0x00000000 in ?? ()
OS details:
I am on mingw (gcc version 4.5.2).
I get a segfault when opening certain files, including PNGs and BMPs. It was working fine on a 128x128 PNG but when I started testing with larger files I started getting a segfault. There are no issues with the TGA format, though. I know the library works for the most part, but not knowing whether it will decide to crash and burn like this is not good.
gdb does not give me any hints about what's going on. I am able to compile DevIL from source, and I compiled a debug dll (--enable-debug for configure script) but it doesn't seem to support png (seems like I need to get a png12 library) but it doesn't get me very far.
I am trying to open a ~2MB BMP I made in GIMP. I run it through GDB and it sometimes will segfault but other times it warns of some stuff happening on the heap (lots of stuff i've never seen before). Here's a gdb run dump. All of the lines beginning with %%% are the output that is specific to my program, the rest comes from gdb.
$ gdb ./entropy_unittest_disp.exe loadpngdisplay
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from c:\Users\Steven\Dropbox\Programming\entropy_p5_makefile\cpp
\game/./entropy_unittest_disp.exe...done.
c:\Users\Steven\Dropbox\Programming\entropy_p5_makefile\cpp\game/loadpngdisplay:
No such file or directory.
(gdb) r
Starting program: c:\Users\Steven\Dropbox\Programming\entropy_p5_makefile\cpp\ga
me/./entropy_unittest_disp.exe
[New Thread 23284.0x5bb4]
%%%UNIT TEST BUILD: INTERNAL USE ONLY. DO NOT DISTRIBUTE
%%%Compiled on Sep 11 2011 at 09:45:38
%%%argc = 1: Main.cpp:119
%%%argv:
%%%0: c:\Users\Steven\Dropbox\Programming\entropy_p5_makefile\cpp\game/./entropy_un
%%%ittest_disp.exe
%%%←[36mStarting Test ilWritePng, at Image.cpp:8←[0m
%%%rm: cannot lstat `output_il.png': No such file or directory
%%%ilGetError() = 1292: Image.cpp:25
%%%Completed Test ilWritePng in 0.033 seconds
%%%←[36mStarting Test loadPNGDisplay, at Image.cpp:31←[0m
[New Thread 23284.0x445c]
[New Thread 23284.0x1fd8]
[New Thread 23284.0x1424]
%%%Number of Joysticks detected: 2
%%%Opening Joystick: Harmonix Guitar for Xbox 360 (Controller)
[New Thread 23284.0x526c]
[New Thread 23284.0x5a70]
[New Thread 23284.0x1ae8]
[New Thread 23284.0x5908]
[New Thread 23284.0x5974]
%%%Using GLEW 1.5.8
%%%OpenGL Vendor: NVIDIA Corporation
%%%OpenGL Renderer: GeForce GTX 260/PCI/SSE2
%%%OpenGL Version: 3.3.0
warning: HEAP[entropy_unittest_disp.exe]:
warning: Invalid address specified to RtlFreeHeap( 00350000, 04000000 )
Program received signal SIGTRAP, Trace/breakpoint trap.
0x772e0475 in ntdll!TpWaitForAlpcCompletion ()
from C:\Windows\system32\ntdll.dll
(gdb) where
#0 0x772e0475 in ntdll!TpWaitForAlpcCompletion ()
from C:\Windows\system32\ntdll.dll
#1 0x0028f510 in ?? ()
#2 0x772a29c0 in ntdll!RtlCopyExtendedContext ()
from C:\Windows\system32\ntdll.dll
#3 0x03fffff8 in ?? ()
#4 0x772e14cf in ntdll!TpQueryPoolStackInformation ()
from C:\Windows\system32\ntdll.dll
#5 0x00350000 in ?? ()
#6 0x7729ab3a in ntdll!AlpcMaxAllowedMessageLength ()
from C:\Windows\system32\ntdll.dll
#7 0x00350000 in ?? ()
#8 0x77243472 in ntdll!RtlLargeIntegerShiftRight ()
from C:\Windows\system32\ntdll.dll
#9 0x03fffff8 in ?? ()
#10 0x766398cd in msvcrt!free () from C:\Windows\syswow64\msvcrt.dll
#11 0x00350000 in ?? ()
#12 0x6180129c in _mm_free (aligned_ptr=0x8230020)
at c:/mingw/bin/../lib/gcc/mingw32/4.5.2/include/mm_malloc.h:71
#13 0x61801370 in DefaultFreeFunc (ptr=0x8230020)
at ./../src-IL/src/il_alloc.c:127
#14 0x618012ee in ifree (Ptr=0x8230020) at ./../src-IL/src/il_alloc.c:99
#15 0x618149f8 in iPreCache (Size=592128) at ./../src-IL/src/il_files.c:550
#16 0x618148a2 in iReadFile (Buffer=0x8100017, Size=1, Number=2313)
at ./../src-IL/src/il_files.c:499
#17 0x61808cf5 in ilReadUncompBmp (Header=0x28f829)
at ./../src-IL/src/il_bmp.c:486
#18 0x61808410 in iLoadBitmapInternal () at ./../src-IL/src/il_bmp.c:250
#19 0x618082f3 in ilLoadBmpF (File=0x766d2960) at ./../src-IL/src/il_bmp.c:199
#20 0x618082ba in ilLoadBmp (FileName=0x4c25f1 "folder.bmp")
at ./../src-IL/src/il_bmp.c:184
#21 0x61830bf0 in ilLoadImage (FileName=0x4c25f1 "folder.bmp")
at ./../src-IL/src/il_io.c:1827
#22 0x0040f66c in SDLSystemloadPNGDisplayHelper::RunImpl (this=0x28fc10)
at Image.cpp:40
#23 0x00461e74 in UnitTest::ExecuteTest<SDLSystemloadPNGDisplayHelper> (
testObject=..., details=...) at ../include/UnitTest++/ExecuteTest.h:25
#24 0x0040f2cd in TestSDLSystemloadPNGDisplay::RunImpl (this=0x4e5cf8)
at Image.cpp:31
#25 0x00463023 in UnitTest::ExecuteTest<UnitTest::Test> (testObject=...,
details=...) at src/ExecuteTest.h:25
#26 0x0044198d in UnitTest::Test::Run (this=0x4e5cf8) at src/Test.cpp:34
#27 0x00441d9a in UnitTest::TestRunner::RunTest (this=0x28fedc,
result=0x3517f0, curTest=0x4e5cf8, maxTestTimeInMs=0)
at src/TestRunner.cpp:61
#28 0x00466b7e in UnitTest::TestRunner::RunTestsIf<UnitTest::True> (
this=0x28fedc, list=..., suiteName=0x0, predicate=..., maxTestTimeInMs=0)
at ../include/UnitTest++/TestRunner.h:40
#29 0x004014e3 in UnitTest::RunAllTestsVerbose () at Main.cpp:72
#30 0x0040167d in main (argc=1, argv=0x3531d8) at Main.cpp:126
(gdb) c
Continuing.
warning: HEAP[entropy_unittest_disp.exe]:
warning: Invalid address specified to RtlFreeHeap( 00350000, 04000000 )
Program received signal SIGTRAP, Trace/breakpoint trap.
0x772e0475 in ntdll!TpWaitForAlpcCompletion ()
from C:\Windows\system32\ntdll.dll
(gdb) c
Continuing.
warning: HEAP[entropy_unittest_disp.exe]:
warning: Invalid address specified to RtlFreeHeap( 00350000, 04000000 )
Program received signal SIGTRAP, Trace/breakpoint trap.
0x772e0475 in ntdll!TpWaitForAlpcCompletion ()
from C:\Windows\system32\ntdll.dll
(gdb)
Continuing.
warning: HEAP[entropy_unittest_disp.exe]:
warning: Invalid address specified to RtlFreeHeap( 00350000, 04000000 )
Program received signal SIGTRAP, Trace/breakpoint trap.
0x772e0475 in ntdll!TpWaitForAlpcCompletion ()
from C:\Windows\system32\ntdll.dll
(gdb)
Continuing.
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 23284.0x5974]
0x05064225 in nvoglv32!DrvGetProcAddress ()
from C:\Windows\SysWOW64\nvoglv32.dll
(gdb)
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x05064225 in nvoglv32!DrvGetProcAddress ()
from C:\Windows\SysWOW64\nvoglv32.dll
(gdb)
Continuing.
Program exited with code 030000000005.
(gdb)
The program is not being run.
(gdb) r
Starting program: c:\Users\Steven\Dropbox\Programming\entropy_p5_makefile\cpp\ga
me/./entropy_unittest_disp.exe
[New Thread 23428.0x49b8]
%%%UNIT TEST BUILD: INTERNAL USE ONLY. DO NOT DISTRIBUTE
%%%Compiled on Sep 11 2011 at 09:45:38
%%%argc = 1: Main.cpp:119
%%%argv:
%%%0: c:\Users\Steven\Dropbox\Programming\entropy_p5_makefile\cpp\game/./entropy_un
%%%ittest_disp.exe
%%%←[36mStarting Test ilWritePng, at Image.cpp:8←[0m
Program received signal SIGSEGV, Segmentation fault.
0x7723dfc4 in ntdll!LdrWx86FormatVirtualImage ()
from C:\Windows\system32\ntdll.dll
(gdb) where
#0 0x7723dfc4 in ntdll!LdrWx86FormatVirtualImage ()
from C:\Windows\system32\ntdll.dll
#1 0x1f002150 in ?? ()
#2 0x00000000 in ?? ()
(gdb)
the test ilWritePng is actually just having it write a .tga image file. That test works fine with the release dll (md5 = 59E291838AE2C88F5F71108E4845A84B) but this debug build I compiled has more issues.
I was so happy when I skimmed the doc and got DevIL up and running in like 10 minutes. I figured it was going to save me so much work...
This is making me start to wonder if I should just implement my own image file format (I would use PPM binary and shove it through a compression stream).
edit: source code:
#include "Texture.h" // for Pixel struct
#include "Script.h" // for lua (quick and dirty shell access)
TEST_FIXTURE(ILSystem, ilWritePng) { // ILSystem calls ilInit(), ilShutDown() in ctor, dtor respectively
ILuint image;
ilGenImages(1,&image);
CHECK(ilGetError()==0);
ilBindImage(image);
Pixel pixels[128*128];
for (int i=0;i<128;++i) { for (int j=0;j<128;++j) {
Pixel &p = pixels[i*128+j];
p.b = 0; p.g = i; p.r = j; p.a = 0xff;
}} // neat and simple test image, a greenish purplish gradient type thing.
CHECK(ilTexImage(128,128,1,4,IL_BGRA, IL_UNSIGNED_BYTE,pixels));
CHECK(ilGetError()==0);
{
LuaSystem l;
l.dostring("os.execute(\"rm output_il.tga\")"); // delete that file
}
ilSaveImage("output_il.tga");
PRINT_INT(ilGetError());
}
#ifdef LOAD_DISPLAY
#include "SDLOGL.h"
#include "Texture.h"
TEST_FIXTURE(SDLSystem, loadPNGDisplay) { // takes care of initing SDL and opengl context
ILSystem s; // RAII = peace of mind
// i can't use two fixtures in one unittest. but this does the same thing anyway.
ILuint image;
CHECK(ilGetError()==0);
ilGenImages(1,&image);
CHECK(ilGetError()==0);
ilBindImage(image);
CHECK(ilGetError()==0);
ilLoadImage("folder.bmp");
CHECK(ilGetError()==0);
ILubyte *pixelData = ilGetData(); CHECK(pixelData);
CHECK(ilGetError()==0);
GLuint tex = loadImage32(pixelData,ilGetInteger(IL_IMAGE_WIDTH),ilGetInteger(IL_IMAGE_HEIGHT),0);
// i do not know exactly how its encoded. but it seems like when loading pngs it is in RGBA format
PRINT_INT(ilGetInteger(IL_FORMAT_MODE));
CHECK(ilGetError()==0);
initOrthoRender();
drawTexture(tex);
CHECK(glGetError()==0);
SDL_GL_SwapBuffers();
SLEEP(500);
}
#endif //LOAD_DISPLAY