Details
-
Bug
-
Resolution: Unresolved
-
P1: Critical
-
None
-
6.8
Description
Floating point arguments to JNI native function get corrupted when registering them via Q_JNI_NATIVE_METHOD on x86_64 (at least, I have not investigated other architectures).
There are only two affected functions in qtbase AFAICS, both related to display properties. This can be practically observed in e.g. the x86_64 Android 15 emulator image, where Qt apps get a negative physical display size due to this and thus break spectacularly. Bypassing Q_JNI_NATIVE_METHOD and registering those functions directly fixes the problem.
The reason for this seems to be the variable argument wrapper functions that Q_DECLARE_JNI_NATIVE_METHOD generates, as those have different calling conventions compared to fixed argument functions. And as the function is eventually passed without type information to JNI, the caller there has no chance to consider this anymore.
The following code shows this problem also on Linux/x86_64 (other platforms/architectures not tested):
#include <cstdarg> #include <iostream> void f1(int arg1, double arg2) { std::cout << "fixed arg " << arg2 << std::endl; } void f2(int arg1, ...) { va_list args; va_start(args, arg1); auto arg2 = va_arg(args, double); std::cout << "var arg " << arg2 << std::endl; va_end(args); } void callF(void* func) { reinterpret_cast<void(*)(int, double)>(func)(23, 42.0); } int main(int argc, char** argv) { callF((void*)&f1); // works callF((void*)&f2); // prints garbage }
Assuming the above analysis is correct, this is particularly nasty as it doesn't leave an obvious way for fixing Q_JNI_NATIVE_METHOD.
Attachments
Gerrit Reviews
For Gerrit Dashboard: QTBUG-132410 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
613552,1 | JNI: don't cast function pointers to void *, use JNICALL | dev | qt/qtbase | Status: NEW | +1 | +1 |