Synchronizing output between a main program and a QProcess? - c++

I'm building a program that performs some users tests and needs to record data on what they are doing at very small intervals (every 10ms). Most of the data can be found from QT, but unfortunately I need to use a separate program to calculate mouse movement (I need to get movement even when the mouse has already hit the edge of the screen, but QT just ignores off-screen movement).
Therefore I've built a windows program that deals with the low level mouse input and outputs the changes in coordinates detected. The problem however, is that I can't get the data from the windows program to line up with the output from the main program.
In my main program, I use the follow code.
mouseTracker = new QProcess();
mouseTracker->start("C:\\WindowsFun.exe",QIODevice::ReadWrite|QIODevice::Unbuffered);
mouseTracker->setProcessChannelMode(QProcess::MergedChannels);
connect(mouseTracker,SIGNAL(readyRead()), this, SLOT(readMouseData()),Qt::DirectConnection);
and the readMouseData function looks like this.
void HideWindow::readMouseData(){
QByteArray data = mouseTracker->readAll();
QString text = QString(data);
saveFileStream << text.toStdString();
}
Some of this stuff might be unnecessary. I added in the "MergedChannels" mode and the "DirectConnection" bit in an attempt to solve the problem.
The result I'm getting is that the output from the windows program shows up in large blocks every 100ms or so, rather than being inserted into the filestream right when it occurs. It seems like there is a buffer somewhere that needs to fill, or a delay before the readyRead() signal is processed. Does anyone have any suggestions for how I can get the output from both the main program and the QProcess in real time? (Well, at least with a delay less than 10ms).
Also, if it is important, I am running Windows 7 and using MinGW for compilation of the main program and Visual Studio 2008 for the windows program that detects mouse movement. The output in windows look like this:
int xPosRelative = raw->data.mouse.lLastX;
int yPosRelative = raw->data.mouse.lLastY;
char output[100];
int n;
n = std::sprintf(output,"%d %d",xPosRelative,yPosRelative);
std::printf("%s\n",output,n);
std::fflush(0);
Let me know if anymore information is needed.
Thanks,
-Keilan

Unfortunately, the Windows implementation of QProcess is hard-coded to check once every 100 milliseconds for stdout/stderr from the external process. Looking through the Qt code, you may be able to get around this by calling waitForReadyRead frequently (with a small timeout value).

I would never depend on the standard input/output of a process on Windows. It seems that there are some limitations to the performance that hit me multiple times, even without Qt getting involved.
You'll do perfectly fine using a network connection on a localhost. That's the most universal and portable interprocess means of communication. Everything that Qt runs on supports it, and the performance is expected to be the same ballpark on each platform.

Related

Debugging a Win32 application c++

My application started life as a c++ Console application in VS2019. Code was provided as part of an SDK. Worked perfect. Great response from the manufacturer USB device. Later, I wanted to graduate is to a GUI application, much as I've been doing in VB and c#. Lo and behold, I managed to reconstruct the application in both Qt and Win32 but I'm running into a situation where the application becomes unresponsive and I have no way to tell what's going on.
In the Console application, I have to execute this code to interface with the device AFTER sending a "TakeMeasurement" command :
if (SDK_SUCCESSFUL(sdkError)) {
printf("\nWaiting for measurement to complete...\n");
while (!isMeasureWait) {
if (isDisConnect) break;
this_thread::sleep_for(chrono::milliseconds(1000));
}
}
This code works like a charm! Ater one or two iteration, the device has completed the measurement and I can get to the data easily.
On the Win32 side, I use the exact same code. Only, once control enters the loop, it never returns.
Any idea how I could diagnose the error? I have the impression that the "timing" is critical, between the exact moment where the Measurement command is initiated to the exact moment the instrument signals that it's done, and the data ready to be picked up.
My naive hypothesis is that, in debug mode on both 'platforms', I must be getting some timing differences? Sadly, I can't get more information from the manufacturer in this regard but I suspect I have a small window of time within which the instrument's response can be acted on? And I begin to suspect that, on Win32, that "time" is too long? Compared to on the Console side?
I was thinking of, perhaps, "measuring" that time, in milliseconds? First, on the Console side, to see what kind of delay "works", and then, to see how the delay compares with the Win32 side.
I may be wasting my time and I sure don't mean to waste yours.
How would I go about getting an idea of time elapsed in a c++ application? I'll take a look around VS2019, they have all kinds of "performance" things that popup at run time?
Any help is appreciated.
I am not sure I completely understand what is going on.
Execution of the thread wait loop was not not the culprit.
I'm not 100% sure but what happens is that, in my 'Export data to CSV TEXT file', if I tried to execute the call to :
SetWindowText(hEditMeasure, wMeasurements);
The application always hung. I placed breakpoints right before the call in the code, to trace execution, and it did not strike me at first but, in VS toolbar, there was a "thread" comboBox? With the value showing = DEVICE.DLL? and to its right, the name of my Export function as the Stackframe. In searching for additional information on the setWindowText function, I came accross the reference to use VM_SETTEXT to send to "different application"? Could it be unknowingly I was sending a message to "another thread", the DLL thread? And that's why it hung? I did not know enough to tell. So I started to move the setWindowText line around, ultimately inside the code that is called by the "Measure" button, and it worked!
I'm not out of the woods yet but I feel I'm making progress. Thank you all for your help and patience.

