OpenCV Multithreading error [using Qt] - multithreading

Till now I have learnt one thing, there's something wrong I'm doing with OpenCV, Qt has no role in the error
I'm trying to run two methods in different threads, but it gives me error:
[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
Blurring_Images: ../../src/xcb_io.c:178: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed.
The program has unexpectedly finished.
Here's my code:
void Dialog::blurImages(int b)
{
QtConcurrent::run(this,&Dialog::homogenour_blur,b);
QtConcurrent::run(this,&Dialog::gaussianBlur,b);
}
void Dialog::homogenour_blur(int b)
{
cv::blur(img,img1,cv::Size(b,b));
showImage("Homogenous Blur",img1);
}
void Dialog::gaussianBlur(int b)
{
cv::GaussianBlur(img,img2,cv::Size(b,b),b);
showImage("Gaussian Blur",img2);
}
whereas if i comment out one call(shown below), it runs fine
void Dialog::blurImages(int b)
{
QtConcurrent::run(this,&Dialog::homogenour_blur,b);
//QtConcurrent::run(this,&Dialog::gaussianBlur,b);
}
It's really annoying guys, please help !!
EDIT:
Instead of calling showImage(), I replaced it with the actial OpenCV call(see below):
void Dialog::homogenour_blur(int b)
{
cv::blur(img,img1,cv::Size(b,b));
//showImage("Homogenous Blur",img1);
cv::imshow("Homogenous Blur",img1);
}
void Dialog::gaussianBlur(int b)
{
cv::GaussianBlur(img,img2,cv::Size(b,b),b);
//showImage("Gaussian Blur",img2);
cv::imshow("Gaussian Blur",img2);
}
Now the error I get is:
Original Image: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.
Original Image: Fatal IO error 0 (Success) on X server :0.
Fatal Error: Accessed global static 'KGlobalSettings *s_self()' after destruction. Defined at ../../kdeui/kernel/kglobalsettings.cpp:190
The program has unexpectedly finished.

To all concerned:
fix Jaydeep's problems
[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
and
error: ‘XInitThreads’ was not declared in this scope
by linking X11, including xlib, and calling XInitThreads.
Example for including xlib and calling XInitThreads:
// main.cpp
#include <thread>
#include <X11/Xlib.h>
int main() {
XInitThreads();
// . . .
}
Example for linking:
g++ main.cpp -o my_program -std=c++0x -pthread -lX11 /* -pthread if you're on Linux */
Of course, don't forget to link the other files that may be necessary to your application

imshow() method seems not thread safe. if you use python, it can be solved like this:
self.img_lock = threading.Lock()
with self.img_lock:
cv2.imshow()
cv2.waitKey(1)

Related

Thread safety of std::cout insertion operator

I've always thought that using std::cout << something was thread safe.
For this little example
#include <iostream>
#include <thread>
void f()
{
std::cout << "Hello from f\n";
}
void g()
{
std::cout << "Hello from g\n";
}
int main()
{
std::thread t1(f);
std::thread t2(g);
t1.join();
t2.join();
}
my expectation was that the order of the two outputs would be undefined (and indeed that is what I observe in practice), but that the calls to operator<< are thread safe.
However, ThreadSanitizer, DRD and Helgrind all seem to give various errors regarding access to std::__1::ios_base::width(long) and std::__1::basic_ios<char, std::__1::char_traits >::fill()
On Compiler Explorer I don't see any errors.
On FreeBSD 13, ThreadSanitizer gives me 3 warnings, the two listed above plus the malloc/memcpy to the underlying i/o buffer.
Again in FreeBSD 13, DRD gives 4 errors, width() and fill() times two for the two threads.
Finally FreeBSD 13 Helgrind gives one known false positive related to TLS in thread creation, fill()and width() twice.
On Fedora 34
No errors with g++ 11.2.1 and ThreadSanitizer
DRD complains about malloc/memcpy in fwrite with g++ compiled exe
Helgrind also complains about fwrite and also for the construction of cout, again with the g++ compiled exe
clang++ 12 ThreadSanitizer complains about fill() and width()
DRD with the clang++ compiler exe complains about fill(), width(), fwrite and one other in start_thread
Helgrind with the clang++ exe complains about some TLS, fill(), width(), fwrite
macOS XCode clang++ ThreadSanitizer generates warnings as well (which will be libc++).
Looking at the libc++ and libstdc++ code I don't see anything at all that protects width(). So I don't understand why there are no complaints on compiler explorer.
I tried running with TSAN_OPTIONS=print_suppressions=1 and there was no more output (g++ Fedora ThreadSanitizer)
There does seem to be some consensus over the width() and fill() calls.
Looking more closely at the libstdc++ source I see that there is
(with some trimming and comments):
// ostream_insert.h
// __n is the length of the string pointed to by __s
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
__ostream_insert(basic_ostream<_CharT, _Traits>& __out,
const _CharT* __s, streamsize __n)
{
typedef basic_ostream<_CharT, _Traits> __ostream_type;
typedef typename __ostream_type::ios_base __ios_base;
typename __ostream_type::sentry __cerb(__out);
if (__cerb)
{
__try
{
const streamsize __w = __out.width();
if (__w > __n)
{
// snipped
// handle padding
}
else
__ostream_write(__out, __s, __n);
// why no hazard here?
__out.width(0);
}
__out is the stream object, global cout in this case. I don't see anything like locks or atomics.
Any suggestions as to how ThreadSanitizer/g++ is getting a "clean" output?
There is this somewhat cryptic comment
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>::sentry::
sentry(basic_ostream<_CharT, _Traits>& __os)
: _M_ok(false), _M_os(__os)
{
// XXX MT
if (__os.tie() && __os.good())
__os.tie()->flush();
The libc++ code looks similar. In iostream
template<class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>&
__put_character_sequence(basic_ostream<_CharT, _Traits>& __os,
const _CharT* __str, size_t __len)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
if (__s)
{
typedef ostreambuf_iterator<_CharT, _Traits> _Ip;
if (__pad_and_output(_Ip(__os),
__str,
(__os.flags() & ios_base::adjustfield) == ios_base::left ?
__str + __len :
__str,
__str + __len,
__os,
__os.fill()).failed())
__os.setstate(ios_base::badbit | ios_base::failbit);
and in locale
template <class _CharT, class _OutputIterator>
_LIBCPP_HIDDEN
_OutputIterator
__pad_and_output(_OutputIterator __s,
const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
ios_base& __iob, _CharT __fl)
{
streamsize __sz = __oe - __ob;
streamsize __ns = __iob.width();
if (__ns > __sz)
__ns -= __sz;
else
__ns = 0;
for (;__ob < __op; ++__ob, ++__s)
*__s = *__ob;
for (; __ns; --__ns, ++__s)
*__s = __fl;
for (; __ob < __oe; ++__ob, ++__s)
*__s = *__ob;
__iob.width(0);
return __s;
}
Again I see no thread protection, but also this time the tools detect a hazard.
Are these real issues? For plain calls to operator<< the value of width doesn't change, and is always 0.
libstdc++ does not produce the error while libc++ does.
iostream.objects.overview Concurrent access to a synchronized ([ios.members.static]) standard iostream object's formatted and unformatted input ([istream]) and output ([ostream]) functions or a standard C stream by multiple threads does not result in a data race ([intro.multithread]).
So this looks like a libc++ bug to me.
I got the answer from Jonathan Wakely. Makes me feel rather stupid.
The difference is that on Fedora, libstdc++.so contains an explicit instantiation of the iostream classes. libstdc++.so isn't instrumented for ThreadSanitizer so it cannot detect any hazards related to it.

GoogleTest CMake doesn't recognize TEST_F: Like it's not recognizing GTest something

OK, I admit it, this is a unique case. When we build our application we are using make, so I've included my tests in a test folder under src. Then at the same level as our release folder we have created a unit-test folder that includes all of our source files and our test source files.
But my IDE is CLion, which uses CMake. In my CMakeLists.txt file, I have included:
enable_testing()
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
add_executable(TestProject ${SOURCE_FILES})
target_link_libraries(TestProject ${GTEST_BOTH_LIBRARIES})
I am creating my first Test Fixture. Here is the code:
#include "OPProperties.h"
#include "gtest/gtest.h"
namespace {
// The fixture for testing class OPPropertiesTestTest.
class OPPropertiesTestTest : public ::testing::Test {
protected:
// You can remove any or all of the following functions if its body
// is empty.
OPPropertiesTestTest() {
// You can do set-up work for each test here.
}
virtual ~OPPropertiesTestTest() {
// You can do clean-up work that doesn't throw exceptions here.
}
// If the constructor and destructor are not enough for setting up
// and cleaning up each test, you can define the following methods:
virtual void SetUp() {
// Code here will be called immediately after the constructor (right
// before each test).
}
virtual void TearDown() {
// Code here will be called immediately after each test (right
// before the destructor).
}
// Objects declared here can be used by all tests in the test case for OPPropertiesTestTest.
};
TEST_F(OPPropertiesTestTest, ThisTestWillFail) {
EXPECT_EQ(0, 2);
}
} // namespace
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Here is an image capture:
Notice the syntax checker errors in my TEST_F function. When I started to type TEST_F code completion is trying to find a Boost Test Function.
Can someone tell me what else I need to add to the CMakeLists.txt file or what I am not doing that GTest functions are not being recognized?
As πάντα ῥεῖ pointed out, I hadn't actually tried to build the code. When I did I first received a linker error for pthread, so we added the following line the the CMakeLists.txt file:
target_link_libraries(OnePrint pthread)
Then I tried again to build and received these errors:
/home/user/gtest-1.7.0/lib/.libs/libgtest.so: undefined reference to `pthread_key_create'
/home/user/gtest-1.7.0/lib/.libs/libgtest.so: undefined reference to `pthread_getspecific'
/home/user/gtest-1.7.0/lib/.libs/libgtest.so: undefined reference to `pthread_key_delete'
/home/user/gtest-1.7.0/lib/.libs/libgtest.so: undefined reference to `pthread_setspecific'
collect2: error: ld returned 1 exit status
So, I ran a search on these errors and found this question.
The answer that worked for me was here.

Qt5 and GLEW MX => glewInit fails

We are migrating our project from Qt 4.8 to 5.4. We use multiple contexts in multiple thread. We use GLEW MX for this purpose (We make the context we desire current then call glewInit() on a local instance of GLEWContextStruct).
I'm trying to change QGLWidget and QGLContext to QOpenGLWidget and QOpenGLContext but I ended up not being able to initialize glew anymore.
GLEW doesn't return an error but glGetError() does.
I did install Qt 5.4 64 with OpenGL version.
Here is the code reduced to a minimum :
#include <QtWidgets/QApplication>
#define GLEW_MX
#define GLEW_STATIC
#include <GL/glew.h>
#include <qopenglcontext.h>
#include <qwindow.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
bool errQt;
int errGlew;
GLenum errorGL;
QSurfaceFormat requestedFormat;
requestedFormat.setVersion(3, 3);
requestedFormat.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile);
//Creates the QGLWidget using the current context:
QWindow window;
window.setSurfaceType(QSurface::OpenGLSurface);
window.setFormat(requestedFormat);
window.create();
//Create context
QOpenGLContext context;
context.setFormat(requestedFormat);
errQt = context.create(); //true
//Bind context
context.makeCurrent(&window);
//Glew context creation
GLEWContext* pCtx = new GLEWContext; //All forwards undefined
//Release context
context.doneCurrent();
return 1;
}
Any suggestion ? Is GLEW alright with Qt5.4 ?
EDIT 1 :
It appears the problem is not Qt related. The GLEWContext created doesn't have any function forward defined (all function pointers are undefined). The code has been updated to help the reviewer not lose focus.
I use glewInit() with Qt 5.4 in my project, but I'm using QWindow as my base class, not QOpenGLWidget.
In my ctor I do this:
QRiftWindow::QRiftWindow() {
setSurfaceType(QSurface::OpenGLSurface);
QSurfaceFormat format;
format.setDepthBufferSize(16);
format.setStencilBufferSize(8);
format.setVersion(4, 3);
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile);
setFormat(format);
m_context = new QOpenGLContext;
m_context->setFormat(format);
m_context->create();
...
I execute my OpenGL work on a separate thread. Once the thread has started I call an setup method on my class
m_context->makeCurrent(this);
glewExperimental = true;
glewInit();
glGetError();
I've previously done this exact same setup with OpenGL 3.3 and had no issues.
You should actually get a warning about that:
#warning qopenglfunctions.h is not compatible with GLEW, GLEW defines will be undefined
#warning To use GLEW with Qt, do not include or after glew.h
Your "qopenglcontext.h" includes . To answer your question, you can use Qt + GLEW, but u can't easily mix up Qt-opengl with GLEW.

How to handle V8 engine crash when process runs out of memory

Both node console and Qt5's V8-based QJSEngine can be crashed by the following code:
a = []; for (;;) { a.push("hello"); }
node's output before crash:
FATAL ERROR: JS Allocation failed - process out of memory
QJSEngine's output before crash:
#
# Fatal error in JS
# Allocation failed - process out of memory
#
If I run my QJSEngine test app (see below) under a debugger, it shows a v8::internal::OS::DebugBreak call inside V8 code. If I wrap the code calling QJSEngine::evaluate into __try-__except (SEH), then the app won't crash, but this solution is Windows-specific.
Question: Is there a way to handle v8::internal::OS::DebugBreak in a platform-independent way in node and Qt applications?
=== QJSEngine test code ===
Development environment: QtCreator with Qt5 and Windows SDK 7.1, on Windows XP SP3
QJSEngineTest.pro:
TEMPLATE = app
QT -= gui
QT += core qml
CONFIG -= app_bundle
CONFIG += console
SOURCES += main.cpp
TARGET = QJSEngineTest
main.cpp without SEH (this will crash):
#include <QtQml/QJSEngine>
int main(int, char**)
{
try {
QJSEngine engine;
QJSValue value = engine.evaluate("a = []; for (;;) { a.push('hello'); }");
qDebug(value.isError() ? "Error" : value.toString().toStdString().c_str());
} catch (...) {
qDebug("Exception");
}
return 0;
}
main.cpp with SEH (this won't crash, outputs "Fatal exception"):
#include <QtQml/QJSEngine>
#include <Windows.h>
void runTest()
{
try {
QJSEngine engine;
QJSValue value = engine.evaluate("a = []; for (;;) { a.push('hello'); }");
qDebug(value.isError() ? "Error" : value.toString().toStdString().c_str());
} catch (...) {
qDebug("Exception");
}
}
int main(int, char**)
{
__try {
runTest();
} __except(EXCEPTION_EXECUTE_HANDLER) {
qDebug("Fatal exception");
}
return 0;
}
I don't believe there's a cross-platform way to trap V8 fatal errors, but even if there were, or if there were some way to trap them on all the platforms you care about, I'm not sure what that would buy you.
The problem is that V8 uses a global flag that records whether a fatal error has occurred. Once that flag is set, V8 will reject any attempt to create new JavaScript contexts, so there's no point in continuing anyway. Try executing some benign JavaScript code after catching the initial fatal error. If I'm right, you'll get another fatal error right away.
In my opinion the right thing would be for Node and Qt to configure V8 to not raise fatal errors in the first place. Now that V8 supports isolates and memory constraints, process-killing fatal errors are no longer appropriate. Unfortunately it looks like V8's error handling code does not yet fully support those newer features, and still operates with the assumption that out-of-memory conditions are always unrecoverable.

d2: Calling writefln in D shared libraries from C side

I'm trying to quickstart with dynamic shared libraries in D, but I'm having a problem.
I'm building following code with dmd -shared ./testlib.d:
module testlib;
import std.c.stdio;
extern (C) export int hello(int a) {
printf("Number is %d", a);
return (a + 1);
}
It builds fine, and works. But when I'm trying to make use of following more D'ish source:
module testlib;
import std.stdio;
extern (C) export int hello(int a) {
writefln("Number is %d", a);
return (a + 1);
}
It fails with segmentation fault once I'm trying to call hello. What am I doing wrong?
I'm calling hello using Python:
import ctypes
testlib = ctypes.CDLL('testlib.dylib');
print (testlib.hello(10))
UPD1: Seems that I also cannot use Phobos functions like std.conv.to!(string).
UPD2: There is no such problem on Windows, everything seems to work fine. Mac OS X suffers from this.
UPD3: Possibly, this is connected with GC. I must somehow initialize GC, but core.memory.GC.enable() still fails with segmentation fault.
Solution is simple, yet brilliant:
static import core.runtime;
extern (C) export void init() { // to be called once after loading shared lib
core.runtime.Runtime.initialize();
}
extern (C) export void done() { // to be called before unloading shared lib
core.runtime.Runtime.terminate();
}
Possibly, there are ways in Linux and Mac OS X to call these functions automagically, but I'm satisfied with even this.

Resources