0

这是一个最小的 Clang 插件,用于打印函数调用的位置。

我有一个名为 FuncCallVisitor 的 RecursiveASTVisitor 访问者,它使用 ASTContext 进行初始化,并尝试打印 CallExpr 的源位置。

#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/FrontendPluginRegistry.h>
#include <clang/Frontend/ASTConsumers.h>

#include <iostream>

using std::unique_ptr;
using std::make_unique;
using std::string;
using namespace clang;

class FuncCallVisitor : public RecursiveASTVisitor<FuncCallVisitor> {
public:
    explicit FuncCallVisitor(CompilerInstance *CI)
        : astContext(&(CI->getASTContext()))
    { }

    bool VisitCallExpr(CallExpr * expr) {
        auto loc = expr->getDirectCallee()->getLocation();
        std::cerr << loc.printToString(astContext->getSourceManager()) << std::endl;
        return true;
    }

private:
    ASTContext *astContext;
};

class FuncCallConsumer : public ASTConsumer {
public:
    explicit FuncCallConsumer(CompilerInstance *CI)
      : m_visitor(FuncCallVisitor(CI))
    { }

    virtual bool HandleTopLevelDecl(DeclGroupRef dg) override {
        for (Decl *decl : dg)
            m_visitor.TraverseDecl(decl);
        return true;
  }

private:
    FuncCallVisitor m_visitor;
};

class ParameterNameChecker : public PluginASTAction {
protected:
    std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &ci,
                                                   llvm::StringRef) override {
        return make_unique<FuncCallConsumer>(&ci);
    }

    bool ParseArgs(const CompilerInstance&, const std::vector<string>&) override {
        return true;
    }
};

static FrontendPluginRegistry::Add<ParameterNameChecker>
X("-print-calls", "print location of function calls");

上面代码中的这个表达式会导致 SEGFAULT

loc.printToString(astContext->getSourceManager())

https://i.stack.imgur.com/AQQWU.png

叮当声调用:

