Подтвердить что ты не робот

Как подойти к отладке огромной не очень знакомой базы кода?

Редко во время работы над крупномасштабными проектами внезапно вы переходите к проекту, который уже находится в стадии технического обслуживания. В итоге у вас есть огромная кодовая база кода C/С++, при этом не так много информации о дизайне. Последний человек, который мог бы дать вам некоторую передачу знаний о коде, уже покинул компанию и добавил к вашим ужасам, что не хватает времени, чтобы познакомиться с кодом и развить понимание общего модуля/с. В этом сценарии когда вы ожидаете исправить ошибки (основные дампы, функциональные возможности, проблемы с производительностью и т.д.) в модуле /s, какой подход вы возьмете?

Итак, вопрос: Каковы ваши обычные шаги для отладки не очень знакомой базы данных кода C/С++ при попытке исправить ошибку?

EDIT: Enviornment - это Linux, но код также переносится на Windows, поэтому предложения для обоих будут полезными.

4b9b3361

Ответ 1

Если возможно, перейдите через него из main() в проблемную область и следуйте по пути выполнения. По пути вы получите хорошее представление о том, как разные части играют вместе.

Также может быть полезно использовать инструмент анализа статического кода, например CppDepends или даже Doxygen, чтобы выяснить отношения между модулями и иметь возможность просматривать их графически.

Ответ 2

Используйте ручку и бумагу, или изображения/графики/диаграммы в целом, чтобы выяснить, какие части принадлежат где и нарисовать некоторые стрелки и т.д.

Это поможет вам создать и увидеть изображение, которое затем будет усовершенствовано в вашем сознании, когда вы будете более комфортно с ним.

Я использовал аналогичный подход, атакуя адскую систему, в которой было 10 синглтонов, все # включая друг друга. Мне пришлось перерисовывать его несколько раз, чтобы соответствовать всем, но видеть это перед вами помогает.

Также полезно использовать Graphviz при построении графиков зависимостей. Таким образом, вам нужно только перечислить все (в текстовом файле), а затем инструмент будет рисовать (часто неприглядную) картину. (Это то, что я сделал для зависимостей #include в указанной выше системе)

Ответ 3

Как уже говорили другие, писать блок-тесты - отличный способ проникнуть в кодовую базу. Для этого подхода существует ряд преимуществ:

  • Это позволяет вам протестировать предположения о том, как код работает. Добавление проходящего теста доказывает что ваши предположения об этом небольшой фрагмент кода, который вы тестирование правильное. Чем больше прохождение тестов, которые вы пишете, тем лучше вы понимаете код.

  • Ошибка unit test, которая воспроизводит ошибка, которую вы хотите исправить, пройдет когда вы исправляете ошибку, и знаете что вы преуспели.

  • Единичные тесты, которые вы пишете, действуют как документация на будущее.

  • Единичные тесты, которые вы пишете, действуют как регрессионные тесты, поскольку больше ошибок исправлена.

Конечно, добавление модульных тестов в устаревший код не всегда является легкой задачей. К счастью, джентльмен по имени Michael Feathers написал отличную книгу о тема, которая включает в себя некоторые отличные "рецепты" при добавлении тестов к базам кода без модульных тестов.

WELC

Ответ 4

Некоторые указатели:

  • Отладка от части, которая кажется более относящихся к рабочему процессу.
  • Использовать debug строки
  • Получить соответствующий .pdb и прикрепить дамп ядра в отладчиках, таких как Windbg или debugdiag для его анализа.
  • Получить помощь человека в вашем организации, которая хороша в отладки. Даже если он не знаком с вашим codebase, он может быть очень полезен. У меня был предыдущий опыт. Они бы дайте вам ценные указатели.
  • В совете Assass Lavie вы можете использовать статические анализаторы кода.
  • Самое главное: как вы исследовать и отлаживать, документировать все, как вы прогрессируете. Как минимум человек, сменивший вас меньше страдают.

Ответ 5

Три вещи, которые я еще не вижу:

  • напишите некоторые модульные тесты, в которых используются библиотеки/интерфейсы. продемонстрировать/проверить ваше понимание их и повысить их ремонтопригодность.

  • иногда бывает полезно создать специальный макрос утверждения, чтобы проверить, соответствуют ли другие инженерные предположения вашим. вы могли:

    • не использовать их
    • обязуются использовать их, превращая их в "реальные" утверждения через определенный период.
    • обязуются использовать их, позволяя другому инженеру (более знакомому с проектом) распоряжаться или продвигать их к реальным утверждениям
  • Рефакторинг также может помочь. код, который трудно читать, является показателем.

Ответ 6

На первом этапе следует попробовать прочитать код. Попробуйте увидеть код, где находится ошибка. Следуйте за кодом от основного к этому пункту и попытайтесь понять, что может быть неправильным. Прочитайте комментарии от кода (если есть). Обычно имена функций полезны. Поймите, что делает каждая функция.
Как только вы получите представление о коде, вы можете начать отладку кода. Поместите точки останова, где вы не понимаете код или где вы думаете, что ошибка может быть. Начните с кода за строкой. Отладка - это секс. Первоначально мучительно, но медленно вы начинаете наслаждаться этим.

Ответ 7

cscope + ctags доступны как на Linux, так и на Windows (через Cygwin). Если вы дадите им шанс, эти инструменты станут для вас незаменимыми. Хотя, IDE, такие как Visual Studio, также отлично справляются с возможностями просмотра кода.

В такой ситуации, как ваша, из-за ограничений по времени вы управляетесь симптомами. Я имею в виду, что у вас нет времени для реконструкции большой картины/дизайна/архитектуры. Таким образом, вы фокусируетесь на симптомах и работаете наружу, и каждый раз восстанавливаете как можно большую картину, как вам нужно для этой конкретной проблемы. Но не делайте "локальные" решения в спешке. Имейте терпение, чтобы увидеть как можно большую картину, чтобы принять правильное решение. И не попадайтесь в синдром оказания бандитизма, то есть ставьте любое старое исправление, которое будет работать. Ваша задача - сохранить базовую архитектуру/дизайн (если таковая есть, и в какой бы степени вы ее ни открыли).

Сначала это будет борьба, так как ваш ум "охотится" чрезмерно. Но скоро появятся основные темы в дизайне/архитектуре, и все это начнет иметь смысл. Подумайте, не подумав, grasshoppa:)

