Skip to content

Commit

Permalink
Avoid calling QMetaObject::invokeMethod in variadic form
Browse files Browse the repository at this point in the history
Since Qt 6.5 there is a new variadic version of the
QMetaObject::invokeMethod() method [0].
Generally this is a good idea, as this fixes the problem of being able
to pass a maximum number of only 10 arguments to invokeMethod().

However for usage in GammaRay this poses a problem:
When we call invokeObjectLocal() from within the inspected process, we
can no longer just dump all arguments, as the variadic invokeMethod()
version will then always attempt to call a version of the method with
exactly 10 arguments of type GammaRay::MethodArgument [1].

The fact that the argument number is fixed (and usually wrong) is not
the main problem here, as it could easily be worked around by adding 10
if branches that select the appropriate invokeMethod() with the correct
arity.

The more serious problem is that the argument type is always fixed to
GammaRay::MethodArgument [2].
We can't easily work around this as Q_ARG() wrappers and similar
shenanigans need the type at compile time, but we don't know the type at
compile time.

Luckily the non-variadic version of QMetaObject::invokeMethod still
exists, so as a workaround we force the usage of the non-variadic
version by explicitly passing the arguments as QGenericArgument.

Note that this version of QMetaObject::invokeMethod is obsolete since Qt
6.5 and might be removed with Qt 7.0, in which case we need to find a
better fix.

As for the actual implementation in this patch, note that we need to
store the MethodArgument first and can't just construct the
QGenericArgument directly.
Alternatively we could wrap every parameter in the function call to
invokeMethod() with QGenericArgument(), but using a second array is a
little bit cleaner code-wise.

Fixes #777
Fixes #761

[0] https://codereview.qt-project.org/c/qt/qtbase/+/422745
[1] see #777 (comment)
[2] e.g.: QMetaObject::invokeMethod: No such method GammaRay::ToolManagerClient::availableToolsResponse(GammaRay::MethodArgument)
	Candidates are: availableToolsResponse(QList<GammaRay::ToolData>)
  • Loading branch information
vimpostor committed Apr 17, 2023
1 parent 9eb3f01 commit a5a17b1
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions common/endpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,14 @@ void Endpoint::invokeObjectLocal(QObject *object, const char *method,
{
Q_ASSERT(args.size() <= 10);
QVector<MethodArgument> a(10);
QVector<QGenericArgument> g(10);
for (int i = 0; i < args.size(); ++i) {
a[i] = MethodArgument(args.at(i));
g[i] = QGenericArgument(a[i]);
}

QMetaObject::invokeMethod(object, method, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8],
a[9]);
QMetaObject::invokeMethod(object, method, g[0], g[1], g[2], g[3], g[4], g[5], g[6], g[7], g[8],
g[9]);
}

void Endpoint::addObjectNameAddressMapping(const QString &objectName,
Expand Down

0 comments on commit a5a17b1

Please sign in to comment.