Cairo - multithreading - stuck during cairo_image_surface_create - c++

I have multithreaded app where each thread create its own surface, render content, save it and destroy all.
However, after some time (eg. 20 images is saved), the app stucks in _cairo_atomic_init_once_enter from cairo-atomic-private.h.
Here is stack-trace from Visual Studio:
[Inline Frame] app.exe!_cairo_atomic_init_once_enter(unsigned int *) Line 409 C
app.exe!_cairo_image_spans_compositor_get() Line 3135 C
[Inline Frame] app.exe!_cairo_image_surface_init(_cairo_image_surface *) Line 176 C
app.exe!_cairo_image_surface_create_for_pixman_image(pixman_image * pixman_image=0x0000023c1d1f31f0, pixman_format_code_t pixman_format=PIXMAN_a8r8g8b8) Line 197 C
app.exe!_cairo_image_surface_create_with_pixman_format(unsigned char * data=0x0000000000000000, pixman_format_code_t pixman_format=PIXMAN_a8r8g8b8, int width, int height, int stride=-1) Line 355 C
app.exe!cairo_image_surface_create(_cairo_format format, int width, int height) Line 403 C
and I am calling:
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, int(w), int(h));
My parallel loop is done via:
std::vector<int> xSeq(countX);
std::iota(std::begin(xSeq), std::end(xSeq), 0); // Fill with 0, 1, ..., countX.
std::for_each(std::execution::par, std::begin(xSeq), std::end(xSeq), [&](auto x)
{
//create cairo surface, write to it, store it and release it
}
If I run serial version, all is working correctly.
Edit: To store surface to image, I dont use internal PNG saver. I have my own implementation, that is based on:
cairo_surface_flush(surface);
data = cairo_image_surface_get_data(surface);
data contains raw data from cairo and I process them manually and store them with my own compression system.
In some cases, I also use the same system to "inject" data to cairo surface. I obtain data pointer, manually rewrite some pixels and call cairo_surface_mark_dirty(surface) to notify Cairo about the change.

This is not really an answer, but the behaviour you are seeing should be impossible.
_cairo_image_traps_compositor_get has a cairo_atomic_once_t variable that is used to protect some initialisation. Since it is static, we can be sure that no other code touches this variable.
https://github.com/freedesktop/cairo/blob/52a7c79fd4ff96bb5fac175f0199819b0f8c18fc/src/cairo-image-compositor.c#L1270-L1304
_cairo_atomic_init_once_enter checks if the once is already initialised and then just returns 0 / false. Since you say you already had 20 successful calls, the initialisation must already be done. Else, the 20 other calls should not have worked.
https://github.com/freedesktop/cairo/blob/52a7c79fd4ff96bb5fac175f0199819b0f8c18fc/src/cairo-atomic-private.h#L398-L411
Per the above... this should not be possible to occur, right?
Unless something overwrites some memory that it should not touch and the value of the once gets corrupted, or something like that.
Alternatively, this is some kind of mis-compilation that occurs for reasons I do not understand. Did you compile cairo yourself, or where did you get it from?

Related

Malloc Error: OpenCV/C++ while push_back Vector

I try to create a Descriptor using FAST for the Point detection and SIFT for building the Descriptor. For that purpose I use OpenCV. While I use OpenCV's FAST I just use parts of the SIFT code, because I only need the Descriptor. Now I have a really nasty malloc Error and I don't know, how to solve it. I posted my code into GitHub because it is big and I dont really know where the Error comes from. I just know, that it is created at the end of the DO-WHILE-Loop:
features2d.push_back(features);
features.clear();
candidates2d.push_back(candidates);
candidates.clear();
}
}while(candidates.size() > 100);
As you can see in the code of GitHub I already tried to release Memory of the Application. Xcode Analysis says, that my Application uses 9 Mb memory. I tried to debug the Error but It was very complicated and I haven't found any clue where the Error comes from.
EDIT
I wondered if this Error could occur because I try to access the Image Pixel Value passed to calcOrientationHist(...) with img.at<sift_wt>(...) where typdef float sift_wt at Line 56, and 57 in my code, because normally the Patch I pass outputs the type 0 which means it is a CV_8UC1 But well, I copied this part from the sift.cpp at Line 330 and 331 Normally the SIFT Descriptor should also have a Grayscale image or not?
EDIT2
After changing the type in the img.at<sift_wt>(...)Position nothing changed. So I googled Solutions and landed at the GuardMalloc feature from XCode. Enabling it showed me a new Error which is probably the Reason I get the Malloc Error. In line 77 of my Code. The Error it gives me at this line is EXC_BAD_ACCESS (Code=1, address=....) There are the following lines:
for( k = 0; k < len; k ++){
int bin = cvRound((n/360.f)+Ori[k]);
if(bin >= n)
bin -=n;
if(bin < 0 )
bin +=n;
temphist[bin] += W[k]*Mag[k];
}
The Values of the mentioned Variables are the following:
bin = 52, len = 169, n = 36, k = 0, W, Mag, Ori and temphist are not shown.
Here the GuadMalloc Output (sorry but I dont really understand what exactly it wants)
GuardMalloc[Test-1935]: Allocations will be placed on 16 byte boundaries.
GuardMalloc[Test-1935]: - Some buffer overruns may not be noticed.
GuardMalloc[Test-1935]: - Applications using vector instructions (e.g., SSE) should work.
GuardMalloc[Test-1935]: version 108
Test(1935,0x102524000) malloc: protecting edges
Test(1935,0x102524000) malloc: enabling scribbling to detect mods to free blocks
Answer is simpler as thought...
The Problem was, that in the calculation of Bin in the For-loop the wrong value came out. Instead of adding ori[k] it should be a multiplication with ori[k].
The mistake there resulted in a bin value of 52. But the Length of the Array that temphist is pointing to is 38.
For all who have similar Errors I really recomment to use GuardMalloc or Valgrind to debug Malloc Errors.

