Release version works unexpectedly - memory races and strange QThread behaviour - c++

I wrote whole application in debug mode and everything works fine in this mode. Unfortunately, now when I trying to run release app two unexpected things happen.
Base information:
Qt 5.1.1
Qt Creator 2.8.1
Windows 7 64x
Application has got second thread which decapsulated data from buffer which is update in main thread.
First problem - memory race:
In one of my methods strange memory race occures in release version - in debug everything is ok. Method looks like:
std::vector<double> dataVec;
std::vecotr<unsigned char> frame("U+014-00300027950l");
//EFrame_AccXPos == 1;
dataVec.push_back(decapsulateAcc(frame.begin()+EFrame_AccXPos));
double Deserializator::decapsulateAcc(std::vector<unsigned char>::iterator pos)
{
const char frac[2] = {*(pos+2),*(pos+3)};
const char integ[] = {*(pos+1)};
double sign;
if (*pos == consts::frame::plusSign) {
sign = 1.0;
} else {
sign = -1.0;
}
double integer = (std::strtod(integ, 0));
double fractial = (std::strtod(frac, 0))/100;
qDebug() << QString::fromStdString(std::string(integ));
//prints "014Rd??j?i" should be "0 ?s"
qDebug() << QString::number(integer);
//prints "14" should be "0"
qDebug() << QString::number(fractial);
//prints "0.14" - everything ok.
return sign*integer+sign*fractial;
}
What wrong with this method?
Second problem:
In additional thread I emit signal to manage data which it decapsulate from buffer. After emit thread wait until flag change to false. When I add some qDebug prints - it's start works, but without them it blocks (even though the flag is already false). Below code:
void DataManager::sendPlottingRequest()
{
numberOfMessurement++;
if (numberOfMessurement == plotAfterEquals ) {
numberOfMessurement = consts::startsFromZero;
isStillPlotting=true;
emit requestPlotting(dataForChart);
//block in next line
while (isStillPlotting);
//it starts work when:
//int i = 0;
//while (isStillPlotting) {
//i++
//if (i == 10000) qDebug() << isStillPlotting;
//}
}
}
void DataManager::continueProcess()
{
plottingState++;
if (plottingState == consts::plottingFinished) {
//program reach this point
isStillPlotting = false;
plottingState = consts::startsFromZero;
}
}

while (isStillPlotting); gets optimized out to if(isStillPlotting)while(true);
you should make isStillPlotting volatile or use an atomicInt instead.
or you can emit a signal plottingDone() from the if in continueProcess() and then connect the slot that executes the code that is after the while

Related

Runtime issues on ARM but runs fine on x86

I recently created an application that I developed on my x86 Linux machine. Basically it's just two threads that communicate over a pipe() with each other. Thread 0 listens on the read end and Thread 1 writes into that pipe. That program worked perfectly fine.
But when I copied the sources over to a RaspberryPi and built it, there were some runtime issues (but compiled with no errors). It seems that thread0 never gets something out of the pipe, it just blocks.
Since pipes are made for Interprocess communication, i thought it would also be thread safe (since there also are two different file descriptors for read and write end).
BUT: Stepping through the program in the Qt Creator debugger on the RPi, everything seemed to work fine! I know the debugger initializing certain variables different can lead to such conditions, but I couldn't find any usages of uninitialized variables etc. in my Code.
thread 1:
void *midiThread(void *fds)
{
midiDevice = ((int*)fds)[0]; // device file for midi input
midiBuffer = ((int*)fds)[1]; // write end of the pipe
unsigned char rawBuffer[MIDI_MSG_LENGTH];
while (read(midiDevice, rawBuffer, MIDI_MSG_LENGTH)
>= MIDI_MSG_LENGTH)
{
struct midievent_t currentEvent;
unsigned char *rawBuffer = (unsigned char *)buffer;
currentEvent.channel = rawBuffer[0] & 0x0f;
// ....
write(midiBuffer, &currentEvent, sizeof(struct midievent_t));
}
close(midiBuffer);
return NULL;
}
main thread:
void MidiInput::createMidiThread()
{
if (pipe(_midiBufferPipe) < 0)
{
// error
}
int fds[2];
fds[0] = _midiFileDescriptor;
fds[1] = _midiBufferPipe[1];
pthread_create(&_midiThreadId, NULL,
midiThread, fds);
}
bool MidiInput::read(midievent_t *event)
{
if (!_initialized)
{
return false;
}
if (read(_midiBufferPipe[0], event, sizeof(struct midievent_t))
< sizeof(struct midievent_t))
{
// some error
return _initialized = false;
}
return true;
}

