Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

raiseQThreadAffinityException cores java instead of throwing an exception #66

Closed
mchistovib opened this issue Aug 12, 2022 · 37 comments
Closed

Comments

@mchistovib
Copy link

mchistovib commented Aug 12, 2022

Describe the bug
When trying to warn about thread affinity, QTJambi sometimes cores the JVM

To Reproduce
In our not very complicated code, it reporoduces often at random moments

Expected behavior
It should correctly return java exception even if one of thread objects is corrupted

Screenshots
Stacktrace of the exception, it happens at different moments, but stacktrace is always the same:

vcruntime140.dll!__RTtypeid(void * inptr) Строка 166 C++
QtJambi6.dll!qtjambi_from_qobject() + 44 байт Нет данных
QtJambi6.dll!JavaException::raiseQThreadAffinityException() + 90 байт Нет данных
QtJambi6.dll!00007ff81c27645b() Нет данных
Qt6Core.dll!QInternal::activateCallbacks(QInternal::Callback cb, void * * parameters) Строка 4254 C++
Qt6Core.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Строка 1054 C++
[Внедренный фрейм] Qt6Core.dll!QCoreApplication::sendEvent(QObject *) Строка 1475 C++
Qt6Core.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data) Строка 1832 C++
Qt6Gui.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Строка 80 C++
Qt6Core.dll!QEventDispatcherWin32::processEvents(QFlags flags) Строка 476 C++
Qt6Gui.dll!QWindowsGuiEventDispatcher::processEvents(QFlags flags) Строка 73 C++
[Внедренный фрейм] Qt6Core.dll!QEventLoop::processEvents(QFlags) Строка 139 C++
Qt6Core.dll!QEventLoop::exec(QFlags flags) Строка 230 C++
Qt6Core.dll!QCoreApplication::exec() Строка 1382 C++
[Внешний код]

Faulty code:

void JavaException::raiseQThreadAffinityException(JNIEnv* env, const char *message QTJAMBI_STACKTRACEINFO_DECL , jobject t1, QThread* t2, QThread* t3){
    jstring jmessage = message ? env->NewStringUTF(message) : nullptr;
    check(env);
    jthrowable t = Java::QtJambi::QThreadAffinityException::newInstance(env,jmessage, t1,
                                                          qtjambi_cast<jobject>(env, t2),
                                                          qtjambi_cast<jobject>(env, t3)
                                        ); // <-- on this line one of qtjambi_cast throws c++ exception that is not catched and so it crashes jvm
    raiseJavaException( QTJAMBI_STACKTRACEINFO_DECL_USE );
}

System (please complete the following information):

  • OS: Windows
  • Java version 11 Azul
  • QtJambi version 6.2.5
  • Qt version 6.2.5

**Additional information
I assume this happens because our code is actively using threads so some of them are destroyed before raiseQThreadAffinityException is called

@mchistovib
Copy link
Author

Perhaps the fact that it just shows this in logs all the time the app is running is related:
Exception thrown at 0x0000026D234FB7E7 in java.exe: 0xC0000005: Access violation while reading at address 0x0000000000000008.
Thread 0x21e8 exited with code 20115 (0x4e93).
Thread 0x5e54 exited with code 20115 (0x4e93).
Thread 0x6380 exited with code 20115 (0x4e93).
Thread 0x12b8 exited with code 20115 (0x4e93).
Thread 0x5940 exited with code 20115 (0x4e93).
Thread 0x41a8 exited with code 20115 (0x4e93).
Thread 0x4138 exited with code 20115 (0x4e93).
Thread 0x3628 exited with code 20115 (0x4e93).
Thread 0x2eb4 exited with code 20115 (0x4e93).
Thread 0x45ac exited with code 20115 (0x4e93).
Thread 0x102c exited with code 20115 (0x4e93).
Thread 0x2fb4 exited with code 20115 (0x4e93).
Exception thrown at 0x0000026D1C561B18 in java.exe: 0xC0000005: Access violation while reading at address 0x0000026D115B0008.
Thread 0x109c exited with code 20115 (0x4e93).
Thread 0x210c exited with code 20115 (0x4e93).
Thread 0x6264 exited with code 20115 (0x4e93).
Thread 0x6080 exited with code 20115 (0x4e93).
Thread 0x5098 exited with code 20115 (0x4e93).
Thread 0x170c exited with code 20115 (0x4e93).