Memory management using mex files with matlab

I have a mex file that communicates with a uEye USB3 camera, captures a length of video at resolution and framerate specified by the input arguments, and exports it as a stack of .tif images. Before the mex file returns, I free the buffers I was using to store the images in, but this memory doesn't get made available to the system again, it appears to remain allocated to matlab. Further calls of mex functions appear to re-use this memory, but I can't free it to the wider system without restarting matlab. Running clear mex or clear all appear to have no influence on this, indeed clear all occasionally completely crashes matlab with a segmentation fault. I'm pretty sure it's not a fault with my C++ because if I rewrite the same function in straight C++ I see the memory being released as it should be.
My memory is de-allocated using
is_UnlockSeqBuf(hCam, nMemID, pBuffer);
is_ClearSequence (hCam);
int k=0;
while (k < frame_count){
int fMem = is_FreeImageMem(hCam, pFrameBuffer[k], pFrame[k]);
k++;
}
having previously been allocated with
for (int i = 0; i < frame_count;i++){
int nAlloc = is_AllocImageMem (hCam, width,height, 24, &pFrameBuffer[i], &pFrame[i]);
int nSeq = is_AddToSequence(hCam, pFrameBuffer[i], pFrame[i]);
pFrame[i] = i + 1;
}
Does anyone have any ideas on how to release the memory without restarting matlab?

SDL_RenderCopy() has strange behavior on Raspberry PI

This is driving me up the wall..
I've got a very simple SDL2 program.
It has a array of 3 SDL_Texture pointers.
These textures are filled as follows:
SDL_Texture *myarray[15];
SDL_Surface *surface;
for(int i=0;i<3;i++)
{
char filename[] = "X.bmp";
filename[0] = i + '0';
surface = SDL_LoadBMP(filename);
myarray[i] = SDL_CreateTextureFromSurface(myrenderer,surface);
SDL_FreeSurface(surface);
}
This works, no errors.
In the main loop (which is just a standard event loop waiting for SDL_QUIT, keystrokes and a user-event which a SDL_Timer puts in the event queue every second) I just do (for the timer triggered event):
idx = (idx+1) % 3; // idx is global var initially 0.
SDL_RenderClear(myrenderer);
SDL_RenderCopy(myrenderer, myarray[idx], NULL, NULL);
SDL_RendererPresent(myrenderer);
This works fine for 0.bmp and 1.bmp, but the 3rd image (2.bmp) simply shows as a black field.
This is structural.
If I alternate the first 2 images they are both fine.
If I alternate the 2nd and 3rd image the 3rd image doesn't show.
If I use more than 3 images then 3 and upwards show as black.
Loading order doesn't matter. It starts going wrong with the 3rd image loaded from disk.
All images are properly formatted BMP's.
I even saved 2.bmp back to disk under a different name by using SDL_SaveBMP() after it was loaded to make sure it got loaded in memory OK. The new file is bit for bit identical to the original.
This program, without modifications and the same bmp files, works fine on OSX (XCode5) and Windows (VC++ 2012 Express).
The problem only shows on the Raspberry PI.
I have placed explicit error checks on every call that can leave a result/error-code (not shown in the samples above for brevity) but all of them show "no error".
I have used the latest stable source set of www.libsdl.org and compiled as instructed (configure, make, make install, etc.).
Anybody got any idea what could be going on ?
P.S.
Keyboard input doesn't seem to work either on my PI, but I haven't delved into that yet.
Answering myself as I finally figured it out myself...
I finally went back to the README-raspberrypi.txt that came with the SDL2 sources.
I didn't read it carefully enough the first time around...
Problem 1: I'am running on a FULL-HD display. The PI's default GPU memory is 64MB which is not enough for large displays and double-buffering. As suggested in the README I increased this to 128MB and this solved the black image problem.
Problem 2: Text input wasn't working because my user-account was not in the input group. I had added the default "pi" account to the input group initially, but when I later started using another account I forgot to add that user to the group.
In short: Caught by my own (too) quick skimming of the documentation.

