0

Suppose that we want to run external command line application, for example "dir" and suppose that it crashes:

namespace util
{

        bool execChildProcess(const std::string & cmd,  std::string & cmdOutput)
        {
           QProcess process;
           QString qStrCmd = QString::fromStdString(cmd);
           process.start(qStrCmd);

           if(process.exitStatus() == QProcess::Crashed )
           {
               std::cout<<"QProcess::Crashed"<<std::endl;
               process.kill();
           }

           if(process.waitForFinished() && process.exitStatus() == QProcess::NormalExit )
           {
               QString output(process.readAllStandardOutput());
               cmdOutput = output.toStdString();
               std::cout<<"Result: "<<cmdOutput<<std::endl;
               return true;
           }
           else
           {
                   switch(process.error())
                   {
                    case QProcess::FailedToStart :
                        std::cout<<"QProcess::FailedToStart"<<std::endl;
                        break ;
                    case QProcess::Crashed :
                        std::cout<<"QProcess::Crashed"<<std::endl;
                        break ;
                    case QProcess::Timedout:
                        std::cout<<"QProcess::Timedout"<<std::endl;
                        break ;
                    case QProcess::WriteError:
                        std::cout<<"QProcess::WriteError"<<std::endl;
                        break ;
                    case QProcess::ReadError:
                        std::cout<<"QProcess::ReadError"<<std::endl;
                        break ;
                    case QProcess::UnknownError:
                        std::cout<<"QProcess::UnknownError"<<std::endl;
                        break ;
                    }
                    process.kill();
           }
           return false;
        }
}

int main(int argc, char* argv[])
{
        std::string output;
        bool res = util::execChildProcess("dir", output);
}

the crash is catched after we close this message:

enter image description here

After the message is closed the code kill the process but not before.

How we can avoid this message with QProcess(I don't know if it also happen in ubuntu but i would like a cross-platform solution in case it also happen in ubuntu).

sergio campo
  • 190
  • 2
  • 13

3 Answers3

0

Call SetErrorMode(SEM_NOGPFAULTERRORBOX) in your process; the error mode is inherited by the child processes. You can revert it right after you start the process:

QProcess process;
...
auto errMode = GetErrorMode();
SetErrorMode(errMode | SEM_NOGPFAULTERRORBOX);
connect(&process, &QProcess::stateChanged, [errMode](QProcess::ProcessState state) { if (state != QProcess::Starting) SetErrorMode(errMode); });
process.start();
...

You could also execute SetErrorMode(SEM_NOGPFAULTERRORBOX) in the target process. For this, you could create a .DLL that includes this call, and inject it into the target process.

The target process handle can be obtained as follows:

HANDLE getHandle(const QProcess *process) {
  auto pid = process->processId();
  return pid->hProcess;
}
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • All [Solutions here](https://stackoverflow.com/questions/2284138/disable-debug-prompt-on-application-crash) used a variant of registry approach including that which mentioned `SetErrorMode` solution, Do you think the registry approach solution is aggressive ? – Mohammad Kanan May 14 '18 at 10:00
-1

Its possible to exclude an application from automatic debugging under windows, thus getting away from the debugging popup.

Under windows edit registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug

Add a REG_DWORD value to the AutoExclusionList subkey, where the name is the name of the executable file and the value is 1.

You don't have to do that manually in your app, you could use Qt QSettings like this:

QSettings settings("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug",
QSettings::NativeFormat);
auto key = settings.childKeys().at(x);

Then you can use QSettings::setValue to set the key to 1.

Complete information and reference under MSDN pages Configuring Automatic Debugging

For Ubuntu, it should be controlled, given that the process is killed.

Mohammad Kanan
  • 4,452
  • 10
  • 23
  • 47
  • I edited with regedit command line. Do i need to restart windows?, I only close the terminal. The external program is a portable binary file .exe and it was not installed in the system through a windows wizard. It does not work. – sergio campo May 12 '18 at 10:57
  • No need to restart I suppose, but I am not sure in case its not installed with wizard. – Mohammad Kanan May 12 '18 at 11:07
-1

As Mohammad Kanan has pointed out, we can disable the Error Dialog in the edit registry key, but in this case for Windows 10 pro it is under:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Windows Error Reporting

Find the value named

DontShowUI

or add a new DWORD value with this name if it doesn't exist. The default value of this key is 0. Double click it to edit, change the value to 1 and save

sergio campo
  • 190
  • 2
  • 13