@mchistovib
Copy link
Author

Is it possible for you to attach .pdb files for qt jambi libs? Without them it's very hard to debug, since I can't use sources and repository code always fails to compile on my visual studio

@mchistovib
Copy link
Author

It also fails like this:

[External code]
vcruntime140.dll!__RTtypeid(void * inptr) Line 166
to d:\a01\_work\4\s\src\vctools\crt\vcruntime\src\eh\rtti.cpp(166)
QtJambi6.dll!qtjambi_from_qobject() + 44 bytes
QtJambi6.dll!JavaException::raiseQThreadAffinityException() + 90 bytes
QtJambi6.dll!00007ff87cac645b()
Qt6Core.dll!QInternal::activateCallbacks(QInternal::Callback cb, void * * parameters) Line 4254
to C:\Users\qt\work\qt\qtbase\src\corelib\global\qglobal.cpp(4254)
Qt6Core.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1054
to C:\Users\qt\work\qt\qtbase\src\corelib\kernel\qcoreapplication.cpp(1054)
[Injected Frame] Qt6Core.dll!QCoreApplication::sendEvent(QObject *) Line 1475
to C:\Users\qt\work\qt\qtbase\src\corelib\kernel\qcoreapplication.cpp(1475)
Qt6Core.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data) Line 1832
to C:\Users\qt\work\qt\qtbase\src\corelib\kernel\qcoreapplication.cpp(1832)
Qt6Gui.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Line 80
to C:\Users\qt\work\qt\qtbase\src\gui\platform\windows\qwindowsguieventdispatcher.cpp(80)
Qt6Core.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 476
to C:\Users\qt\work\qt\qtbase\src\corelib\kernel\qeventdispatcher_win.cpp(476)
Qt6Gui.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 73
to C:\Users\qt\work\qt\qtbase\src\gui\platform\windows\qwindowsguieventdispatcher.cpp(73)
[Injected frame] Qt6Core.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag>) Line 139
to C:\Users\qt\work\qt\qtbase\src\corelib\kernel\qeventloop.cpp(139)
Qt6Core.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 230
to C:\Users\qt\work\qt\qtbase\src\corelib\kernel\qeventloop.cpp(230)
Qt6Core.dll!QCoreApplication::exec() Line 1382
to C:\Users\qt\work\qt\qtbase\src\corelib\kernel\qcoreapplication.cpp(1382)
[External code]

@omix
Copy link
Contributor

omix commented Aug 13, 2022

Thanks for the bug report. I'll look at it on Monday.

As a first impression: It looks like, one of the QThreads is a dangling pointer. Thus typeid(*pointer) crashes. Could you show me the Java code causing this situation?

@mchistovib
Copy link
Author

mchistovib commented Aug 13, 2022

Thus typeid(*pointer) crashes. Could you show me the Java code causing this situation?

Unfortunately there is no a single point of failure, it happens at random moments of interacting with qml components using mouse, sometimes even that is not required and it just crashes right after showing the qml ui.

@omix I believe it would be easy to find exact cause if you could provide .pdb files for msvc_2019 windows build of qtjambi 6.2.5, then I would be able to see what exactly causes it in the debugger

@omix
Copy link
Contributor

omix commented Aug 15, 2022

Please try to run your program with JVM argument -Dio.qt.disable-thread-affinity-check=true. This disables the thread check causing the crash. I assume, then the program will crash due to a thread-affine event call. But however, maybe this crash may at least give you more information. Hopefully.

@mchistovib
Copy link
Author

mchistovib commented Aug 15, 2022

@omix with flag for disabling jambi thread checks, app runs just fine and doesn't crash at all. When I enbled qtjambi thread checks again, I managed to reproduce the crash in a few seconds after the app had started. I suspect jambi is wrong with its' thread check here.

@omix
Copy link
Contributor

omix commented Aug 15, 2022

Can you give me example code to reproduce it?