clang-10 test.c -Xclang -load -Xclang ./Plugin.so -Xclang -plugin -Xclang -print-calls -c
Stack dump:
0.  Program arguments: clang-10 ../../ast_test.c -o ast_test -Xclang -load -Xclang ./Plugin.so -Xclang -plugin -Xclang -print-calls -c 
1.  <eof> parser at end of file
/lib/x86_64-linux-gnu/libLLVM-10.so.1(_ZN4llvm3sys15PrintStackTraceERNS_11raw_ostreamE+0x1f)[0x7f17ba3c94ff]
/lib/x86_64-linux-gnu/libLLVM-10.so.1(_ZN4llvm3sys17RunSignalHandlersEv+0x50)[0x7f17ba3c77b0]
/lib/x86_64-linux-gnu/libLLVM-10.so.1(_ZN4llvm3sys15CleanupOnSignalEm+0xdd)[0x7f17ba3c8c4d]
/lib/x86_64-linux-gnu/libLLVM-10.so.1(+0x8d6e60)[0x7f17ba31ee60]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x153c0)[0x7f17c0b993c0]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(+0x797ffe)[0x7f17be873ffe]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(+0x795cb7)[0x7f17be871cb7]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZNK5clang13SourceManager14getPresumedLocENS_14SourceLocationEb+0x25)[0x7f17be874da5]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZNK5clang14SourceLocation5printERN4llvm11raw_ostreamERKNS_13SourceManagerE+0x2d)[0x7f17be86f77d]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZNK5clang14SourceLocation13printToStringB5cxx11ERKNS_13SourceManagerE+0x69)[0x7f17be86fa09]
./Plugin.so(_ZN15FuncCallVisitor13VisitCallExprEPN5clang8CallExprE+0x48)[0x7f17b803a378]
./Plugin.so(_ZN5clang19RecursiveASTVisitorI15FuncCallVisitorE18WalkUpFromCallExprEPNS_8CallExprE+0x60)[0x7f17b8035e90]
./Plugin.so(_ZN5clang19RecursiveASTVisitorI15FuncCallVisitorE16TraverseCallExprEPNS_8CallExprEPN4llvm15SmallVectorImplINS5_14PointerIntPairIPNS_4StmtELj1EbNS5_21PointerLikeTypeTraitsIS9_EENS5_18PointerIntPairInfoIS9_Lj1ESB_EEEEEE+0x5f)[0x7f17b80511ef]
./Plugin.so(_ZN5clang19RecursiveASTVisitorI15FuncCallVisitorE16dataTraverseNodeEPNS_4StmtEPN4llvm15SmallVectorImplINS5_14PointerIntPairIS4_Lj1EbNS5_21PointerLikeTypeTraitsIS4_EENS5_18PointerIntPairInfoIS4_Lj1ES9_EEEEEE+0x16ab)[0x7f17b80309bb]
./Plugin.so(_ZN5clang19RecursiveASTVisitorI15FuncCallVisitorE12TraverseStmtEPNS_4StmtEPN4llvm15SmallVectorImplINS5_14PointerIntPairIS4_Lj1EbNS5_21PointerLikeTypeTraitsIS4_EENS5_18PointerIntPairInfoIS4_Lj1ES9_EEEEEE+0x233)[0x7f17b802c143]
./Plugin.so(_ZN5clang19RecursiveASTVisitorI15FuncCallVisitorE22TraverseFunctionHelperEPNS_12FunctionDeclE+0x55f)[0x7f17b80bf92f]
./Plugin.so(_ZN5clang19RecursiveASTVisitorI15FuncCallVisitorE20TraverseFunctionDeclEPNS_12FunctionDeclE+0x7e)[0x7f17b800fa5e]
./Plugin.so(_ZN5clang19RecursiveASTVisitorI15FuncCallVisitorE12TraverseDeclEPNS_4DeclE+0x9a6)[0x7f17b8007a56]
./Plugin.so(_ZN16FuncCallConsumer18HandleTopLevelDeclEN5clang12DeclGroupRefE+0x69)[0x7f17b8006d89]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZN5clang17MultiplexConsumer18HandleTopLevelDeclENS_12DeclGroupRefE+0x2c)[0x7f17bfddc8bc]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZN5clang8ParseASTERNS_4SemaEbb+0x214)[0x7f17be931ba4]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZN5clang14FrontendAction7ExecuteEv+0x48)[0x7f17bfda7e58]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZN5clang16CompilerInstance13ExecuteActionERNS_14FrontendActionE+0x621)[0x7f17bfd608a1]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZN5clang25ExecuteCompilerInvocationEPNS_16CompilerInstanceE+0x66f)[0x7f17bfe0bdaf]
clang-10(_Z8cc1_mainN4llvm8ArrayRefIPKcEES2_Pv+0x98d)[0x41229d]
clang-10[0x4105b1]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(+0x19d58f2)[0x7f17bfab18f2]
/lib/x86_64-linux-gnu/libLLVM-10.so.1(_ZN4llvm20CrashRecoveryContext9RunSafelyENS_12function_refIFvvEEE+0xd7)[0x7f17ba31ec67]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZNK5clang6driver10CC1Command7ExecuteEN4llvm8ArrayRefINS2_8OptionalINS2_9StringRefEEEEEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPb+0x13f)[0x7f17bfab0e2f]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZNK5clang6driver11Compilation14ExecuteCommandERKNS0_7CommandERPS3_+0x2df)[0x7f17bfa8952f]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZNK5clang6driver11Compilation11ExecuteJobsERKNS0_7JobListERN4llvm15SmallVectorImplISt4pairIiPKNS0_7CommandEEEE+0x7a)[0x7f17bfa896da]
/lib/x86_64-linux-gnu/libclang-cpp.so.10(_ZN5clang6driver6Driver18ExecuteCompilationERNS0_11CompilationERN4llvm15SmallVectorImplISt4pairIiPKNS0_7CommandEEEE+0xdc)[0x7f17bfa9c93c]
clang-10(main+0x259f)[0x41002f]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x7f17b95300b3]
clang-10(_start+0x2e)[0x40d7ce]
clang: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 10.0.0-4ubuntu1 
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
clang: note: diagnostic msg: PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
clang: error: unable to execute command: Segmentation fault (core dumped)
clang: note: diagnostic msg: Error generating preprocessed source(s).

4

0 回答 0