Пределы Klee (инструмент анализа программы LLVM)

http://klee.llvm.org/ - это инструмент анализа программ, который работает путем символического выполнения и решения ограничений, поиска возможных входов, которые приведут к сбою программы, и вывода их в качестве тестовых примеров. Это чрезвычайно впечатляющий инженерный проект, который до сих пор дал хорошие результаты, включая обнаружение ряда ошибок в коллекции реализаций Unix с открытым исходным кодом, которые считались одними из самых тщательно протестированных программ никогда не писал.

мой вопрос: что это не делать?

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

2 ответов


Как я могу сказать после чтения http://llvm.org/pubs/2008-12-OSDI-KLEE.html

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

Он не может работать быстро, согласно бумаге, для генерации тестов для 141000 строк кода в COREUTILS (с кодом libc, используемым в их.) И крупнейшая программа имеет только ~10000 строк.

Он ничего не знает о плавающей точке, longjmp/setjmp, потоках, asm; объектах памяти переменного размера.

обновление: / из блога llvm/http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html

5 . Подпроект LLVM "Klee" использует символический анализ ,чтобы "попробовать каждый возможный путь" через фрагмент кода, чтобы найти ошибки в коде, и он производит тесткейса. Это отличный маленький проект это в основном ограничено тем, что не практично работать в крупномасштабных приложениях.

Update2: KLEE требует, чтобы программа была изменена. http://t1.minormatter.com / ~ddunbar/klee-doxygen/overview.html

. Символьная память определяется путем вставки специальных вызовов KLEE (а именно klee_make_symbolic) во время выполнения, KLEE отслеживает все виды использования символьной памяти.


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

[1] модель памяти, используемая интерпретатором LLVM IR в KLEE, требует много памяти и времени. Для каждого пути выполнения KLEE поддерживает частное "адресное пространство". Адресное пространство поддерживает " стек "для локальных переменных и" кучу " для глобальных переменных и динамически распределенных переменных. Однако каждый переменная (локальная или глобальная) завернута в объект MemoryObject (MemoryObject поддерживает метаданные, связанные с этой переменной, такие как начальный адрес, размер и сведения о распределении). Размер памяти, используемый для каждой переменной, будет размером исходной переменной плюс размер объекта MemoryObject. Когда переменная должна быть доступна, KLEE сначала ищет "адресное пространство", чтобы найти соответствующий MemoryObject. Клее проверит MemoryObject и посмотрит, является ли доступ законным. Если это так, доступ будет завершен, и состояние MemoryObject будет обновлено. Такой доступ к памяти, очевидно, медленнее, чем ОЗУ. Такая конструкция может легко поддерживать распространение символических значений. Однако эта модель может быть упрощена путем изучения анализа загрязнений (маркировки символического статуса переменных).

[2] KLEE не хватает моделей для системных сред. Единственный системный компонент, смоделированный в KLEE, - это простая файловая система. Другие, как гнезда или multi-продевать нитку, не поддерживаемый. Когда программа вызывает системные вызовы этих немоделированных компонентов, KLEE либо (1) завершает выполнение и вызывает предупреждение, либо (2) перенаправляет вызов на базовую ОС (проблемы: символические значения должны быть конкретизированы, и некоторые пути будут пропущены; системные вызовы из разных путей выполнения будут мешать друг другу). Я полагаю, что это причина того, что "он ничего не знает", как упоминалось выше.

[3] KLEE не может напрямую работать с двоичными файлами. Клее требуется LLVM ИК-тестируемой программы. В то время как другие инструменты символического выполнения, такие как S2E и VINE из проекта BitBlaze, могут работать с двоичными файлами. Интересно, что проект S2E опирается на KLEE в качестве своего символического механизма выполнения.

Что касается вышеуказанного ответа, у меня лично разные мнения. Во-первых, это правда, что KLEE не может отлично работать с большими программами, но какой инструмент символического выполнения может? Взрыв пути - это скорее теоретическая открытая проблема инженерной проблемы. Во-вторых, как я уже упоминал, кли может работать медленно из-за своей модели памяти. Однако клее не зря замедляет казнь. Он консервативно проверяет повреждения памяти (например, переполнение буфера) и регистрирует набор полезной информации для каждого выполняемого пути (например, ограничения на входы для следования пути). Кроме того, я не знал других инструментов символического выполнения, которые могут работать очень быстро. В-третьих, " плавающая точка, longjmp / setjmp, потоки, asm; объекты памяти переменного размера " - это просто инженерные работы. Например, автор KLEE фактически сделал что-то, чтобы позволить KLEE поддерживать плавающую точку (http://srg.doc.ic.ac.uk/files/papers/kleefp-eurosys-11.pdf). В-третьих, KLEE не обязательно требует инструментирования над программой для маркировки символьных переменных. Как упоминалось выше, символические значения могут быть поданы в программу через командные строки. Фактически, пользователи также могут указывать файлы как символические. При необходимости, пользователи могут просто инструмент функции библиотеки, чтобы сделать входы символическими (раз и навсегда).