Мы считаем, что подход, основанный на использовании учебных данных[22], может быть эффективно использован во время занятий по отладке с целью оказания помощи учащимся в достижении их учебных целей с помощью формирующих советов. Наша идея начинается с того, что знания, скрытые в уже исправленных ошибках, могут быть эффективно использованы, чтобы обеспечить лучшее руководство для учеников во время их отладочных сессий. Это позволит новичкам быстро создавать опыт формативной отладки, регулярно аргументируя и подтверждая положительные гипотезы на многообещающем подмножестве отношений dataflow. Как следствие, учащиеся избегают вкладывать усилия и время в следование ошибочным путям в коде, часто не имея реальных намерений и не руководствуясь какими-либо основополагающими критериями. При правильном руководстве они чаще во время сеансов отладки испытывают положительные подтверждения своих догадок.
Целью предлагаемого подхода является предоставление с помощью статического анализа полезной информации, которая может быть использована в процессе отладки начинающими программистами. Он ориентирован на повторное использование прослушанного исходного кода как существующих программных систем, так и небольших образцовых программ, подготовленных преподавателем. Проблемы масштабируемости и отсутствия формального представления требований исключают возможность проведения комплексного и точного межпроцессорного анализа потоков данных на всей системе для автоматического определения положения ошибки с учетом только информации, относящейся к ошибке. Однако, зная точку входа в систему (представленную в виде тестовых примеров), фактическое местоположение ошибки и место отказа, анализ может быть ограничен на пути от места отказа к месту отказа и становится выполнимым.
Подход к анализу потока данных можно обобщить следующим образом:
- построить полное абстрактное синтаксическое дерево ( АСД ) исходного кода системы;
- на основе АСД вывести контекстно-чувствительную ICFG, применив алгоритм, предложенный в [35,39];
- украсить узлы ICFG известными метаданными о точке входа в систему, положение "багг" и положение "отказ";
- получить немедленный DT, применяя алгоритм, предложенный Ленгауэром и Тарьяном (LT) [29, 32] и сохраняя аннотации к информации об ошибках;
- на вычисленном DT, найти непосредственный доминант как сайтов об ошибках, так и сайтов об ошибках: мы ссылаемся к этому узлу, как к предку багга;
- из пути DT, который связывает сайт сбоя с предком ошибок (мы называем его "путь к ошибке"), определите подграфик ICFG, содержащий узлы, в которых доминируют по всем узлам пути;
- выполнять межпроцедурный анализ потока данных, применяя подход, предложенный в [7]. на подграфе, идентифицированном в предыдущем проходе;
- предоставить для каждого узла пути отказа от ошибок вычисленные соотношения потока данных что может привести к баггу.
Чтобы лучше проиллюстрировать вышеописанные шаги, на рисунке 1 приведен запущенный пример.
Шаги от (1) до (3) изображены, например, на небольшом примере на Рисунке 1(а). ICFG получена из абстрактных синтаксических данных системы. Для каждого контекста внутрипроцедурный поток управления Граф построен. В последующем проходе добавляются межпроцедурные связи (например, вызовы), чтобы приклеить контексты вместе. На этом этапе узлы АСД помечаются примечаниями (@BugSite, @FailureSite, @EntryPoint) обнаруживаются и вводятся в ICFG для маркировки заметных узлов. На рисунке 1(b) показаны этапы от (4) до (6), на которых изображены деревья-доминаторы, образованные от ICFG, применяющего алгоритм LT. Процесс начинается на шаге (4) с вычисления первого поиска по глубине для вычисления дерева первого пролета (DFST) графа управляющего потока DT. Метаданные о точке входа, сайте с ошибками сохраняются и сообщаются также на DT. DT затем используются на этапах (5) и (6), которые представляют собой основу подхода. Шаг (5) идентифицирует важный узел, называемый предком ошибки. Этот узел определяется как узел, который доминирует как на сайте сбоев, так и на сайте ошибок, и его можно легко найти, выполняя доминатор. В нашем маленьком примере мы видим, что узел W является родоначальником баггов. Этот шаг очень важно, поскольку это позволяет рассматривать только те отношения потока данных, которые были восстановлены по пути, который ведет от места повреждения к месту отказа.
В частности, предок ошибки используется для вычисления пути от ошибки к ошибке на доминаторе. Этот путь необходим для определения подграфа ICFG, для которого всесторонний поток данных проводится анализ, позволяющий предположить потенциально аномальные взаимосвязи потока данных. Новичок разработчиков просят исследовать такие отношения во время их отладки.
Повторное использование ошибочного исходного кода...4. Подход к учебным данным для обучения отладки. Часть 2.