Visual Studio 2012 отладка удаленного процесса не работает должным образом
Я борюсь с довольно сложной задачей отладки и надеюсь, что у кого-то могут быть некоторые подсказки, как сделать эту работу.
Здесь сценарий:
У меня есть служба Windows С#, которая работает под учетной записью пользователя с правами администратора и запускает отдельный исполняемый процесс под учетной записью пользователя, которая имеет стандартные пользовательские привилегии. Эти два процесса предназначены для связи с использованием WCF.
К сожалению, когда дочерний процесс запущен, он немедленно сбрасывается, и ничто в журнале событий не указывает, что произошло. Родительский процесс продолжает работать без исключений.
Для информации: эти два приложения надежно работают вместе в конфигурации, в которой родительский процесс является настольным приложением. У меня также был успех с родителем как службой Windows, но только тогда, когда оба процесса работают под одной учетной записью пользователя с правами администратора.
Теперь мне нужно переконфигурировать их отношения, чтобы ограничить привилегии дочернего процесса, но это происходит при сбое.
Чтобы доказать, что то, что я пытаюсь сделать, возможно, я создал два приложения-заглушки и успешно их запустил в желаемой конфигурации. Итак, я могу сделать вывод, что мое настоящее дочернее приложение содержит что-то, что несовместимо с этой конфигурацией и которое вызывает сбой даже до запуска кода. К сожалению, поскольку дочерний процесс основан на довольно сложном устаревшем коде, нелегко выделить его элементы, пока я не устраню проблему, поэтому мне действительно нужно надежное средство для ее преодоления.
Если я модифицирую код дочернего процесса для немедленного запуска отладки при запуске, он приглашает меня подключить отладчик, но не может завершить вложение, с сообщением, которое указывает, что The Just-in-time debugger does not have permission to debug the process
.
Я также видел этот вопрос и попытался реализовать это предлагаемое решение (которое выглядит действительно многообещающим) но он не работает в моем сценарии. Вместо запуска отладки перед запуском приложения он ничего не делает - нигде отладчик или приложение не запускаются, а диалог приглашения отладки не отображается. Тем не менее, я подтвердил, что этот метод работает в моей среде (используя его для запуска Notepad.exe), поэтому есть что-то в отношении моего приложения или того, как я запускаю его, что вызывает проблему.
Я рад поэкспериментировать и поделиться более подробными сведениями о результатах своих тестов, если у кого есть какие-либо предложения.
Большое спасибо за ваши идеи,
Тим
Ответы
Ответ 1
Тот факт, что отладчик никогда не запускается для дочернего элемента, означает, что ошибка должна происходить в серверном процессе PARENT. Если вы правильно установите Image File Execution Options
(что проще всего сделать с помощью программы GFlags с помощью бесплатных средств отладки Windows от Microsoft), значит, вы никогда не начинаете создавать ребенка. Самый простой способ проверить это, добавив Assert к вашему коду, прямо перед созданием дочернего процесса, создайте родительскую службу в режиме отладки, установите/зарегистрируйте ее как услугу и запустите ее. Когда появляется Assert, присоединитесь к процессу и начните отладку оттуда. Затем вы должны увидеть ошибку процесса создания, происходящую в родительском.
Если вы хотите интерактивно отлаживать как родительскую службу, так и дочерний процесс, вы можете сделать это с помощью WinDbg и GFlags, но это будет сложно.
Вам понадобятся WinDbg и GFlags. Эти инструменты включены бесплатно от Microsoft как часть средств отладки для Windows. Вы можете найти этот бесплатный пакет программного обеспечения здесь:
http://msdn.microsoft.com/en-us/windows/hardware/gg463009.aspx
Используйте GFlag, чтобы установить параметр выполнения для вашего PARENT SERVICE со следующими параметрами отладчика:
"C:\Program Files (x86)\Windows Kits\8.0\Debuggers\x86\WinDbg.exe" -server tcp:port=5000:9000 -o -g
Когда Windows запускает родительскую службу, она будет работать под WinDbg. Из-за опции -o WinDbg также будет управлять запущенным дочерним процессом, позволяя вам интерактивно деактивировать ребенка от запуска. Из-за опции -g WinDbg запустит ParentService и позволит ему работать, а не останавливать его при загрузке, как это обычно происходит при отладке. Это предотвратит закрытие Windows SCM и запуск нового экземпляра.
Поскольку у вас запущена служба, у нее не будет доступа к рабочему столу, поэтому ни один из ее хостов WinDbg. Вам придется приложить отладчик ANOTHER к исполняемому экземпляру WinDbg, на котором запущен ParentService. Вы можете сделать это, используя другой экземпляр WinDbg. Для этого запустите второй экземпляр WinDbg и подключитесь удаленно, используя пункт меню "Файл | Подключиться к удаленному сеансу...". В диалоговом окне введите:
TCP: Port = 5000: 9000, Server = [имя_компьютера]
Как только вы подключитесь, вы сможете работать с вашим ParentService.exe, а когда он создает ChildProcess, исполняемый контекст будет заменен на него, и вы также сможете его отладить.
Я использовал этот метод для отладки дочернего процесса, созданного службой Windows. Это не так просто, как просто отладить что-то в Visual Studio, встроенной в отладчик в своей среде разработки, но он работает.
WinDbg имеет обширную документацию, доступную для него, как из Microsoft, так и из других источников в Интернете. В приведенном выше URL-адресе содержатся ссылки на документацию WinDbg.
Я рекомендую использовать GFlags, потому что он сделает все необходимые изменения в вашем реестре для запуска исполняемых файлов под отладчиком по вашему выбору. Это также делает гораздо больше, и стоит того, чтобы узнать о нем.
При запуске WinDbg можно настроить точки останова и задать всевозможные параметры. Я заменяю параметр -g опцией командной строки:
-c "$$<c:\MyDebugCommands.txt"
Это дает команду WinDbg выполнить команду, а команда - запустить WinDbg script с именем "MyDebugCommands.txt". Я заполняю файл MyDebugCommands.txt со всеми настраиваемыми изменениями, которые мне нужны (например, параметры символа загрузки), а также задает интересующие меня точки останова, при этом последняя команда в файле имеет -g
Как я уже сказал, это не так просто, как просто использовать VS IDE и встроенный отладчик, но это позволит вам интерактивно отлаживать родительскую службу и ее запущенный дочерний процесс.
Ответ 2
В соответствии с моими испытаниями, основанными на вашем сценарии выше (родительский процесс - это служба с правами администратора, дочерняя консоль без прав администратора), я вижу ту же ошибку отладки, что и при искусственном принуждении дочернего процесса к исключению разрешения как как только он начнется. Сообщение об ошибке в этом случае может вводить в заблуждение, так как неясно, что это проблема с разрешением отладчика
Было бы полезно узнать, каким типом приложения является ваш дочерний процесс, потому что это повлияет на параметры отладки, которые у вас есть.
Первый способ, которым я пытался отлаживать это, - перехватить все необработанные исключения в моем дочернем процессе (консольное приложение). Вы можете сделать это, добавив следующий код в процедуру запуска вашего дочернего приложения:
AppDomain.CurrentDomain.UnhandledException += new
UnhandledExceptionEventHandler(App_UnhandledException);
Затем я добавил код в мою App_UnhandledException процедуру для регистрации исключения. Это сработало для меня, и я видел причину ошибки разрешения. Единственное предостережение в том, что это не приведет к перехвату исключения, когда ваше приложение даже не загрузится из-за проблемы с разрешением. Но этот подход должен по крайней мере сократить пространство поиска в понимании проблемы с разрешением.
Если исключение генерируется до того, как ваш обработчик исключений будет достигнут, другой возможностью является использование средства просмотра привязки к сборке. Это очень полезный инструмент.
FWIW вы можете выполнить свой служебный код (но, к сожалению, не в ваш дочерний процесс), запустив службу в Visual Studio. Код, показанный ниже в корпусе коммутатора под названием DEBUG, позволит вам запускать/отлаживать вашу службу в VS.
// This is the entry point
static void Main(string[] args)
{
// If parameter passed, act on it
if ( args.Length > 0 )
{
switch (args[0] )
{
// Debug the service as a normal app from within Visual Studio
case DEBUG:
MyService DebugService = new MyService();
DebugService.OnStart(null);
break;
// Install the service programatically
case INSTALL:
ManagedInstallerClass.InstallHelper(new string[] _
{ Assembly.GetExecutingAssembly().Location });
break;
// Un-install the service programatically
case UNINSTALL:
ManagedInstallerClass.InstallHelper(new string[] +
{ UNINSTALL, Assembly.GetExecutingAssembly().Location });
break;
// We don't understand this parameter!
default:
message = string.Concat(DEBUG, " to run service manually.", Environment.NewLine);
message += string.Concat(INSTALL, " to install service.", Environment.NewLine);
message += string.Concat(UNINSTALL, " to un-install service.", Environment.NewLine);
message += string.Concat("Do not understand the command-line parameter ", args[0]);
throw new System.NotImplementedException(message);
}
}
// If no parameter passed, just start the service normally
else
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new MyService() };
ServiceBase.Run(ServicesToRun);
}
}
Ответ 3
Вы пытались запустить Visual Studio в качестве администратора и вызывать метод Process.EnterDebugMode()?
Ответ 4
Если я модифицирую код дочернего процесса для немедленного запуска отладки при запуске, он приглашает меня подключать отладчик, но не удается завершить вложение, с сообщением, которое указывает, что отладчик "точно в срок" не имеет разрешение отладки процесса
Запустите secpol.msc как администратор и в разделе "Локальные политики". "Управление правами пользователя" выберите "Отладочные программы". Затем добавьте к ним группу "Пользователи". Посмотрите, исправляет ли эти проблемы разрешения.
НТН