@mchistovib
Copy link
Author

@omix unfortunately I can't send you soruces right now because they have too9 much company code, but I am trying to reproduce the situation in some demo. Could you please in parallel create .pdb files for qtjamvi v6.2.5? Sources always fail to compile for me for msvc2019 compiler so I can't make them myself.

@mchistovib
Copy link
Author

So far I can tell that it's thrown in

bool qtjambi_thread_affine_event_notify(void **data)
, qtjambi_thread_affine_event_notify method, although I am not sure yet how that happens

@omix
Copy link
Contributor

omix commented Aug 15, 2022

I already identified the line where to expect the crash. Actually, the crash is not caused by the exception but shortly before creating the exception. The exception is actually a Java exception to be caught in Java. However, there is an error with real time type information of one of the thread pointers. It seems one of it is dangling. Well, but that makes no sense because QThread::currentThread() does not return a dangling pointer and also a QObject is always associated to a QThread object, which is therefore never deleted before the last QObject instance is deleted.

Well, there could be one scenario I did not check until now: the QThread is created and deleted in native code (e.g. by QML engine). There is a QObject associated to this thread that survives the deletion of the QThread object. This might be caused by bringing the object to Java or creating it in Java. then, it is managed by Java GC and could survive native QThread.

@omix
Copy link
Contributor

omix commented Aug 15, 2022

Sources always fail to compile for me for msvc2019 compiler so I can't make them myself.

What doesn't work with compiling?
I actually uploaded two bug fixes today for compile issues other people reported recently.

@mchistovib
Copy link
Author

Compile works now.. I'll try to generate .pdbs

@omix
Copy link
Contributor

omix commented Aug 15, 2022

Use QtJambi debug dll's. Therefore, start your program with -Dio.qt.debug=debug.

@mchistovib
Copy link
Author

mchistovib commented Aug 15, 2022

I am already running with -Dio.qt.debug=debug. It didn't add any new information. Vs says "dll was built without symbols information"

@omix
Copy link
Contributor

omix commented Aug 15, 2022

I am not familiar with VS. Do you have Qt Creator?

@mchistovib
Copy link
Author

I've managed to make qt debug flag work, for that you also need to build -debug verion of all jars, forked to a new issue #67

@omix
Copy link
Contributor

omix commented Aug 15, 2022

The pre-configured setting qtjambi.configuration=debug_and_release compiles both debug and release binaries. However, I think you need Qt as debug built as it is shipped by Qt installer.

@omix
Copy link
Contributor

omix commented Aug 16, 2022

Could you send me any example code leading to this bug?
I would like to solve this for the next release I am currently preparing.

@mchistovib
Copy link
Author

@omix I still can't provide you with our internal IB code, however I have found that even when I use qtjambi 6.2.5 built locally in release mode, it almost never crashes. After that I checked and found that latest 6.2.5 jars from Maven are dated by July 5th, whilethis git repo has a lot of bugfixes after that date:
Bugfix Issue #64 Fixed crash of deployer when using self-compiled Qt Peter Droste 8/15/2022 11:25 AM
Bugfix Issue #64 Fixed crash of generator when docs are not available Peter Droste 8/15/2022 10:53 AM
Bugfix Issue #64 Peter Droste 7/27/2022 1:48 PM
Bugfix Issue #62 Peter Droste 7/27/2022 10:47 AM
Patch version 6.3.2a Bugfix Issue #63 Peter Droste 7/26/2022 11:41 AM
Patch version 6.3.2 Peter Droste 7/6/2022 10:16 PM
Patch version 6.3.2 Bugfix Issue #57 Bugfix Issue #56 Bugfix Issue #55 Peter Droste 7/6/2022 10:03 PM

Perhaps one of them also fixed the issue we are seeing now. Could you please repost 6.2.5 jars to Maven?

@omix
Copy link
Contributor

omix commented Aug 17, 2022

I don't think these small bugfixes deal with your issue. However, I inserted a blindfix. I removed the Java convertion for the threads in raiseQThreadAffinityException.

@omix
Copy link
Contributor

omix commented Aug 17, 2022

