C ++对象的转储内存布局在clang中不起作用

时间:2018-06-23 23:03:30

标签: c++ macos clang llvm

我已经阅读了有关dumping a C++ object's memory layout with Clang的文章,现在我正在尝试使用此功能。我创建了两个类:

// simple.cpp
struct Base
{
    int value;
};

struct Derived : Base
{
    int count;
};

int main(int argc, char* argv[])
{
    return 0;
}

并运行以下命令:

$ clang -cc1 -fdump-record-layouts-simple simple.cpp

却什么也没得到。 lang版本是:

$ clang++ -dumpversion
4.2.1

如果我运行以下命令:

$ clang -cc1 --help

在很多信息中,我可以找到这一点:

...
  -fdump-record-layouts-simple
                          Dump record layout information in a simple form used for testing
  -fdump-record-layouts   Dump record layout information
  -fdump-vtable-layouts   Dump the layouts of all vtables that will be emitted in a translation unit
...

我做错了什么?

2 个答案:

答案 0 :(得分:3)

您需要进行两项更改:

  1. 添加def tokenize_finditer(line): token_pat = re.compile(r'({{)|(}})') result = [] if re.search(token_pat, line): prev = len(line) for match in re.finditer(token_pat, line): start, end = match.span() if start > prev: expr = line[prev:start] if not expr.isspace(): result.append(expr) prev = end result.append(match.group()) return result 编译器开关。没有这个,就不需要LLVM输出,因此永远不会计算记录布局,也不会转储。
  2. 使用代码中的类。如果从未使用过这些类,则不会为它们执行任何代码生成,并且不会转储其布局。

进行这些更改后,将这样的输出打印在stdout上:

-emit-llvm

...

*** Dumping AST Record Layout
Type: struct Base

Layout: <ASTRecordLayout
  Size:32
  DataSize:32
  Alignment:32
  FieldOffsets: [0]>

*** Dumping AST Record Layout
Type: struct Derived

Layout: <ASTRecordLayout
  Size:64
  DataSize:64
  Alignment:32
  FieldOffsets: [32]>

答案 1 :(得分:1)

这是根据我对clang 10.0.1的经验所做的更新:

  • 一个必要条件是,编译器需要一些理由来实际关心所讨论结构的布局。因此,原始问题中的simple.cpp源文件似乎永远不会导致转储。我发现添加代码以实例化这些结构之一,或在其上调用sizeof(...),或调用其虚拟方法之一,都可以。

  • 如果您使用的是-cc1,则需要-emit-llvm -emit-obj引起转储。 (也许其他选项也可以,但是在我的实验中,我至少需要其中一种。)

  • 如果您不想使用-cc1选项(也许是因为您只是想将它们添加到假定具有g ++兼容性的现有构建系统中),这样的调用也可以:{{ 1}}。 (至少在我的系统上,这种方法的好处是,以这种方式调用clang会导致结构布局信息在我的终端中着色。)

  • 我上面写的内容似乎也适用于clang -Xclang -fdump-record-layouts-simple simple.cpp-fdump-record-layouts选项。