Unsolved QWebEnginePage runJavaScript callback
-
We had some seg faults in a QWebEnginePage::runJavaScript callback. I tracked it down to an invalid QWebEnginePage pointer.
Example:page()->runJavaScript("// JavaScript code here", QWebEngineScript::ApplicationWorld, [this](const QVariant& data) { page()->scrollPosition(); // sometimes seg fault because page() returns an invalid pointer }
Why is the page which triggers the callback invalid in its own callback? Is there a way to make this code safe?
-
@Christoph-Schaefer said in QWebEnginePage runJavaScript callback:
Is there a way to make this code safe?
Check the pointer before dereferencing it.
Also what is page() here? -
@Christoph-Schaefer
Have you verified (you may have done so) that in your callback it is definitelypage()
which is seg faulting? Are you sure it is not thescrollPosition()
which is faulting (e.g. because you are trying to call it at the wrong time)? -
The this pointer is a QWebEngineView:
QWebEngineView* v = new QWebEngineView(); v->page()->runJavaScript("// JavaScript code here", QWebEngineScript::ApplicationWorld, [v](const QVariant& data) { v->page()->scrollPosition(); // sometimes seg fault because page() returns an invalid pointer }
I ask this question because I am not sure if I do something wrong if I have to check the pointer. For me it is unexpected that Qt offers a method
void QWebEnginePage::runJavaScript(const QString &scriptSource, quint32 worldId, const QWebEngineCallback<const QVariant &> &resultCallback)
and inside the resultCallback the page in which the JavaScript was executed sometimes doesn't exist anymore. But if you say that's the intended behavior, I close the question. Thank you!
-
@Christoph-Schaefer I don't know whether this is intended behaviour. Could be a bug (check Qt bug-tracker). Or maybe script couldn't be executed correctly and the page was invalidated?
-
@JonB
It is definitely page(). The codev->page();
also seg faults.
I can reproduce it when the JavaScript execution takes very long and the page is deleted while JavaScript is still running. By deleting the page, the JavaScript is aborted and triggers the resultCallback. In this case the page pointer is invallid. -
@Christoph-Schaefer said in QWebEnginePage runJavaScript callback:
v->page();
If this segfaults then most probably v is invalid pointer
-
I can reproduce it when the JavaScript execution takes very long and the page is deleted while JavaScript is still running. By deleting the page, the JavaScript is aborted and triggers the resultCallback. In this case the page pointer is invallid.
And is this what is happening in your case?
Also, at least OOI, what is it that your JavaScript code actually does? You seem to be trying to query
scrollPosition()
very early (not that I'm saying that's the seg fault), though maybe you know what you are doing... -
@jsulm
v is valid. It is captured in the lambda. When I check if v is valid, I got a warning: 'v' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true. -
@Christoph-Schaefer Well, the pointer itself can still be valid but not the object it is pointing to (for example if it was deleted). Can you try to call something else on it v->...?
-
@jsulm said in QWebEnginePage runJavaScript callback:
@Christoph-Schaefer Well, the pointer itself can still be valid but not the object it is pointing to (for example if it was deleted). Can you try to call something else on it v->...?
That's it. The v pointer is valid but the entire QWebEngineView behind it is gone.
v->title();
also crash.
Still, unexpectedly, Qt does not ensure that the sender and receiver exist in the runJavaScript callback. -
@Christoph-Schaefer It's indeed strange behaviour. Could be a bug.
-
I reported a bug for this QTBUG-72816.