Do you have an idea what kind of object is used from the wrong thread? Is it QWidget instance?

@mchistovib
Copy link
Author

mchistovib commented Aug 17, 2022

@omix I think it's some qobject from non ui thread passed to QML js function. Unfortunately, it never repoduced for me on debug/release build I made for 6.2.5, only when using jars from maven

@omix
Copy link
Contributor

omix commented Aug 17, 2022

Just to understand, you create a qobject in a thread pass it to QML where you perform actions on the object?
Does the thread have an event loop?

@mchistovib
Copy link
Author

That's a guess, I don't know for sure. Will you upload new 6.2.X qtjambi build?

@omix
Copy link
Contributor

omix commented Aug 17, 2022

Yes, but that takes a while. I am performing last tests. Then I'll continue with release steps. Should be ready until weekend. Hopefully.

@mchistovib
Copy link
Author

@omix this code immediatley crashes when you call dispose() on a running thread. Is this the same behavior as in qt?

import io.qt.core.QThread;
import io.qt.widgets.QApplication;
import io.qt.widgets.QPushButton;
import io.qt.widgets.QVBoxLayout;
import io.qt.widgets.QWidget;

public class AffinityTest {
    public static void main(String[] args) {
        QApplication.initialize(args);
        new MainWin().show();
        QApplication.exec();
        QApplication.shutdown();
    }

    private static class MainWin extends QWidget {
        QThread testThread = new QThread("Bg thread");

        public MainWin() {
            QVBoxLayout layout = new QVBoxLayout(this);
            setLayout(layout);
            QPushButton test = new QPushButton("Test thread affinity");
            layout.addWidget(test);
            //test.clicked.connect(this::testClicked); not needed
            testThread.setDaemon(true);
            testThread.start();
            testThread.dispose(); // crashes right here
        }
    }
}

@omix
Copy link
Contributor

omix commented Aug 18, 2022

Oh, this program even crashes in C++.
Never delete a running thread (dispose() right after start()). Use quit() to exit the thread's event loop. Use join() to make sure the thread finished.

omix added a commit that referenced this issue Aug 19, 2022
Bugfix Issue #60
Bugfix Issue #62
Bugfix Issue #63
Bugfix Issue #64
Bugfix Issue #66
Bugfix Issue #69
@mchistovib
Copy link
Author

hey @omix I see that you've uploaded new 5.15 build, will you also push 6.2 today/on the weekend?

@omix
Copy link
Contributor

omix commented Aug 19, 2022

Yes, it takes a day to upload. I'm just finishing the last artifacts. Then, give the maven database a couple of hours.

@omix
Copy link
Contributor

omix commented Aug 19, 2022

Unfortunately, maven repository blocks me. I can no longer log in and wait for support now. Thus, I am not able to finish release before next week.

@mchistovib
Copy link
Author

mchistovib commented Aug 22, 2022

All of the libs we use made it to maven except for quick-native:
image

@omix
Copy link
Contributor

omix commented Aug 22, 2022

I know. At one position between the 6.2 artifacts the Nexus Repository blocked my account. I'm waiting for support. No response up to now.

@omix
Copy link
Contributor

omix commented Aug 22, 2022

I am in contact with Nexus Respository support. My release request crashed the system. I asked the server to release over 1000 artifacts in short time. That was the reason why they blocked me.
I see about 18 artifacts not handled correctly. qtjambi-quick natives for instance. I hope I will get access again today and then, I will upload these missing components again. I'll let you know.

@omix
Copy link
Contributor

omix commented Aug 22, 2022

I have released the missing components. Should be available in Maven in couple of minutes.

@omix omix closed this as completed Aug 22, 2022
@mchistovib
Copy link
Author

@omix 6.2.6 for quick-native is still not there: https://search.maven.org/artifact/io.qtjambi/qtjambi-quick-native-windows-x64

@mchistovib
Copy link
Author

I'll fork a new issue since this one is closed..

omix added a commit that referenced this issue Jul 25, 2023
Bugfix Issue #60
Bugfix Issue #62
Bugfix Issue #63
Bugfix Issue #64
Bugfix Issue #66
Bugfix Issue #69
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants