I am seeing a strange crash in a Qt app that I am working on, and I am wondering if anyone has seen something similar or knows what the reason could be.
The crash is due to an access violation and occurs in around 30% of the cases when a call to QMessageBox::question() is made. The app only crashes in Release mode (never in Debug).
The code that causes the crash looks completely innocuous:
QMessageBox::question(
this,
QString("Deleting configuration"),
QString("Are you sure you want to delete this configuration?"));
It does not matter if the dialog is created with a static function call (like above) or explicitly. Other standard dialogs that have an icon (QMessageBox::critical(), QMessageBox::information(), etc.) also cause this crash, but interestingly a default QMessageBox dialog without any icons never crashes. However, the crash appears again after adding a standard icon through setIcon():
QMessageBox dialog;
dialog.setText("Blah blah blah");
dialog.setIcon(QMessageBox::Question);
dialog.exec();
Could it have something to do with the standard icons in these dialogs? The crash only occurs on the first dialog display; once a single dialog has displayed without a crash, all subsequent ones will work fine.
The Qt version is 5.12.2 and the app is compiled with the Visual Studio 2017 x64 C++ compiler.
Related
I have created a File Explorer context menu extension that uses the IExplorerCommand interface to add menu commands to the Windows 11 context menu.
This has been working fine, but after the last Windows update, it no longer works properly.
Although the menu commands still appear, nothing happens when I click on any of them. I've added logging and I can see that IExplorerCommand::Invoke() is no longer being called.
Strangely, if I select the "Show more options" menu to get the legacy Windows 10 context menu, the commands work fine from that menu, it is only in the new Windows 11 context menu that they don't work.
I have tried running File Explorer in a debugger while selecting my menu commands, and I get lines like this in the output window when I click on the command:
onecore\com\combase\dcomrem\stdid.cxx(726)\combase.dll!00007FF9EB9947F5: (caller: 00007FF9C22E1E38) ReturnHr(2627) tid(67bc) 8001010E The application called an interface that was marshalled for a different thread.
I'm guessing this is the reason why my commands are not being called. Does anyone have any suggestions for what is causing this? Could it be a bug in File Explorer?
I've tried both STA and MTA threading models, and changing this made no difference.
Well, after wasting hours on this I finally have a solution!
My code was based on the PhotoStoreContextMenu sample code here:
https://github.com/microsoft/AppModelSamples/tree/master/Samples/SparsePackages/PhotoStoreContextMenu
This uses the Windows Runtime C++ Template Library (WRL), and defines the base classes used by the class like this:
class TestExplorerCommandBase : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IExplorerCommand, IObjectWithSite>
The change that fixed it for my code was to use WinRtClassicComMix instead of ClassicCom, i.e.
class TestExplorerCommandBase : public RuntimeClass<RuntimeClassFlags<WinRtClassicComMix>, IExplorerCommand, IObjectWithSite>
I'm pretty sure this problem started when I installed KB5019509, which is the Windows update that changes File Explorer so that it now has tabs.
Note: this problem only happens for IExplorerCommands created in the plug-in for submenus, the top level commands that are defined in the APPX file work fine.
Also note that although this change does fix the problem with Invoke() not being called, it does introduce a new problem which is that IOleWindow::GetWindow() no longer works so it is not possible to get the parent HWND. (See Calling IOleWindow::GetWindow() from IExplorerCommand::Invoke() is giving error 8001010d (RPC_E_CANTCALLOUT_ININPUTSYNCCALL)).
I have asked the question QWidget::repaint: Recursive repaint detected on Windows in Debug without creation of new threads. It turned out that the crash (on Windows in DEBUG mode) is due the fact that auto-generated ui file contained:
<widget class="QToolButton" name="button_logout">
</widget>
which would generate the code
QToolButton *button_logout;
button_logout = new QToolButton(widget_session_list);
button_logout->setObjectName(QString::fromUtf8("button_logout"));
header_layout->addWidget(button_logout);
So having a clicked event due to this connection:
...
connect(_ui->button_logout, &QToolButton::clicked, this, &ViewImpl::performLogout);
...
void ViewImpl::performLogout()
{
emit onLogout();
}
led to the crash with QWidget::repaint: Recursive repaint detected after the window would be hidden and deleted as a reaction on the signal onLogout().
However, I discovered that if I replace the QToolButton with QPushButton I do not get the crash and everything is fixed.
So my question is why? What is wrong with the QToolButton? And why is the problem on Windows in Debug mode and I do not have it on Linux or on Window in Release mode. Honestly, I have already encountered strange crashes on Windows in Debug mode for Qt. E.g., I remember once that QVariantList failed there, so I got rid of it. I must note here that I build against debug qt libraries and tried \MT, \MDd, and \MTd runtime libraries.
Probably your shutdown / logout logic is flawed: I guess, that you delete the object from which you are running your logout code. Try to replace the call to delete() with
deleteLater() and see what happens. For further diagnosis, we'd need more information about your object tree, construction and destruction.
It has absolutely nothing to do with the kind of button you are using, that is absolutely accidental.
Using mixed managed/unmanaged C++ (Visual Studio 2008) I'm opening a windows form child window from a DirectX application. Weird stuff indeed, but it works, mostly. If I use showDialog() the child window works perfectly, but obviously the main app stops running (until the child is closed). If I use show() life is good, but the child has subtle issues. A textbox works and accepts input for example, but you can no longer use the Tab key to move to different controls. Mnemonics (Alt+hotkey) have stopped working as well.
I'm a huge keyboard shortcut fan, so this is very annoying. To make it worse, I'm not even sure how to Google this issue. Any help would be greatly appreciated.
To resolve the tabbing problem either use a separate thread to create the dialog and call showDialog(), or call IsDialogMessage in your main message loop.
I maintain an application written using visual studio 2010 and wxWidgets version 2.8.10. It has been reported to me that, under windows vista, the application will crash when displaying a wxFileDialog that is viewing a network drive and being resized. The dialogue is invoked with the following code:
wxFileDialog file_chooser(
this,
make_wxString(my_strings[strid_file_choose_caption]),
make_wxString(frame->get_config()->get_last_os_dir()),
wxT(""), // default file
make_wxString(loader->get_file_extension()),
wxOPEN);
int rcd = file_chooser.ShowModal();
Has anybody seen anything similar?
Crashes inside the standard file dialog are almost invariably due to the presence of some buggy shell extension on the system. To say anything more you'd need to get the minidump (or at least a stack trace) at the moment of crash and debug it.
When I start the program, I get the dialog and everything. But it closes by itself after some 10 seconds. How do I disable that?
EDIT: This happens when I run "Debug -> Start Without Debugging". This is the only way I know how to run the program.
EDIT2: My dialog is inheriting from CDialogEx.
If your dialog is not modal, i.e. you are not firing it up using the DoModal() member function, it is possible that it is being created with the constructor, and deleted with the destructor as it goes out of scope. You see this type of behaviour with some implementations of splash screens. To figure out what is happening, put a breakpoint on your dialogs destructor, and look at the call stack that is leading to it. It is also worth turning on all exceptions in the debugger, as you could be getting hit with an uncaught exception that is terminating your app.
As others have already said, this is not normal behaviour for an MFC app.
Usually dialogs do not behave that way.
But in default, they close on OnOk (CDialog::OnOk) which is "Enter Key Pressed"
and OnCancel (CDialog::OnCancel()) which is "Esc Key Pressed"
Try overloading those two in your Dialog, to see if those get called and to handle
the behaviour there as you like it.
Perhaps the Close event should also be handled or watched.
here are lots of examples of what can be done with a Dialog (especially OnOk, OnCancel and Close) CDialog Examples
I was facing the same issue with Visual Studio 2013:
I was creating the most basic MFC application with the Visual Studio wizard (either dialog-based, Single/Multiple document based), and just recompiling the generated code. No modification to the code at all.
I just found out that the "restart" does not occur when I turn off my Anti-virus. :-)
This is not a bug in Visual Studio, it is an environment problem.
My anti-virus is Avast.
The solution for Avast is to turn-off the Deepscreen feature.
There, go to Settings / Active Protection / Deepscreen - and disable that.
More details could be found about this approach to the solution on Avast's forums, from this discussion:
https://forum.avast.com/index.php?topic=139935.0
Confirmed, this happens with Visual Studio 2010, and doesn't happen with Visual Studio 2008. That means all the negative votes were completely unnecessary. It's a default of Visual Studio 2010, I didn't change anything. Nor did I make any bug, because I explicitly said that I created a new application without changing anything.
Thanks for all the negative votes.
Just for the record, I tried this using Visual Studio 2010. I picked Dialog-based application and left all the other options at their default settings. Compiled both Debug and Release configurations, for x86 and x64. When launched using Start without Debugging none of the four executables terminated by themselves.
If this is happening for you I would assume you have some application running (in the background) that interferes with the expected behavior. Try setting up a virtual machine, install a clean Visual Studio and perform the same procedure again.