Why this code doesn't work when "cout"s are commented?

I'm writing a server for an online game based on IOCP, and the core codes handling game message is something like below:
CMessage ret;
int now_roomnum = recv_msg->para1;
int now_playernum = recv_msg->para2;
/*if(true)
{
cout<<"Received Game Message: "<<endl;
cout<<"type2 = "<<recv_msg->type2;
cout<<" player_num = "<<now_playernum<<" msg= "<<recv_msg->msg<<endl;
cout<<endl;
}*/
if(recv_msg->type2 == MSG_GAME_OPERATION)
{
ret.type1 = MSG_GAME;
ret.type2 = MSG_GAME_OPERATION;
while(game_host[now_roomnum].Ready(now_playernum) == true)
{
;
}
//cout<<"Entered from "<<now_playernum<<endl;
game_host[now_roomnum].SetMessage(now_playernum, recv_msg->msg);
game_host[now_roomnum].SetReady(now_playernum, true);
game_host[now_roomnum].SetUsed(now_playernum, false);
while(true)
{
bool tmp = game_host[now_roomnum].AllReady();
if(tmp == true)
break;
}
//cout<<"AllReady from"<<now_playernum<<endl;
string all_msg = game_host[now_roomnum].GetAllMessage();
game_host[now_roomnum].SetUsed(now_playernum, true);
while(!game_host[now_roomnum].AllUsed())
{
;
}
//cout<<"AllUsed from "<<now_playernum<<endl;
EnterCriticalSection(&cs);
game_host[now_roomnum].ClearReady();
LeaveCriticalSection(&cs);
strcpy_s(ret.msg, all_msg.c_str());
//cout<<"Return msg "<<now_playernum<<": "<<ret.msg<<endl;
}
return ret;
Now, the problem is: on a PC, when all cout are commented like above, the game freezes at once; but when I cancel the comments, the server works well.
What's more, when I run the server on my laptop, everything goes fine, no matter whether I comment the cout or not. The main difference between my laptop and PC is that my laptop's OS is Windows 8.1, while the PC is Windows 7.
I'm totally confused. It will be of great help if someone can tell me what to do. Thank you!
Looks like a multithreading issue.
By the way I see you use a Critical section around ClearReady but not when testing for AllReady. That call should be wrapped as well (or, better, write a LockedAllReady that makes use of the lock).
//cout<<"Return msg "<<now_playernum<<": "<<ret.msg<<endl;
What you mean by ret.msg? if msg is method you must do ret.msg(); , is it a field?
If you have this good then like they say above probably a timing problem, try to do cout without ret.msg and see what will happen, and then you know from where the problem is.

C++ Timed Process

I'm trying to set up some test software for code that is already written (that I cannot change). The issue I'm having is that it is getting hung up on certain calls, so I want to try to implement something that will kill the process if it does not complete in x seconds.
The two methods I've tried to solve this problem were to use fork or pthread, both haven't worked for me so far though. I'm not sure why pthread didn't work, I'm assuming it's because the static call I used to set up the thread had some issues with the memory needed to run the function I was calling (I continually got a segfault while the function I was testing was running). Fork worked initially, but on the second time I would fork a process, it wouldn't be able to check to see if the child had finished or not.
In terms of semi-pseudo code, this is what I've written
test_runner()
{
bool result;
testClass* myTestClass = new testClass();
pid_t pID = fork();
if(pID == 0) //Child
{
myTestClass->test_function(); //function in question being tested
}
else if(pID > 0) //Parent
{
int status;
sleep(5);
if(waitpid(0,&status,WNOHANG) == 0)
{
kill(pID,SIGKILL); //If child hasn't finished, kill process and fail test
result = false;
}
else
result = true;
}
}
This method worked for the initial test, but then when I would go to test a second function, the if(waitpid(0,&status,WNOHANG) == 0) would return that the child had finished, even when it had not.
The pthread method looked along these lines
bool result;
test_runner()
{
long thread = 1;
pthread_t* thread_handle = (pthread_t*) malloc (sizeof(pthread_t));
pthread_create(&thread_handle[thread], NULL, &funcTest, (void *)&thread); //Begin class that tests function in question
sleep(10);
if(pthread_cancel(thread_handle[thread] == 0))
//Child process got stuck, deal with accordingly
else
//Child process did not get stuck, deal with accordingly
}
static void* funcTest(void*)
{
result = false;
testClass* myTestClass = new testClass();
result = myTestClass->test_function();
}
Obviously there is a little more going on than what I've shown, I just wanted to put the general idea down. I guess what I'm looking for is if there is a better way to go about handling a problem like this, or maybe if someone sees any blatant issues with what I'm trying to do (I'm relatively new to C++). Like I mentioned, I'm not allowed to go into the code that I'm setting up the test software for, which prevents me from putting signal handlers in the function I'm testing. I can only call the function, and then deal with it from there.
If c++11 is legit you could utilize future with wait_for for this purpose.
For example (live demo):
std::future<int> future = std::async(std::launch::async, [](){
std::this_thread::sleep_for(std::chrono::seconds(3));
return 8;
});
std::future_status status = future.wait_for(std::chrono::seconds(5));
if (status == std::future_status::timeout) {
std::cout << "Timeout" <<endl ;
} else{
cout << "Success" <<endl ;
} // will print Success
std::future<int> future2 = std::async(std::launch::async, [](){
std::this_thread::sleep_for(std::chrono::seconds(3));
return 8;
});
std::future_status status2 = future2.wait_for(std::chrono::seconds(1));
if (status2 == std::future_status::timeout) {
std::cout << "Timeout" <<endl ;
} else{
cout << "Success" <<endl ;
} // will print Timeout
Another thing:
As per the documentation using waitpid with 0 :
meaning wait for any child process whose process group ID is equal to
that of the calling process.
Avoid using pthread_cancel it's probably not a good idea.

