Mario.Tapilouw

Tuesday, December 22, 2015

Debugging Multi-Thread Application

Most of the application I develop are running more than one thread with different task for each thread. It might sound ok if the threads are running properly, all the critical sections are not dead locked, and memory are well controlled.

But, sometimes due to deadlines, we forget some parts of the codes and it leads to application crash, memory leak, and the most difficult part is data race problem. These are sorted based on difficulty in debugging.

These several months, I've been struggling hard to read others' code, interpret what they are trying to achieve with the code, how the threads work, how do they synchronize, and how to add another feature to the existing program. And here because it's almost the end of the year, I want to summarize what I learned so far this year.

  1. Application crash is the easiest to debug among all of the three problems I mentioned above. This can be traced quite easily by setting debug points on object creations, every function calls, and object destructions. Usually the error messages gives a clue on what to debug, it takes experience to know what the problem is from the error messages. The more mistakes you make, the more experience you have in interpreting error codes :), but this is not a justification for making mistakes.
  2. Memory leaks is more difficult when it comes to multi threaded applications because the problem might spread with the thread instantiation. The only way to debug this is by checking the source code line by line, making sure that there's always a delete or delete [] for every new or new[].
  3. The data race can be traced by checking all the critical sections and writing a log file for every threads. This is difficult to check because the more threads in the software the more complicated the debugging process is. It become more complicated when the thread is dealing with arrays. Some compilers are not very good in debugging multi threaded application, because the application itself might crash. So, what I did is writing the algorithm into dll, then write some debugging string then use another software to catch the debug strings. In this way, the main threads are not interrupted during debugging and it's much easier to debug the software. The software I am using is called DebugView (https://technet.microsoft.com/en-us/sysinternals/debugview.aspx). It's very convenient to use in debugging algorithm, especially when it is run in thread.

Labels: , , , , ,

Sunday, April 11, 2010

Using Message Map in Borland C++ Builder

If we want to pass information from a thread to the windows, we need to pass it safely. There are several ways that I know on how to perform this. One is by using a Message Map, which is a default message passing method in MFC(Microsoft Foundation Classes), another one is by overriding the Windows Process, i.e. the WndProc function.

There is another way of doing this in Borland C++ builder, but I found it is not stable. I don't know the reason, so I decided to change the other method. Ok, let's start.

First, you need to define the name of the windows message that you want to pass, in order to simplify, give an intuitive name e.g. UPDATE_TIMER

const DWORD UPDATE_TIMER = WM_USER + 1;

then, create a handler function that will process this message, for my application, I use something like this:

void updateTimerProc(CMMTimer &Timer);

CMMTimer is a multimedia timer class wrapper that I used, I downloaded it from this website in codeproject.

then begin delaring the message map

BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(UPDATE_TIMER, CMMTimer , updateTimerProc)
END_MESSAGE_MAP(TForm)


and finally, we have to pass the message to the message map system, this can be performed as follow:

SendMessage(this->Handle, UPDATE_MMTIMER, 0, 0);

Then, one more thing that you have to do is to declare the function to perform some tasks such as updating the UI, etc.

void TFormMain::updateTimerProc(CMMTimer &Timer)
{
//put your code here

}

Call this function from your callback function or your thread. And, Voila! you will get your windows UI updated from the thread.

Labels: , , ,

Friday, September 11, 2009

Real Time chart using OpenCV

If you need a chart that is fast and need to be updated in real time, this article might be useful for you. I have been searching for real time charting but I couldn't find one. But it happened to be creating your own is not that difficult, so why not creating your own charting tools.

What you will need is OpenCV Library that has been installed and configured properly in your computer. If you don't know how to install and configure one, you can start by searching a tutorial using "OpenCV Installation" as the keywords in Google and you will find plenty of them.

Start by creating an object of IplImage, something like this:
IplImage *avtImgProfile;

Then, you might need to define some color lines and font for descriptions, like this:
CvScalar greenLine;
CvScalar redLine;
CvScalar blueLine;
CvScalar whiteLine;
CvFont font;

These color lines and fonts need to be initialized prior to use, the color can be initialize as follow:
greenLine = cvScalar(0, 255, 0);
redLine = cvScalar(0, 0, 255);
blueLine = cvScalar(255, 0, 0);
whiteLine = cvScalar(255, 255, 255);

The font can be initialized as follow:
cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1.0, 1.0, 0, 1, 8);

Then, if you have an array of data, for example from a matrix, you can iterate the data and draw it as a circle, or anything you need. I use circle for simplicity reason.

for(int i=0;icols;i++)
{
int height = avtLineMat->data.ptr[i];
int posx = textOffset + i;
int posy = zeroPos - height;
cvCircle(avtImgProfile, cvPoint(posx, posy), 1, whiteLine, 1);
}

You might need some description about the Chart, the axis and the Title, simply by adding these lines:

cvPutText(avtImgProfile, "Cross Section Profile", cvPoint(200, 15), &font, whiteLine);
cvPutText(avtImgProfile, "Pos.(pixel)", cvPoint(550, 290), &font, whiteLine);
cvPutText(avtImgProfile, "Int.(gray)", cvPoint(10, 15), &font, whiteLine);

And also you might need to add horizontal and vertical axis, such as:
cvLine(avtImgProfile, cvPoint(textOffset , textOffset ), cvPoint(textOffset ,300), whiteLine, 1);
cvLine(avtImgProfile, cvPoint(0, zeroPos ), cvPoint(669, zeroPos ), whiteLine, 1);

Then after finished iterating the data, you can show it using OpenCV display, like this:
cvShowImage("cross section profile", avtImgProfile);

And as a result, you will got is something like this:


So far, this chart can be updated in real time for a 200 fps camera by embedding this function in the callback.

I haven't tried it with a higher speed camera, and I might need to measure the speed of the display and try to make it faster.

Labels: , , , ,

Sunday, May 24, 2009

State Machine

Managing multiple-threaded application is quite tricky.. I spent a lot of time trying to do this and I ended up with an idea of a solution which is based on my previous experience designing hardware on an FPGA, using a state machine which is running on another thread and publishing the state to all the application.

The state machine controls all the thread activity inside the application and all the running thread must send a message to the state machine to change the state. Therefore the state machine acts as the manager of all the threads and by doing so we can control the activity of the threads.

I don't know the correct way of doing such thing, does anybody knows? however, this solution works for me..

Labels: , , ,