Ответ 8

У вас должна быть полностью надежная среда разработки, в которой есть много инструментов для отладки (контрольные точки, часы и т.п.). Лучший способ познакомиться с огромным кодом - это поиграть с ним и посмотреть, как данные передаются от одного метода к другому. Кроме того, вы можете перепроектировать код, чтобы увидеть взаимосвязь классов.: D Удачи!

Ответ 9

while (!codeUnderstood)
{
  Breakpoints();
  Run();
  StepInto();
  if(needed)
  { 
   StepOver();
  }
}

Ответ 10

Для меня есть только один способ узнать процесс - Взаимодействие. Определите интерфейсы процесса/системы. Затем определите соотношение вход/выход (эти шаги могут быть не линейными). Как только вы это сделаете, вы можете начать возиться с кодом с достаточной уверенностью, потому что знаете, что он "должен делать", а затем просто выяснять, "как это делается". Для меня, однако, знакомство с интерфейсом (не обязательно пользовательским интерфейсом) системы является ключом. Скажем прямо: никогда не прикасайтесь к коду!

Ответ 11

Не уверен в C/С++, но, исходя из Java и С#, модульное тестирование поможет. В Java есть библиотеки JUnit и TestNG для модульного тестирования, на С# - NUnit и mstest. Не уверен в C/С++.

Прочтите книгу "Рефакторинг: совершенствование дизайна существующего кода" Мартина Фаулера, Кент Бек и др. Будет довольно много советов, я уверен, что это поможет, и дадим вам некоторые рекомендации по улучшению кода.

Один совет: если он не сломался, не исправляйте его. Не пытайтесь исправить какую-либо библиотеку или действительно сложную функцию, если она работает. Сосредоточьтесь на частях, где есть ошибки.

Напишите unit test, чтобы воспроизвести сценарий, в котором должен работать код. Сначала тест завершится с ошибкой. Зафиксируйте код до успешного завершения unit test. Повторите:)