Function call causes C++ program to freeze unless stepped-through in debugger

I have this short C++ program which takes snapshot images from a camera in a loop and displays them:
void GenericPGRTest::execute()
{
// connect camera
Camera *cam = Camera::Connect();
// query resolution and create view window
const Resolution res = cam->GetResolution();
cv::namedWindow("View");
c = 0;
// keep taking snapshots until escape hit
while (c != 27)
{
const uchar *buf = cam->SnapshotMono();
// create image from buffer and display it
cv::Mat image(res.height, res.width, CV_8UC1, (void*)buf);
cv::imshow("Camera", image);
c = cv::waitKey(1000);
}
}
This uses a class (Camera) for camera control I created using the Point Grey SDK and functions from the OpenCV library to display the images. I'm not necessarily looking for answers relating to the usage of either of these libraries, but rather some insight on how to debug a bizarre problem in general. The problem is that the application freezes (not crashes) on the cam->SnapshotMono() line. Of course, I ran through the function with a debugger. Here is the contents:
const uchar* Camera::SnapshotMono()
{
cam_.StartCapture();
// get a frame
Image image;
cam_.RetrieveBuffer(&image);
cam_.StopCapture();
grey_buffer_.DeepCopy(&image);
return grey_buffer_.GetData();
}
Now, every time I step through the function in the debugger, everything works OK. But the first time I do a "step over" instead of "step into" SnapshotMono(), bam, the program freezes. When I pause it at that time, I notice that it's stuck inside SnapshotMono() at the RetrieveBuffer() line. I know it's a blocking call so it theoretically can freeze (no idea why but it's possible), but why does it block when running normally and not when being debugged? This is one of the weirdest kinds of behaviour under debugging I've seen so far. Any idea why this could happen?
For those familiar with FlyCapture, the code above doesn't break as is, but rather only when I use StartCapture() in callback mode, then terminate it with StopCapture() before it.
Compiled with MSVC2010, OpenCV 2.4.5 and PGR FlyCapture 2.4R10.
Wild guess ... but may it be that StartCapture already starts the process that
ends up with having the buffer in ìmage, and if you step you leave it some
time until you get to RetrieveBuffer. That's not the case if you run it all at once ...

devIL ilLoad error 1285

I'm Having an issue with loading an image with devIL for openGL
in an earlier part of my project i call
ilInit();
in a function right after i call my load just like this
//generate a texture
ilGenImages( 1, &uiTextureHandle );
//bind our image
ilBindImage( uiTextureHandle );
//load
//ilLoad( IL_PNG, (const ILstring)"fake.png" );
ilLoad( IL_PNG, "fake.png" );
for the sake of error tracking i did place "ilGetError()" after every call
which returned 0 for all of these except for ilLoad which returns 1285
after some searching i figured out that this is a lack of memory error.
so ilLoad always returns 0 and not loaded.
anyone know what im doing incorrect as for my loading or if i forgot to do something
because i feel i might have forgotten something and thats the reason why 1285 appears.
A common reason for ilLoad() to fail with IL_OUT_OF_MEMORY is simply if the PNG file you're using is corrupt.
However, 1285 means IL_INVALID_VALUE - it means the path you're giving it is likely wrong. Try an absolute path (remembering that back slashes aren't okay in C++ unless you use double slashes).
I personally have used DevIL for quite some time and did like it. However, I urge you to consider FreeImage. It has a bit more development going on and is quite stable - I used it in a commercial engine for all my image needs, and it integrates decently well with DirectX/OpenGL much like DevIL.