КС:2015:Проект:debuger — различия между версиями
Rkovalev (обсуждение | вклад) (→Итоговая оценка) |
Rkovalev (обсуждение | вклад) (→Введение) |
||
Строка 2: | Строка 2: | ||
=== Введение === | === Введение === | ||
− | + | Часто лучший способ понять, каким образом процесс пришёл в какое-то интересное состояние (например, в которое не должен был прийти никогда), - это проследить по шагам за его выполнением. Типичные способы, которые используются на практике: | |
+ | |||
+ | * К процессу можно присоединиться при помощи gdb и отследить его выполнение по шагам. Неудобства: во-первых, не всегда есть возможность присоединиться gdb в интерактивном режиме. Во-вторых, проблема может быть тяжело воспроизводимой, и шагов придётся делать очень много. | ||
+ | * В программу можно добавить отладочную печать, и процесс в процессе работы будет записывать в поток своё состояние. | ||
+ | |||
+ | Как можно добавить отладочную печать? | ||
+ | * Например, можно модифицировать исходный код и пересобрать программу. Можно это сделать руками. Можно при помощи кодогенерации, так это делает, например, [http://ndevilla.free.fr/etrace/ etrace]. Недостаток: не всегда есть возможность пересобрать программу. | ||
+ | * Можно воспользоваться системным вызовом [http://man7.org/linux/man-pages/man2/ptrace.2.html ptrace] и добавить [https://en.wikipedia.org/wiki/INT_%28x86_instruction%29#INT_3 software breakpoints] в интересующие места, как это делает [http://man7.org/linux/man-pages/man1/strace.1.html strace] или [http://www.gnu.org/software/gdb/ gdb]. Или даже ещё проще - написать [http://ndevilla.free.fr/etrace/ скрипт] для gdb. Недостаток этого подхода: это может быть очень медленно, если мы хотим трассировать большое количество событий. | ||
+ | * Можно воспользоваться динамической линковкой через [http://samanbarghi.com/blog/2014/09/05/how-to-wrap-a-system-call-libc-function-in-linux/ LD_PRELOAD или ld --wrap], как это делает [http://man7.org/linux/man-pages/man1/ltrace.1.html ltrace]. Ограничение - нужна динамическая линковка. | ||
+ | * И, наконец, мы можем на лету изменить код программы (это называется [https://en.wikipedia.org/wiki/Instrumentation_%28computer_programming%29 инструментированием]). Так делает, например, [http://valgrind.org/docs/manual/cl-manual.html callgrind]. | ||
+ | |||
+ | === Что требуется === | ||
+ | Вам предлагается написать менее функциональный, но существенно более быстрый аналог callgrind с использованием инструментирования бинарного кода, воспользовавшись библиотекой [http://www.dyninst.org/dyninst DynInst] или аналогичной. Ваша программа должна будет выводить в поток все вызовы функций в исследуемом процессе. | ||
=== Что требуется === | === Что требуется === |
Версия 15:46, 25 сентября 2015
Содержание
Что это за проект
Введение
Часто лучший способ понять, каким образом процесс пришёл в какое-то интересное состояние (например, в которое не должен был прийти никогда), - это проследить по шагам за его выполнением. Типичные способы, которые используются на практике:
- К процессу можно присоединиться при помощи gdb и отследить его выполнение по шагам. Неудобства: во-первых, не всегда есть возможность присоединиться gdb в интерактивном режиме. Во-вторых, проблема может быть тяжело воспроизводимой, и шагов придётся делать очень много.
- В программу можно добавить отладочную печать, и процесс в процессе работы будет записывать в поток своё состояние.
Как можно добавить отладочную печать?
- Например, можно модифицировать исходный код и пересобрать программу. Можно это сделать руками. Можно при помощи кодогенерации, так это делает, например, etrace. Недостаток: не всегда есть возможность пересобрать программу.
- Можно воспользоваться системным вызовом ptrace и добавить software breakpoints в интересующие места, как это делает strace или gdb. Или даже ещё проще - написать скрипт для gdb. Недостаток этого подхода: это может быть очень медленно, если мы хотим трассировать большое количество событий.
- Можно воспользоваться динамической линковкой через LD_PRELOAD или ld --wrap, как это делает ltrace. Ограничение - нужна динамическая линковка.
- И, наконец, мы можем на лету изменить код программы (это называется инструментированием). Так делает, например, callgrind.
Что требуется
Вам предлагается написать менее функциональный, но существенно более быстрый аналог callgrind с использованием инструментирования бинарного кода, воспользовавшись библиотекой DynInst или аналогичной. Ваша программа должна будет выводить в поток все вызовы функций в исследуемом процессе.
Что требуется
Вам предлагается реализовать простой неинтерактивный дебагер, который будет выводить в файл историю вызовов функций в программе.
Чему вы научитесь
1. Узнаете, как устроены отладчики.
2. Узнаете, как устроена память процесса.
3. Подружитесь с эльфом и дварфом.
Начальные требования
1. Технический английский язык.
2. Знание C++.
3. Любознательность.
Критерии оценивания
Требования на зачет в конце 1-го модуля
Нужно будет реализовать программу, которая умеет трейсить вызовы функций и выводить их имена в файл.
Итоговая оценка
- 4 балла. Реализованы требования на зачёт в конце первого модуля.
- 8 баллов. Трейсер выводит имена вызываемых функций, а также, используя отладочную информацию в отлаживаемом бинарнике, выводит значения параметров, с которыми эта функция была вызвана, номер строки и название файла исходого кода, из которых было скомпилировано место вызова.
- +2 балла. Трейсер умеет выводить текущий стек вызовов в человекочитаемом формате.
- +2 балла. Трейсер умеет выводить возвращаемое значение функции.
- +2 балла. Трейсер поддерживает многопоточные приложения.