hyperscan调试环境与技巧

编译

研究源码的一种方法是将它编译为调试版本, 然后可以加断点调试, 也可以查看运行过程中的输出信息.

参考: https://intel.github.io/hyperscan/dev-reference/getting_started.html

注解

以4.6.0版本为准.

第3方依赖库

依赖项 版本 说明
CMake >=2.8.11  
Ragel 6.9  
Python 2.7  
Boost >=1.57 仅需要头文件,无需编译
Pcap >=0.8 Optional: 仅用于示例程序
SQLite ? Optional: 用于编译hsbench

注解

  1. boost不需要编译安装,如果通过系统包管理工具(yum/apt-get)安装的 版本无法满足版本需要,则需要下载源码包,解压后执行类似

    ln -s /home/zzq/boost_1_59_0/boost hyperscan-4.6.0/include/boost 的命令创建符号链接,注意boost路径需要是绝对路径,否则可能找不到。

    或者使用下文描述的BOOST_ROOT选项.

  2. pcap库会依赖flex和bison

CMake配置

When CMake is invoked, it generates build files using the given options. Options are passed to CMake in the form -D<variable name>=<value>. Common options for CMake include:

参数 描述
CMAKE_C_COMPILER C compiler to use. Default is /usr/bin/cc.
CMAKE_CXX_COMPILER C++ compiler to use. Default is /usr/bin/c++.
CMAKE_INSTALL_PREFIX Install directory for install target
CMAKE_BUILD_TYPE Define which kind of build to generate. Valid options are Debug, Release, RelWithDebInfo, and MinSizeRel. Default is RelWithDebInfo.
BUILD_SHARED_LIBS Build Hyperscan as a shared library instead of the default static library.
BUILD_STATIC_AND_SHARED Build both static and shared Hyperscan libs. Default off.
BOOST_ROOT Location of Boost source tree.
DEBUG_OUTPUT Enable very verbose debug output. Default off.
FAT_RUNTIME Build the fat runtime. Default true on Linux, not available elsewhere.
OPTIMISE Turns off compiler optimizations(默认TRUE)

注解

FAT_RUNTIME是4.4版本引入的新特性, 即在编译时同时编译出针对若干种CPU的运行时, 这个开关(在编译Release版本时)默认是打开的. fat runtime目前仅支持Linux. 如果编译早期版本, 或者想要显式指定target architecture, 应在CMAKE_C_FLAGS和CMAKE_CXX_FLAGS中使用-march选项, 例如 cmake -DCMAKE_C_FLAGS="-march=corei7" -DCMAKE_CXX_FLAGS="-march=corei7" <hyperscan-source-path>

编译过程

假设在用户根目录下的hs_build下面编译hyperscan,源码在~/hyperscan-4.6.0, 编译为调试版本的动态链接库(还打开了调试信息输出):

  1. cd ~
  2. mkdir hs_build
  3. cd hs_build
  4. cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=on -DDEBUG_OUTPUT=on -DBOOST_ROOT=/Users/zzq/dev/pkg/boost_1_59_0 ../hyperscan
  5. cmake –build . (别忘了最后有个点)

生成的.so文件放在hs_build/lib目录.

生成dump信息

hyperscan代码大量使用了dump来进行调试, 不过默认情况下dump选项是关闭的, 打开dump功能hyperscan会输出大量信息和文件, 对分析源码很有帮助. Grey类有两个成员, 用来控制dump信息的输出.

  1. dumpFlags

    dump选项. 所有的dump flags如下所示(见src/grey.h):

    enum DumpFlags {
        DUMP_NONE       = 0,
        DUMP_BASICS     = 1 << 0, // Dump basic textual data
        DUMP_PARSE      = 1 << 1, // Dump component tree to .txt
        DUMP_INT_GRAPH  = 1 << 2, // Dump non-implementation graphs
        DUMP_IMPL       = 1 << 3  // Dump implementation graphs
    };
    

    它在构造函数中被初始化为0, hyperscan代码的其他部分也没有修改过此值. 因此要输出dump信息, 需要修改src/grey.cpp, 把此值改为>0的值, 建议改成0xf.

  2. dumpPath

    dump文件保存路径. dumpFlags不为DUMP_NONE时, hyperscan会把某些文件dump到此位置, 这个成员默认没有初始化, 如果只修改dumpFlags, hyperscan运行时会崩溃. 可以修改成”./”.

dump打开之后, hyperscan在运行时会输出很多dot文件, 可以使用graphviz工具直接查看其所表示的图形, 或者将其转换成图片格式. 这些图形会对我们理解内部机制有很大的帮助.

加速编译过程

hyperscan编译需要较长的时间, 修改主目录下的CMakeLists.txt, 配置其不编译某些代码, 可以提高一些编译速度.

比如, 搜索add_subdirectory, 注释掉util, unit, tools, examples等子目录的编译:

#add_subdirectory(util)
#add_subdirectory(unit)
add_subdirectory(doc/dev-reference)
if (EXISTS ${CMAKE_SOURCE_DIR}/tools/CMakeLists.txt)
    #add_subdirectory(tools)
endif()

if(NOT WIN32)
    #add_subdirectory(examples)
endif()

生成源码文档

hyperscan的代码注释使用doxygen风格,对源码生成文档可以有助于我们理解源码。

  1. 在<hyperscan root>/src下运行 doxygen -g , 生成Doxyfile文件
  2. 参考这篇文章 https://www.ibm.com/developerworks/cn/aix/library/au-learningdoxygen/index.html 修改Doxyfile, 建议开启dot支持并装好graphviz, 以生成形象的图表
  3. 运行 doxygen Doxyfile 生成文档