How to trace resource deadlocks?

I've wrote a timer using std::thread - here is how it looks like:
TestbedTimer::TestbedTimer(char type, void* contextObject) :
Timer(type, contextObject) {
this->active = false;
}
TestbedTimer::~TestbedTimer(){
if (this->active) {
this->active = false;
if(this->timer->joinable()){
try {
this->timer->join();
} catch (const std::system_error& e) {
std::cout << "Caught system_error with code " << e.code() <<
" meaning " << e.what() << '\n';
}
}
if(timer != nullptr) {
delete timer;
}
}
}
void TestbedTimer::run(unsigned long timeoutInMicroSeconds){
this->active = true;
timer = new std::thread(&TestbedTimer::sleep, this, timeoutInMicroSeconds);
}
void TestbedTimer::sleep(unsigned long timeoutInMicroSeconds){
unsigned long interval = 500000;
if(timeoutInMicroSeconds < interval){
interval = timeoutInMicroSeconds;
}
while((timeoutInMicroSeconds > 0) && (active == true)){
if (active) {
timeoutInMicroSeconds -= interval;
/// set the sleep time
std::chrono::microseconds duration(interval);
/// set thread to sleep
std::this_thread::sleep_for(duration);
}
}
if (active) {
this->notifyAllListeners();
}
}
void TestbedTimer::interrupt(){
this->active = false;
}
I'm not really happy with that kind of implementation since I let the timer sleep for a short interval and check if the active flag has changed (but I don't know a better solution since you can't interrupt a sleep_for call). However, my program core dumps with the following message:
thread is joinable
Caught system_error with code generic:35 meaning Resource deadlock avoided
thread has rejoined main scope
terminate called without an active exception
Aborted (core dumped)
I've looked up this error and as seems that I have a thread which waits for another thread (the reason for the resource deadlock). However, I want to find out where exactly this happens. I'm using a C library (which uses pthreads) in my C++ code which provides among other features an option to run as a daemon and I'm afraid that this interfers with my std::thread code. What's the best way to debug this?
I've tried to use helgrind, but this hasn't helped very much (it doesn't find any error).
TIA
** EDIT: The code above is actually not exemplary code, but I code I've written for a routing daemon. The routing algorithm is a reactive meaning it starts a route discovery only if it has no routes to a desired destination and does not try to build up a routing table for every host in its network. Every time a route discovery is triggered a timer is started. If the timer expires the daemon is notified and the packet is dropped. Basically, it looks like that:
void Client::startNewRouteDiscovery(Packet* packet) {
AddressPtr destination = packet->getDestination();
...
startRouteDiscoveryTimer(packet);
...
}
void Client::startRouteDiscoveryTimer(const Packet* packet) {
RouteDiscoveryInfo* discoveryInfo = new RouteDiscoveryInfo(packet);
/// create a new timer of a certain type
Timer* timer = getNewTimer(TimerType::ROUTE_DISCOVERY_TIMER, discoveryInfo);
/// pass that class as callback object which is notified if the timer expires (class implements a interface for that)
timer->addTimeoutListener(this);
/// start the timer
timer->run(routeDiscoveryTimeoutInMilliSeconds * 1000);
AddressPtr destination = packet->getDestination();
runningRouteDiscoveries[destination] = timer;
}
If the timer has expired the following method is called.
void Client::timerHasExpired(Timer* responsibleTimer) {
char timerType = responsibleTimer->getType();
switch (timerType) {
...
case TimerType::ROUTE_DISCOVERY_TIMER:
handleExpiredRouteDiscoveryTimer(responsibleTimer);
return;
....
default:
// if this happens its a bug in our code
logError("Could not identify expired timer");
delete responsibleTimer;
}
}
I hope that helps to get a better understanding of what I'm doing. However, I did not to intend to bloat the question with that additional code.

MySQL Segfault, Intermittent

I am trying to run through a series of checks/inserts into a MySQL 5.5 db, but I am having frequent yet intermittent issues with SIGSEGV errors. Over the course of many queries being executed, the SELECT statements run just fine. However, after some variable amount of time or number of executed queries (sometimes thousands of checks, sometimes 1 or 2, sometimes not at all and the program exits normally), I inexplicably get a segfault...
Program received signal SIGSEGV, Segmentation fault.
0x100188a8 in mysql_send_query () from K:\Programming\C\Test\libmysql.dll
(gdb) bt full
#0 0x100188a8 in mysql_send_query () from K:\Programming\C\Test\libmysql.dll
No symbol table info available.
#1 0x100188e5 in mysql_real_query () from K:\Programming\C\Test\libmysql.dll
No symbol table info available.
#2 0x00000000 in ?? ()
No symbol table info available.
(gdb)
This is from my heavily reduced code:
int main() {
for (int i = 0; i < 5000; i++) {
int iNewX = GenerateRandomInt(1, 50);
int iNewY = GenerateRandomInt(1, 50);
std::string str = "SELECT * FROM Resources WHERE XPOS = ";
str = str +
StatToString(iNewX) + " AND YPOS = " +
StatToString(iNewY) + ";";
const char * Query = str.c_str();
MYSQL *connect;
connect=mysql_init(NULL);
connect=mysql_real_connect(connect,SERVER,USER,PASSWORD,DATABASE,0,NULL,0);
// Print SQL statment for debugging only...
// This appears to always be good, even in the case of the segfault.
std::cout << Query << std::endl;
if (mysql_query(connect, Query)) {
// Supposed to log an error; I don't get this far...
// This does work when I intentionally break the statement.
std::cout << printf("Failed to SELECT, Error: %s", mysql_error(connect));
std::cout << printf("Query: %s", Query) << std::endl;
mysql_close(connect);
return 0;
}
mysql_close(connect);
}
return 1;
}
I have been unsuccessful in searching online for a case that really matches what I have going on here (though there are lots of MySQL/segfault related forum/Q+A topics/threads). Since this appears to be happening within the .dll itself, how can I fix this?
Can anyone explain why the issue seems to come and go?
I have not yet tried to reinstall MySQL, as that will likely be a very big headache that I would rather avoid. If I must, then I must.
If I am missing any details in my question or any pertinent code, please let me know and I will add.
After following Christian.K's advice, I was able to see that this was error 23 (as returned by mysql_error(connect)) after connect=mysql_init(NULL).
This led me to a few resources, most clearly, this one. This says that this is a know problem when working within Windows, and there's not much I can do about this.
You might get around the open file limit (error 23) by not opening a connection for every loop iteration (which is questionable anyway), but rather use one connection for all loop iterations.
Together with my comments about error handling, and the strange cout << printf use you end up with something like this:
int main() {
MYSQL *connect;
connect=mysql_init(NULL);
if (connect == NULL)
{
printf("Insufficient memory to initialize.\n");
return 1;
}
connect=mysql_real_connect(connect,SERVER,USER,PASSWORD,DATABASE,0,NULL,0);
if (connect == NULL)
{
printf("Could not connect: %s\n", mysql_error(connect);
return 1;
}
for (int i = 0; i < 5000; i++) {
int iNewX = GenerateRandomInt(1, 50);
int iNewY = GenerateRandomInt(1, 50);
std::string str = "SELECT * FROM Resources WHERE XPOS = ";
str = str +
StatToString(iNewX) + " AND YPOS = " +
StatToString(iNewY) + ";";
const char * Query = str.c_str();
if (mysql_query(connect, Query)) {
// Supposed to log an error; I don't get this far...
// This does work when I intentionally break the statement.
printf("Failed to SELECT, Error: %s", mysql_error(connect));
printf("Query: %s", Query);
mysql_close(connect);
return 1;
}
}
mysql_close(connect);
return 0;
}
Note that I also changed the return values. Per convention main() should return 0 on success and something else (mostly 1) otherwise.