QT5.3.2 + VTK6.1 C++ program quits randomly after long time running

I have a C++ program written together with QT5.3.2 + VTK 6.1. The program compiles fine and can run after deployment. Each function button also works fine.
The problem happens when I run this program for weeks (its a motion control software, so it needs to be on for a long time). Randomly(probably not random at all...) it quits/crashes without a frozen window. In another word, the program window just closes and no error message window appears.
I met the memory leak issue before, the program window first froze and the cursor kept busy status and unresponsive. But this time it just closes itself without any error message or unresponsiveness.. Could this also be a memory leak issue?
So I really appreciate it if someone can give me some hint or direction to troubleshoot this issue by their rich experience in programming.
Since there is a lot of code and I do not know where the problem comes from. I will not post code for now but I am happy to include some key aspects:
It uses ADS communication to communicate with hardware drives.
Callback function to fetch the monitoring data and display in QT interface, meaning a lot of actions like LineEdit->SetText() are used repeatedly. SetText() is called with a global qapplication pointer *tp->SetText().
VTK just displays the 3D data. And I separately tested there is no memory leak.
I am happy to share more information if needed.
Memory leak test.

SDL2 hardware accelerated renderer crashes linux when using Proprietary drivers on xubuntu 12.04?

I am creating a small 2D game library (That's right world, another one!) in C++ using SDL and I finally got around to testing its current state (very much a work in progress) on linux(xubuntu 12.04). Up until now I have mostly been working on my Windows 10 install. Note: My linux and windows 10 installs are on the same machine.
At first I was using the xorg nvidia driver, my code was using hardware accelerated rendering (i.e. using the SDL_RENDERER_ACCELERATED flag when creating the SDL_Renderer) but when I ran my code I was getting poor frame rate ~100FPS, bear in mind that at this point I am only testing it by drawing one little animation on screen and on windows I was getting ~1200FPS.
I had the idea that it may be because of the graphics driver. So I switched to the recommended nvidia proprietary driver for my GPU, restarted, recompiled, and ran my game again. Then an empty window appeared, my computer froze but the FPS counter in the window title reported ~15000 FPS (woohoo!). I sighed, began bashing on my keyboard, ctrl-alt-del logged me out, and I logged back into the same frozen screen as before.
After a hard-restart I examined my test program's log and it reported that it successfully entered the game loop i.e. began rendering frames.
Now, if I add a delay in the main loop or use vsync everything is fine (and faster when using the proprietary nvidia driver), no crashes. Everything as defined.
I am confused as to what is happening, I know that my program is trying to go as fast as it can if I don't have a sleep in there but I wouldn't have thought the scheduler would give it so much processor time as to neglect the rest of the system. I tried looking into the differences between the Windows and linux schedulers but I can find a solid reason as to why my program would runaway on linux.
You can view the library code here: https://github.com/callumW/Howler the library is in Howler/ and the test program is in testsrc/ the main loop being in Game.cpp: run().
(As a side note, if you have any suggestions to the library code I would be glad to receive them).
Does anyone have any ideas as to what is happening?
It is evident that I need to cap the frame rate, and seeing as I'm not short of FPS that is not an issue. I also assume this is good practice as to not use power unnecessarily. But this peaked my interest and I wondered if anyone had an answer for me.
Hint for the future - there is no need to reboot. Enable X kill sequence (usually ctrl-alt-backspace, but disabled by default in modern distros, you have to enable it manually) as last resort, but usually it is just ctrl-alt-f1, login to tty, kill offending process, then return back to X with ctrl-alt-fN (the number of tty where X sits, most often 7). If you're working with graphics you probably will need that sooner or later.
Not sure if your problem was exactly the same as I've seen when running your program, but it is very likely so. You display FPS in window title, sending it to window manager on each frame, 15 thousands times per second. Window manager gets confused by so many window title updates (at least openbox does. Haven't tested with different WMs). Not sure if it will eventually flush accumulated changes or just hang forever; didn't wait.
Basically don't update window title more often than 10 times per second.
I'd add SDL_Delay() inside the main loop. Something like :-
while(running) {
while(SDL_PollEvent(&e) != 0) {
if(e.type == SDL_KEYDOWN) {
if(e.key.keysym.sym == SDLK_ESCAPE) {
running = false;
break;
}
}
else if(e.type == SDL_QUIT) {
running = false;
break;
}
}
update();
frames++;
//Add a delay here
SDL_Delay(0);
}
This is to give the cpu time back to the OS. In some OS (like older Windows if I'm not mistaken) if you infinitely spin loop, your application will freeze, the OS would think your application is unresponsive and will try to kill it. Etc.
I'm not really sure if this is your case, give it a try. You might want to change the value of the parameter (essentially it's the length of time you want to delay, though it's not guaranteed to be exact). I usually use 0 or 1 in the case that I don't want to limit the framerate. 13 will cap your framerate at around 60fps.

Heisenbug issue with using a dll. What do I do next?

I am working on a system that uses a Voltage Controlled Oscillator chip (VCO) to help process a signal. The makers of the chip (Analog Devices) provide a program to load setup files onto the VCO but I want to be able to setup the chip from within the overarching signal processing control system. Fortunately Analog Devices also provides a DLL to interface with their chip and load setup files myself. I am programming in Visual C++ 6.0 (old I know) and my program is a dialog application.
I got the system to work perfectly writing setup files to the card and reading its status. I then decided that I needed to handle the case where there are multiple cards attached and one must be selected. The DLL provides GetDeviceCount() which returns an integer. For some reason every time the executable runs it returns 15663105 (garbage I assume). Whenever I debug my code however the function returns the correct number of cards. Here is my call to GetDeviceCount().
typedef int (__stdcall *GetDeviceCount)();
int AD9516_Setup()
{
int NumDevices;
GetDeviceCount _GetDeviceCount;
HINSTANCE hInstLibrary = LoadLibrary("AD9516Interface.dll");
_GetDeviceCount = (GetDeviceCount)GetProcAddress(hInstLibrary,"GetDeviceCount");
NumDevices = _GetDeviceCount();
return NumDevices;
}
Just to be clear: every other function from the DLL I have used is called exactly like this and works perfectly in the executable and debugger. I did some research and found out that a common cause of Heisenbugs is threading. I know that there is some threading behind the scenes in the dialogs I am using so I deleted all my calls to the function except one. I also discovered that the debugger code executes slower than executable code and I thought the chip may not have enough time to finish processing each command. First I tried taking up time between each chip function call by inserting an empty for loop and when that did not work I commented out all other calls to the DLL.
I do not have access to the source code used to build the DLL and I have no idea why its function would be returning garbage in the executable and not debugger. What other differences are there between running in debugger and executing that could cause an error? What are some other things I can do to search for this error?
Some compilers/IDEs add extra padding to variables in debug builds or initialize them to 0 - this might explain the differences you're encountering between debugging and "normal" execution.
Some things that might be worth checking:
- are you using the correct calling convention?
- do you get the same return value if no devices are connected?
- are you using the correct return type (uint vs int vs long vs ..)?
Try setting _GetDeviceCount to 0 before calling the function; that could be what the debugger is doing for you.

Why is my paintBox Canvas being erased when my program is "Not Responding"?

I have written a small program using Borland's C++ builder, and along the way, everything seemed fine. My program has a map window and a table window, and when a user presses a button, a long process is started that reads in all the map and table information and then displays that. Every time i ran it through the debugger, I had no issues. Then today, I decided to test it without running it through the debugger. To my horror, The program reads in the map information and then displays it on the paintbox canvas without a problem, but when it loads the information for the grid, the map gets erased!!! It appears to happen during the load phase for the table. this takes about 4 seconds, and during which time, the window tells me that it isnt responding. This is when the map gets erased. Anyone have any ideas on why this is happening? Its driving me nuts, and I dont really understand whats going on under the hood here.
UPDATE:
I have fixed the problem to some degree. I was poking around and found this: Avoiding "(Not Responding)" label in windows while processing lots of data in one lump
I added the code to run once in the middle of the data read in for the table. this fixed my problems. however, I was wondering if anyone knows why this is the case? why does my program going unresponsive cause my canvases to be erased?
Marcus Junglas wrote a detailed explanation of the problem, which affects both Delphi and C++Builder.
When programming an event handler in
Delphi (like the OnClick event of a
TButton), there comes the time when
your application needs to be busy for
a while, e.g. the code needs to write
a big file or compress some data.
If you do that you'll notice that your
application seems to be locked. Your
form cannot be moved anymore and the
buttons are showing no sign of life.
It seems to be crashed.
The reason is that a Delpi application
is single threaded. The code you are
writing represents just a bunch of
procedures which are called by
Delphi's main thread whenever an event
occured. The rest of the time the main
thread is handling system messages and
other things like form and component
handling functions.
So, if you don't finish your event
handling by doing some lengthy work,
you will prevent the application to
handle those messages.
You can reduce the problem by calling Application->ProcessMessages(), while loading your map data, however I recomend using a separate thread to load the data.
I have never used C++ Builder, but i used Delphi. I think the libraries are the same.
Does that component you use store the image data? It may only draw to the screen. Try covering the window of your app with another window. If it erases it, you have to use a component which stores the image.
See this, it is for Delphi, but it may help. There should be a Image component in C++ Builder. Try using that instead of PaintBox.
You can solve the unresponsivenes problem by running the time consuming task in a separate thread or calling some function that processes the window's messages.