Как только большинство вашего кода, важные биты, которые слишком сложны для ручной отладки и исправления, находятся в автоматизированных модульных тестах, у вас будет система безопасности регрессионных тестов, которая заставит вас чувствовать себя более уверенно в изменении существующая база кода.

Ответ 12

Я не пытаюсь получить обзор всей системы, как это предлагают многие. Если есть что-то, что нужно для исправления, я узнаю наименьшую часть кода, которую я могу исправить ошибку. В следующий раз, когда у меня возникла проблема, я немного более знаком и немного менее обескуражен, и я узнаю немного больше. В конце концов я могу поддержать весь shebang.

Если руководство предложит мне внести существенные изменения в то, с чем я не знаком, я убеждаюсь, что они понимают временные масштабы, и если что-то действительно беспорядочное, предложите переписать.

Ответ 13

Обычно рассматриваемая программа создает какой-то вывод (журнал, распечатка консоли, диалоговое окно).

  • Найдите ближайшее место для своего проблема в выходе программы
  • Поиск по базе кода и поиск текста в этом выпуске
  • Начните создавать свои собственные распечатки, ничего необычного, просто printf( "Calling xxx\n" );, чтобы вы могли точно определить точку, в которой начинается проблема.
  • Как только вы определили место проблемы, установите точку останова
  • Когда вы нажмете точку останова, напечатайте stacktrace

Теперь вы можете видеть, какие у вас есть игроки, и начать анализ того, как вы попали в неправильное место.

Надеемся, что имена методов в стеке вызовов более значимы, чем a, b и c (см. это), и есть какие-то комментарии, документация метода более значимая, чем calling a (часто видели это).

Если источник плохо документирован, не бойтесь оставлять свои комментарии, когда вы выяснили, что происходит. Если дизайн программы позволяет создать unit test для исправленной проблемы.

Ответ 14

Спасибо за приятные ответы, довольно много очков, чтобы заняться. Я работал над такой ситуацией несколько раз, и здесь я следую обычной процедуре:

  • Проверьте журнал сбоев или журнал трассировки. Проверьте соответствующую трассировку, если просто ошибка разработчика, если вы не можете оценить за один раз, а затем перейдите к 2.
  • Воспроизводите ошибку! Это самое важное. Некоторые ошибки встречаются редко, и если вы пытаетесь воспроизвести ошибку, ничего подобного. Это означает, что у вас есть лучший% от взлома.
  • Если вы не можете воспроизвести ошибку, найдите альтернативный вариант использования, где вы можете реально воспроизвести ошибку. Возможность фактически отлаживать сценарий гораздо полезнее, чем просто журнал сбоев.
  • Управляйте версией! Проверьте, существует ли такая же ошибка в предыдущих версиях SW. Если НЕ.. Воила! Вы можете найти между двумя версиями ошибок, которые были введены, и вы можете легко получить разницу в кодах двух версий и нацелиться на соответствующую область. (Иногда это не новый код с ошибкой, но он предоставляет некоторые старые остатки., У нас по крайней мере есть начало, я бы сказал!)
  • Включить трассировку отладки. Запустите пример использования ошибки, проверьте, можете ли вы найти дополнительную информацию, полезную для расследования.
  • Соблюдайте соответствующую область кода через журнал трассировки. Проверьте там код для введения ошибки.
  • Поместите некоторые точки останова в соответствующий код. Изучите поток. Проверьте поток данных. Вывод для указателей (обычных преступников). Повторяйте, пока не почувствуете поток.
  • Если у вас есть версия SW, которая не воспроизводит ошибку, сравните то, что отличается в потоках. Спросите себя: в чем разница?
  • По-прежнему нет удачи! - Арх... Мои трюки истощились... Нужно идти по старому пути. Понимайте код... и понимайте код и понимаете его, пока не знаете, что происходит в коде, когда этот конкретный вариант использования выполняется.
  • С новым пониманием попробуйте отладить код и убедитесь, что решение находится за углом.
  • Самое главное - Опишите понимание, которое вы разработали о модуле/с. Даже маленькие вязаные суровые вещи. Он обязательно поможет вам или кому-то, как вы, когда-нибудь... иногда!

Ответ 15

Вы можете попробовать инструмент GNU cFlow (http://www.gnu.org/software/cflow/). Он даст вам график, начертив поток управления внутри программы.