2013-12-02 3 views
8

Мне нужно запустить отладчик из моей родной программы на C++, когда выполняются определенные условия. В C# я просто вызываю System.Diagnostics.Debugger.Launch(). Я думал, что вызов Win32 DebugBreak() будет делать то, что я хочу, но он просто завершает приложение, если нет отладчика.Что эквивалентно System.Diagnostics.Debugger.Launch() в неуправляемом коде?

Как запустить новый экземпляр отладчика (знаменитый диалог «Возможные отладчики») из собственного кода? Возможно ли это? Я мог бы попытаться использовать COM для создания нового экземпляра Visual Studio, но это довольно сложно, и я также заблокирую меня для конкретной версии VS.

+0

я столкнулся с той же проблемой, а также не нашли никакого решения. Я, наконец, решил свою проблему, поставив вызов System.Diagnostics.Debugger.Launch в DLL смешанного режима, экспортировал функцию как неуправляемую функцию, а затем явно загрузил библиотеку с помощью LoadLibrary из моего неуправляемого приложения. – Patrick

+0

Это классно, но не тогда, когда ваше приложение имеет CLR. Загрузка управляемой библиотеки kinda messes вверх по всему предмету хостинга –

ответ

9

Получается, что можно напрямую вызвать vsjitdebugger.exe с помощью PID текущего процесса. Убедитесь, что в приложении «Инструменты» -> «Параметры» - «Отладка» - «Времени времени» в Visual Studio выбрано «Родной».

Вот код C++ для запуска отладчика. Он использует UNICODE версии различных API Win32. Я получаю системный каталог, потому что CreateProcess() не использует PATH.

bool launchDebugger() 
{ 
    // Get System directory, typically c:\windows\system32 
    std::wstring systemDir(MAX_PATH+1, '\0'); 
    UINT nChars = GetSystemDirectoryW(&systemDir[0], systemDir.length()); 
    if (nChars == 0) return false; // failed to get system directory 
    systemDir.resize(nChars); 

    // Get process ID and create the command line 
    DWORD pid = GetCurrentProcessId(); 
    std::wostringstream s; 
    s << systemDir << L"\\vsjitdebugger.exe -p " << pid; 
    std::wstring cmdLine = s.str(); 

    // Start debugger process 
    STARTUPINFOW si; 
    ZeroMemory(&si, sizeof(si)); 
    si.cb = sizeof(si); 

    PROCESS_INFORMATION pi; 
    ZeroMemory(&pi, sizeof(pi)); 

    if (!CreateProcessW(NULL, &cmdLine[0], NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) return false; 

    // Close debugger process handles to eliminate resource leak 
    CloseHandle(pi.hThread); 
    CloseHandle(pi.hProcess); 

    // Wait for the debugger to attach 
    while (!IsDebuggerPresent()) Sleep(100); 

    // Stop execution so the debugger can take over 
    DebugBreak(); 
    return true; 
} 
+0

Фантастический! Это именно то, что мне нужно для отладки COM-сервера вне процесса. – UweBaemayr

+0

Я в настоящее время пытаюсь разместить CoreCLR внутри управляемого приложения, и я нашел, что это единственный способ работать с смешанной отладкой. Начиная с смешанной отладки от VS, происходит сбой отладчика, вызывая просто DebugBreak, вызывает тупик, как и 'System.Diagnostics.Debugger.Launch'. – Sebazzz

8

DebugBreak() в порядке, также является встроенным __debugbreak(). Они оба делают то же самое, они разбивают программу с исключением STATUS_BREAKPOINT. Затем, затем запускается диалоговое окно «Отчет об ошибках Windows», он катится некоторое время, а затем предлагает кнопку «Отладка». Затем запускается отладчик.

Единственная реальная ошибка, которую вы могли бы сделать, не ждет достаточно долго для диалога WER и нажатия Отмена слишком быстро. Или WER отключен. Если отладочного устройства вообще нет, тогда да, вы не можете его выбрать.

Ключ реестра имеет значение HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ AeDebug \ Debugger. Обычно устанавливается в vsjitdebugger.exe, тот, который отображает диалоговое окно «Возможные отладчики».

+0

Nope. DebugBreak() вызывает диалог ошибки «foobar.exe перестает работать, Windows проверяет решение проблемы». Ни при каких обстоятельствах мне предлагается выбрать отладчик. По крайней мере, это то, что происходит в Windows 7. –

+1

Это диалог WER, о котором я говорил. Нажмите ногу и не нажимайте «Отмена». И проверьте этот раздел реестра. –

+0

Действительно, если вы подождете некоторое время, а затем нажмите «debug», вы можете выбрать отладчик. Должно было быть более терпеливым. Однако System.Diagnostics.Debugger.Launch() сразу попадает в диалог выбора отладчика, без 45-секундного ожидания. Еще одно осложнение заключается в том, что мое приложение не получает непосредственно пользователя. Если бы это было так, мне не нужны трюки, чтобы присоединить к нему отладчик. Если я использую DebugBreak(), родительское приложение, похоже, думает, что дочерний процесс просто умер и дает мне поруки, но я еще не исследовал это глубоко. –

0

Вызов _CrtDbgBreak() из кода Visual C++, перекомпилировать, запустить программу, а затем выберите отладки программы из диалога.

enter image description here

Смежные вопросы