- Что нужно для начала отладки
- Что такое debug
- Почему debug тебе необходим
- Выход ssh
- Выход sshd
- Зачем это всё?
- История 1
- История 2
- Как начать sshd на переднем конце?
- Как начать отладку варианты?
- Немного теории… обещаю :d
- Отладчик
- Параметры отладки sshd-d
- Параметры отладки ssh-v
- Пошаговое выполнение
- Программа debug
- Способ №1 (подключение отладчика)
- Способ №2 (подключение отладчика из исходного кода)
- Способ №3 (запуск с параметрами командной строки)
- Установка службы
- Шаг назад
- Шаг с выходом (step out)
- Шаг с заходом (step into)
- Шаг с обходом (step over)
- Шаги по ssh
- Шагнули слишком далеко
- Этапы sshd
- Подведем итог
- Вместо заключения
- Узнайте больше о Huawei
Что нужно для начала отладки
Даю бесплатный совет: пока читаете статью, проделывайте все то, что здесь будет описано, благо есть все для этого.
Что нужно:
Что такое debug
Debug — это процесс отладки (проверки) кода, когда в процессе его выполнения можно остановиться в обозначенном месте и посмотреть за ходом выполнения. Понять, в каком состоянии находится программа в определенном месте.
Это точно так же, как если бы можно было остановить жизнь и посмотреть на всё со стороны.
Почему debug тебе необходим
Давайте сразу проясним для себя: кода без багов не бывает… Так устроена жизнь. Поэтому не стоит сразу раскисать и бросать все, если код работает не так, как мы ожидали.
Но что же делать? Конечно, можно наставить
System.out.println
везде, где только можно и потом разгребать вывод в терминале в надежде на то, что получится найти ошибку.
Все-таки можно… и это делают, и делают аккуратно при помощи логирования (можно почитать об этом
).
Но если есть возможность запустить на локальной машине код, лучше использовать
Debug
. Сразу хочу заметить, что в этой статье мы будем рассматривать дебаг проекта внутри Intellij IDEA. Если интересно почитать об удаленном дебаге — вот, пожалуйста,
Выход ssh
ali-4c3275957b8b:~ $ ssh -i ~/.ssh/id_aliyun_rsa [email protected] exit
[email protected]:~ $
Выход sshd
[email protected]:~#$(which sshd) -D
Could not load host key: /etc/ssh/ssh_host_ed25519_key
C-c C-c
[email protected]:~#
Зачем это всё?
Если вы взялись за написание службы, то встаёт вопрос об её отладке. В интернетах в основном пишут про способ, который заключается в
, про альтернативу которому я и хочу рассказать. Т.к. служба — это не совсем обычный процесс Windows, просто запустить её из Visual Studio у вас не получится.
История 1
Собственно, началось все с того, что пришел баг о том что при некоторых операциях приложение вылетает. Это бывает часто. Баг не захотел воспроизводиться в Debug-версии. Это порой бывает. Поскольку в приложении часть библиотек была написано на C , то первой мыслью было что-то вроде «где-то забыли переменную проинициализировать или что-то в этом духе». Но на деле суть бага крылась в управляемом коде, хотя без неуправляемого тоже не обошлось.
А код оказался примерно следующим:
class Wrapper : IDisposable
{
publicIntPtr Obj {get; privateset;};
public Wrapper()
{
this.Obj = CreateUnmObject();
}
~Wrapper()
{
this.Dispose(false);
}
protectedvirtualvoid Dispose(bool disposing)
{
if (disposing)
{
}
this.ReleaseUnmObject(this.Obj);
this.Obj = IntPtr.Zero;
}
publicvoid Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
}
* This source code was highlighted with Source Code Highlighter.
В принципе, практически каноническая реализация шаблона IDisposable («практически» — потому, что нет переменной disposed, вместо нее обнуление указателя), вполне стандартный класс-обертка неуправляемого ресурса.
Использовался же класс примерно следующим образом:
{
Wrapper wr = new Wrapper();
calc.DoCalculations(wr.Obj);
}
* This source code was highlighted with Source Code Highlighter.
Естественно, что внимательный читатель сразу обратит внимание, что объекта wr надо вызвать Dispose, то есть обернуть все конструкцией using. Но на первый взгляд, на причину падения это не должно повлиять, так как разница будет в том детерминировано ли очистится ресурс или нет.
Но на самом деле разница есть и именно в релизной сборке. Дело в том, что объект wr становится доступным сборщику мусора сразу после начала выполнения метода DoCalculations, ведь больше нет ни одного «живого» объекта, кто на него ссылался бы. А значит wr вполне может(а так оно и происходило) быть уничтожен во время выполнения DoCalculations и указатель, переданный в этот метод становится невалидным.
Если обернуть вызов DoCalculations в using (Wrapper wr = new Wrapper()){…}, то это решит проблему, поскольку вызов Dispose в блоке finally, не даст жадному сборщику мусора «съесть» объект раньше времени. Если же по какой-то причине мы не можем или не хотим вызывать Dispose (к примеру WPF этот шаблон совсем не жалует), то придется вставлять GC.KeepAlive(wr) после вызова DoCalculations.
Реальный код, безусловно, был сложнее и разглядеть в нем ошибку было не так просто, как в примере.
Почему же ошибка проявлялась только в Release-версии, и то запущенной не из-под студии(если присоединить отладчик в процессе выполнения, то ошибка будет повторяться)? Потому что в противном случае для всех локальных ссылочных переменных добавляются якоря, чтобы они доживали до конца текущего метода, сделано это явно ради удобства отладки.
История 2
Жил-был проект, где для доступа к ресурсам использовался менеджер, который по строковому ключу доставал из заданной сборки различного вида ресурсы. С целью облегчения написания кода был написан следующего вида метод:
publicstring GetResource(string key)
{
Assembly assembly = Assembly.GetCallingAssembly();
returnthis.GetResource(assembly, key);
}
* This source code was highlighted with Source Code Highlighter.
После миграции на .Net 4 некоторые ресурсы внезапно перестали находиться. И дело тут опять же в оптимизации релизной версии. Дело в том, что в 4 версии дотнета компилятор может встраивать вызовы в код методов других сборок.
Чтобы «почувствовать разницу» предлагается следующий пример:
dll1:
publicclass Class1
{
publicvoid Method1()
{
Console.WriteLine(new StackTrace());
}
}
dll2:
publicclass Class2
{
publicvoid Method21()
{
this.Method22();
}
publicvoid Method22()
{
(new Class1()).Method1();
}
}
dll3:
class Program
{
staticvoid Main(string[] args)
{
(new Class3()).Method3();
}
}
class Class3
{
publicvoid Method3()
{
(new Class2()).Method21();
}
}
* This source code was highlighted with Source Code Highlighter.
Если скомпилировать в дебажной конфигурации(или если запускать процесс из-под студии) то получим честный стек вызовов:в ClassLibrary1.Class1.Method1()в ClassLibrary2.Class2.Method22()в ClassLibrary2.Class2.Method21()в ConsoleApplication1.Class3.Method3()в ConsoleApplication1.Program.Main(String[] args)
Если собрать под .Net версии до 3.5 включительно в релизе:в ClassLibrary1.Class1.Method1()в ClassLibrary2.Class2.Method21()в ConsoleApplication1.Program.Main(String[] args)
А под .Net 4 в релизной конфигурации то и вовсе получим:в ConsoleApplication1.Program.Main(String[] args)
Мораль здесь проста — не стоит привязывать логику к стеку вызовов, равно как и удивляться необычному стеку в исключениях в логе релизной версии. В частности, если вы пытаетесь найти причину исключения исключительно по его стеку вызовов, то стоит учитывать, что если стек заканчивается на методе Method1, то в коде оно(исключение) могло быть сгенерировано в одном из небольших методов, которые вызываются в теле Method1.
Так же на всякий случай стоит помнить, что можно запретить компилятору встраивать метод пометив его атрибутом [MethodImpl(MethodImplOptions.NoInlining)], эдакий аналог __declspec(noinline) в VC .
Как начать sshd на переднем конце?
Может действительно увеличена путем изменения сценария запуска или связанных с ними файлов конфигурации-dПараметры. К примеру, на CentOS может быть изменен/etc/sysconfig/sshdДля достижения этой цели.
Но лучшим решением будет использовать параметры командной строки. Это требует SSHD к переднему концу.
Выше тест Для того, чтобы выделить фокус, мы сознательно игнорировать некоторые препараты и после. Теперь мы добавили полный
Root @ localhost: ~ netstat -ltpn # 1. Проверьте, работает ли SSHD
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 978/sshd
tcp 0 0 127.0.0.1:32000 0.0.0.0:* LISTEN 918/java
Root @ localhost: ~ Service SSHD Стоп # 2. Пауза SSHD Операция
Root @ localhost: ~ netstat -ltpn # 3. Подтвердите, что SSHD был закрыт
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:32000 0.0.0.0:* LISTEN 918/java
Root @ localhost: ~ $ (какой SSHD) -D # 4. интерфейс запускает SSHD и начать режим отладки
... ...
Как начать отладку варианты?
Оба SSH и SSHD имеют параметры конфигурации и параметры командной строки для инициирования отладки. То же одно и то же, все из которых являютсяLogLevel。
Для конкретного использования элементов конфигурации, пожалуйста, обратитесь кssh_config(5)с участиемsshd_config(5)Отказ Мы рассматриваем только опции командной строки ниже.
Немного теории… обещаю :d
Чтобы начать мало-мальски дебажить, нужно понять, что такое
breakPoint
и разобраться в нескольких горячих клавишах, которые нужны для начала.
BreakPoint
— это специальный маркер, который отображает место или
состояние, на котором нужно остановить приложение.
Поставить breakpoint можно либо нажав левой кнопкой мыши на левую боковую панель, либо кликнув курсором по месту кода и нажав
Ctrl F8
.
Breakpoint’ы бывают трех видов: метка на строку, метка на переменную и метка на метод.
Выглядит это так:
Breakpoint’ы можно удалить, выполнив те же действия, что и при их добавлении.
Бывают ситуации, когда нужно сделать их неактивными (замьютить). Для этого в Debug секции, можно найти значок
, который сделает все breakpoint’ы неактивными.
Чтобы посмотреть, какие уже выставленные breakpoint’ы, можно или зайти в Debug в левом нижнем углу и найти иконку
, или нажать
Ctrl Shift F8
Когда зайдем в список breakpoint’ов, увидим:
Здесь есть два preakpoint’a:
- Bee.java:24 — в классе Bee на 24-й строке
- Main.java:14 — в классе Main на 14-й строке
Хочу заметить, что при клонировании проекта к себе не будет этих BreakPoint’ов: их нужно выставить самостоятельно!
Также есть секция
Java Exception Breakpoints
. Очень полезная вещь. При помощи ее можно добавить неявный breakpoint, чтобы программа останавливалась перед выбрасыванием любого исключения или какого-то конкретного.
Добавим для RuntimeException неявный breakpoint. Делается это легко: в верхнем левом углу есть плюсик “ ”. Нажимаем на него и выбираем
Java Exceptions Breakpoints
В появившемся окне пишем имя исключения, которое нужно добавить, выбираем из предложенного списка и нажимаем
OK
На этом ликбез заканчиваем и переходим к практике.
Отладчик
Отладчик – это компьютерная программа, которая позволяет программисту контролировать выполнение программы и проверять ее состояние во время выполнения программы. Например, программист может использовать отладчик для выполнения программы построчно, по ходу проверяя значения переменных.
Возможности отладчика двойственные: способность точно контролировать выполнение программы и возможность просматривать (и при желании изменять) состояние программы.
Ранние отладчики, такие как gdb, были отдельными программами с интерфейсами командной строки, где программисту приходилось вводить загадочные команды, чтобы заставить их работать. Более поздние отладчики (такие как ранние версии Turbo Debugger от Borland) всё еще были автономными, но поставлялись со своими собственными «графическими» интерфейсами для облегчения работы с ними.
Большинство современных IDE, доступных в наши дни, имеют встроенный отладчик, то есть отладчик использует тот же интерфейс, что и редактор кода, поэтому вы можете отлаживать программу, используя ту же среду, которую вы используете для написания кода (вместо того, чтобы переключаться между программами).
Параметры отладки sshd-d
Добавить SSHD-dПараметры могут начать свой режим отладки. Сравнивать
Параметры отладки ssh-v
Дайте командную строку SSH-vОпция может начать свой режим отладки. Мы сравниваем-vРазница между вариантами.
Когда нет опции -V, SSH строго следует обучению «молчание золота»
[email protected]:~$ ssh -i ~/.ssh/id_rsa [email protected] exit
[email protected]:~$
Выход SSH следующим образом, когда существует опция -V
Пошаговое выполнение
Мы собираемся начать изучение отладчиков с изучения некоторых инструментов отладки, которые позволяют нам контролировать выполнение программы.
Пошаговое выполнение – это название набора связанных функций отладчика, которые позволяют нам выполнять (поэтапно) наш код инструкцию за инструкцией.
Есть несколько пошаговых команд, которые мы рассмотрим по очереди.
Программа debug
Ассемблер /
Для чайников /
Быстрый старт /
ПРИМЕЧАНИЕ
Рисунки на этой странице не отображаются, но вы можете найти их в книге.
Как уже говорилось (см. ВВЕДЕНИЕ),
программа Debug входит в состав Windows. Запустить программу Debug
можно из командной строки или непосредственно из папки, в которой она находится. Чтобы
запустить программу из командной строки, выберите команду из меню ПУСК – ВЫПОЛНИТЬ или
нажмите комбинацию клавиш WIN R (если вы не знаете, что такое комбинация клавиш, см.
книгу Компьютер для чайников).
В открывшемся окне (рис. 1.5) напечатайте слово debug и нажмите клавишу ENTER или щёлкните кнопку ОК.
После этого откроется окно с пустым экраном и чёрточкой в левом верхнем углу,
которая приглашает вас ввести какую-либо команду. Например, чтобы выйти из программы Debug,
напечатайте букву q и нажмите ENTER.
Написать программу, используя Debug, можно не единственным способом, но мы пока
рассмотрим тот, который больше похож на написание программы для
Emu8086.
Чтобы написать уже известную нам программу, используя Debug, сделаем следующее
(подразумевается, что Debug вы уже запустили, и увидели черный экран с маленькой мигающей
черточкой в левом верхнем углу).
Введем букву «а» (напоминаю в последний раз – все команды вводятся на
английском языке) и нажмем ENTER.
Затем введем программу, нажимая ENTER в конце каждой строки:
0B72: 0100 MOV AH, 02 0B72: 0102 MOV DL, 41 0B72: 0104 INT 21 0B72: 0106 INT 20 0B72: 0108
Результат будет примерно таким, как показано на рис. 1.6.
ПРИМЕЧАНИЕ 1
Обратите внимание, что все числовые значения пишутся без буковки h в конце. Это потому,
что Debug работает только с шестнадцатеричными числами, и ему не надо объяснять,
в какой системе исчисления вводятся данные.
ПРИМЕЧАНИЕ 2
После ввода команды -а, появляются символы: 0B72: 0100. В вашем случае первые четыре
символа могут быть другими, но нас они пока не интересуют. А как вы думаете, что означает
число 0100? Помните директиву ORG 100h (см. раздел
Emu8086)?
Вот-вот – это адрес, с которого начинается выполнение программы. То есть в память с
этим адресом заносится первая команда программы (для файлов СОМ). Каждая команда занимает
2 байта, поэтому следующий адрес будет 0102 и т.д.
Сами команды мы уже знаем (см. раздел
Emu8086),
поэтому описывать их здесь не будем.
Программа написана – нужно проверить ее работу. Нажмём ENTER ещё раз, чтобы на экране
появилась чёрточка, которая говорит о том, что можно вводить команду для Debug. Затем
введем команду g (от английского «GO») и нажмем клавишу ENTER. На экране увидим следующее:
-g A Программа завершилась нормально -
Здесь A – та самая буква, которая выводится на экран в результате работы программы.
Затем идёт сообщение о нормальном завершении программы (оно может отличаться в зависимости
от версии Debug).
А теперь, если интересно, можно проверить программу в пошаговом режиме, то есть
понаблюдать, как выполняются команды одна за другой. Для этого придется по новой
набрать текст программы (не забудьте сначала ввести команду а), затем:
Введем команду t и нажмем клавишу ENTER. Увидим нечто вроде этого:
AX=0200 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0B72 ES=0B72 SS=0B72 CS=0B72 IP=0102 NV UP EI PL NZ NA PO NC 0B72:0102 B241 MOV DL,41
Это есть ни что иное, как состояние регистров процессора после выполнения первой
строки программы. Как вы можете видеть, в регистр АН записалось число 02. В нижней
строке находится адрес команды и сама команда, которая будет выполняться следующей.
Снова введем команду t и нажмем клавишу ENTER. Увидим следующее:
AX=0200 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0B72 ES=0B72 SS=0B72 CS=0B72 IP=0104 NV UP EI PL NZ NA PO NC 0B72:0104 CD21 INT 21
Команда MOV DL, 41, как ей и полагается, записала в регистр DL число 41.
Снова введем команду t и нажмем клавишу ENTER. Увидим следующее:
AX=0200 BX=0000 CX=0000 DX=0041 SP=FFE8 BP=0000 SI=0000 DI=0000 DS=0B72 ES=0B72 SS=0B72 CS=0347 IP=0225 NV UP EI PL NZ NA PO NC 0347:0225 80FC4B CMP AH,4B
Команды CMP AH,4B нет в нашей программе. Наша программа завершила свою работу.
Мы можем долго еще вводить команду t – нам будут выдаваться состояния регистров.
Почему это происходит, нам пока не интересно. Лучше введем команду g и нажмем клавишу ENTER,
таким образом окончательно выполним нашу программу, и увидим то, что мы уже видели.
Программа написана и проверена. Но как сделать ее самостоятельной, то есть как создать
файл СОМ? Ведь то, что мы сделали, работает только с помощью Debug. Чтобы создать
исполняемый файл, нужно ответить на несколько вопросов:
- Какого размера будет наш файл? Выполнение программы начинается с адреса 0100h,
а последняя строка в программе содержит адрес 0108h. Это значит, что размер файла
будет 8 байт (108h – 100h = 8). - Как мы назовем наш файл? А хоть как. Однако, рекомендуется давать файлам английские
имена, в которых содержится не более 8 символов (DOSу так приятнее работать). Назовем,
например, debug_1.com
А теперь выполним следующие действия:
- Снова напишем нашу программу (тренируйтесь, тренируйтесь…).
- Запишем в регистр СХ размер файла. Для этого введем команду r cx и нажмем ENTER. Затем введем размер файла (8 байт) и нажмем ENTER.
- Введем команду n, затем один пробел и имя файла. Нажмем ENTER.
- И, наконец, введем команду w и нажмем ENTER.
В результате всех этих действий на экране появится следующая информация (см. также рис. 1.7):
-r cx СХ 0000 :8 -n debug_1.com -w Запись: 00008 байт -
Если вы работаете в режиме эмуляции DOS из под WINDOWS, то файл debug_1.com
сохранится на рабочий стол, либо в папку текущего пользователя. Это зависит от
версии и/или настроек WINDOWS. Теперь его можно запустить как обычную программу.
Если в указанных папках вы не нашли этот файл, то найдите его через поиск файлов.
Ну а если вы не знаете, как это сделать, см. книгу Компьютер для чайников.
Чувствую, что мы уже устали. Выход из Debug осуществляется командой q.
Набравшись сил и терпения, изучим еще одну опцию Debug – дизассемблер. С его помощью
можно дизассемблировать какой-нибудь СОМ-файл (то есть выполнить действие, обратное
ассемблированию – преобразовать исполняемый файл в исходный код на языке ассемблера).
Допустим, у вас есть программка, написанная не вами – ее исходный код вы не знаете,
а посмотреть очень хочется. Для этого и существует дизассемблер.
Итак, программа Debug у нас закрыта. Набираем в командной строке:
debug debug_1.com
(где debug_1.com – это имя файла, который мы хотим дизассемблировать) и нажимаем ENTER.
ПРИМЕЧАНИЕ
Если программа не запустилась, значит нужно указать полный путь к ней, например
C:WINDOWSCOMMANDdebug debug_1.com
Если же программа запустилась, но выдала ошибку (например: Ошибка 1282 или «Файл не найден»),
то нужно указать полный путь к файлу, например:
C:WINDOWSCOMMANDdebug C:MYPROGdebug_1.com
Если и это не помогло, то, возможно, вы всё-таки где-то допустили ошибку в пути или
путь не соответствует требованиям DOS. В таком случае лучше поместить программу в
корень диска С, откуда она гарантированно загрузится по пути «C:debug_1.com».
Если Debug запустилась без сообщений об ошибках, то вводим команду u и нажимаем ENTER.
Вот что мы увидим (примерно, см. также рис 1.8):
-u 0BC6:0100 B402 MOV AH, 02 0BC6:0102 B241 MOV DL, 41 0BC6:0104 CD21 INT 21 0BC6:0106 CD20 INT 20 0BC6:0108 56 PUSH SI 0BC6:0109 2E CS: 0BC6:010A 8A04 MOV AL, [SI] 0BC6:010C 0AC0 OR AL, AL 0BC6:010E 741A JZ 012A 0BC6:0110 3C3A CMP AL, 3A 0BC6:0112 750D JNZ 0121 0BC6:0114 2E CS: 0BC6:0115 807C0100 CMP BYTE PTR [SI 01], 00 0BC6:0119 7506 JNZ 0121 0BC6:011B 2E CS: 0BC6:011C C60400 MOV BYTE PTR [SI], 00 0BC6:011F EB09 JMP 012A -
Посмотрите на первые четыре строки. Узнаете? Это наша программа. Остальные строки
нас не интересуют (это инструкции, оставшиеся от программ или данных, отработавших
до запуска Debug). Ну а если мы рассматриваем незнакомый файл, как узнать, где
кончается программа и начинается «мусор»? Ориентировочно это можно сделать по размеру
файла (для очень маленьких программ). Размер можно посмотреть в свойствах файла.
Только следует учитывать, что в свойствах файла размер дан в десятичной форме, а
Debug нам выдает шестнадцатеричные адреса. Поэтому придется перевести десятичное число
в шестнадцатеричное.
Есть еще вариант (который тоже не всегда приемлем) – найти в полученном списке строку,
содержащую команду выхода из программы (INT 20).
Если программа большая, то список ее команд не поместится на экран. Тогда снова вводим
команду u и нажимаем ENTER. И так до конца программы.
Возможно, вы не увидите на экране свою программу. Это может быть либо из-за того,
что программа почему-то не загрузилась, либо по причине несоответствия адресов.
Будьте внимательны: обращайте внимание на адреса памяти, которые указаны в левой колонке.
Наша программа начинается с адреса 0100. Если адрес другой, то это, соответственно,
не наша программа.
Способ №1 (подключение отладчика)
- Запустите службу с помощью консоли управления службами Windows.
- В Visual Studio выберите
Tools → Connect To Process
в появившемся диалоговом окне выберите имя процесса службы и нажмите кнопкуAttach
После этого можно расставлять точки останова и отлаживать службу.
У этого способа есть недостаток: без дополнительных ухищрений не получится отладить код, находящийся в обработчике
OnStart
Способ №2 (подключение отладчика из исходного кода)
В код модуля
program.cs
, сразу после начала метода
Main()
добавляем следующее:
#if DEBUG
System.Diagnostics.Debugger.Launch();
#endif
Этот код подключает отладчик к процессу и компилируется только в режиме
DEBUG
. Теперь для отладки службы её нужно запускать не из Visual Studio, а с помощью консоли управления службами (или команды
net start
). Сразу после запуска появится диалоговое окно выбора отладчика:
Выбираете запущенный экземпляр Visual Studio, нажимаете
Yes
и наслаждаетесь отладкой!
Способ №3 (запуск с параметрами командной строки)
предложил
Есть еще способ — предусматривать возможность запуска службы как консольного приложения. Например, в командной строке передавать /console, и если этот флаг установлен, стартовать приложение как консольное, если нет — как службу.
Преимущества такого подхода:Очень просто отлаживать, по сути дела, как обычное консольное приложение. В консоль можно выводить отладочную информацию
Спасибо komr за помощь в отладке текста 🙂
Установка службы
При попытке запуска вам будет показано сообщение, что, мол, служба запуститься не может и вам нужно использовать
installutil.exe
для её установки.
Для установки службы вам потребуется консоль Visual Studio, которая находится по пути
Пуск → Программы → Visual Studio 2008 → Visual Studio Tools → Visual Studio 2008 Command Prompt
(в зависимости от версии установленной VS путь может отличаться)
После запуска консоли переходим в директорию, в которую собирается ваша служба в режиме
Debug
и устанавливаем её:
installutil.exe /i <имя вашей сборки со службой>
Более вам
installutil.exe
не потребуется. Для удобства запускаем консоль управления службами Windows:
services.msc
Теперь консоль Visual Studio можно закрыть.
Переходим к самому интересному 🙂
Шаг назад
Некоторые отладчики (такие как Visual Studio Enterprise Edition и GDB 7.0) представили возможность пошагового выполнения, обычно называемую шагом назад или обратной отладкой. Цель шага назад – отмотать последний шаг назад, чтобы вы могли вернуть программу в предыдущее состояние. Это может быть полезно, если вы перешагнули цель, или если вы хотите повторно проверить только что выполненную инструкцию.
Шаг с выходом (step out)
В отличие от двух других пошаговых команд, шаг с выходом (step out) не просто выполняет следующую строку кода. Вместо этого он выполняет весь оставшийся код функции, которая выполняется в настоящее время, а затем возвращает управление вам, когда будет выполнен возврат из функции.
Для пользователей Visual Studio
В Visual Studio команду шаг с выходом можно выполнить через меню Отладка (Debug) → Шаг с выходом (Step Out), или нажав комбинацию клавиш Shift F11.
Давайте посмотрим на пример этого, используя ту же программу, что и выше:
#include <iostream>
void printValue(int value)
{
std::cout << value << 'n';
}
int main()
{
printValue(5);
return 0;
}
Выполните команды шаг с заходом, пока не окажетесь внутри функции printValue с маркером выполнения в строке 4.
Затем выполните шаг с выходом. Вы заметите, что в окне вывода появится значение 5, и отладчик вернет вам управление после завершения функции (в строке 10).
Эта команда наиболее полезна, когда вы случайно вошли в функцию, которую не хотите отлаживать.
Шаг с заходом (step into)
Команда шаг с заходом (step into) выполняет следующую инструкцию в обычном пути выполнения программы, а затем приостанавливает выполнение программы, чтобы мы могли проверить состояние программы с помощью отладчика. Если выполняемый оператор содержит вызов функции, шаг с заходом заставляет программу перескакивать в начало вызываемой функции, где она приостанавливается.
Давайте посмотрим на очень простую программу:
#include <iostream>
void printValue(int value)
{
std::cout << value << 'n';
}
int main()
{
printValue(5);
return 0;
}
Давайте отладим эту программу, используя команду шаг с заходом.
Сначала найдите и затем выполните команду отладки шаг с заходом один раз.
Для пользователей Visual Studio
В Visual Studio к команде шаг с заходом (step into) можно получить доступ через меню Отладка (Debug) → Шаг с заходом (Step Into), или нажав клавишу F11.
Для других компиляторов
Если вы используете другую среду IDE, вы, вероятно, найдете команду step into в меню Debug (Отладка) или Run (Выполнить).
Когда ваша программа не запущена и вы выполняете первую команду отладки, вы можете увидеть, что происходит несколько вещей:
- При необходимости программа перекомпилируется.
- Программа начинает выполняться. Поскольку наше приложение является консольной программой, должно открыться окно консоли. Оно будет пустым, потому что мы еще ничего не выводили.
- В вашей IDE могут открываться некоторые диагностические окна, которые могут иметь такие названия, как «Diagnostic Tools» (средства диагностики), «Call Stack» (стек вызовов) и «Watch» (наблюдение). Некоторые из них мы рассмотрим позже – пока вы можете их игнорировать.
Шаг с обходом (step over)
Как и шаг с заходом, команда шаг с обходом (step over) выполняет следующую инструкцию в обычном пути выполнения программы. Однако в то время как шаг с заходом будет входить в вызовы функций и выполнять их построчно, шаг с обходом выполнит всю функцию без остановки и вернет вам управление после выполнения этой функции.
Для пользователей Visual Studio
В Visual Studio к команде шаг с обходом (step over) можно получить доступ через меню Отладка (Debug) → Шаг с обходом (Step Over), или нажав клавишу F10.
Давайте посмотрим на пример, в котором мы делаем шаг с обходом вызова функции printValue:
#include <iostream>
void printValue(int value)
{
std::cout << value << 'n';
}
int main()
{
printValue(5);
return 0;
}
Сначала используйте команду шаг с заходом, пока маркер выполнения не окажется в строке 10:
Теперь выполните шаг с обходом. Отладчик выполнит функцию (которая выводит значение 5 в окно консоли), а затем вернет управление вам в следующей инструкции (строка 12).
Команда шаг с обходом предоставляет удобный способ пропустить функции, если вы уверены, что они уже работают, или не заинтересованы в их отладке прямо сейчас.
Шаги по ssh
ssh -vvv [email protected]_host
Исследовать счастье.
Шагнули слишком далеко
При пошаговом выполнении программы вы обычно можете шагать только вперед. Очень легко случайно перешагнуть то место, которое вы хотели исследовать.
Если вы перешагнете намеченное место назначения, обычное дело – остановить отладку и снова ее перезапустить, соблюдая осторожность, чтобы на этот раз не пройти мимо цели.
Этапы sshd
# 1. Проверьте, работает ли SSHD
netstat -ltpn
# 2. Закройте SSHD
service sshd stop
# 3. Проверьте, был ли закрыт SSHD
netstat -ltpn
# 4. Запустите передний конец и запустите режим отладки
$ (Какая SSHD) -D -D-# -D, чтобы убедиться, что SSHD работает на переднем конце
# 5. Тест, тест, проверка ...
# 6. Перезапуск SSHD
service sshd start
Подведем итог
За эту статью мы разобрались, что:
- работы без ошибок не бывает и дебаг — это отличный способ их решить;
- что такое breakpoint и какой он бывает;
- как настроить exception breakpoint;
- как проводить навигацию в режиме дебага.
Вместо заключения
Мир проявляемых только в релизе багов воистину безграничен, и цели сделать полный его обзор я не ставил. Просто хотелось поделиться собственным опытом, точнее более интересной его частью. Ну и остается только пожелать читателям поменьше сталкиваться с подобными ошибками в работе.