小编Ale*_*lex的帖子

vtable:底层算法

我对vtable的理解是,如果我有一个带有虚函数的Cat,带有子类Lion和HouseCat的函数,那么有一个vtable,它将speak()映射到每个子类的正确实现.所以一个电话

cat.speak()
Run Code Online (Sandbox Code Playgroud)

编译成

cat.vtable[0]()
Run Code Online (Sandbox Code Playgroud)

也就是说,在vtable位置0中查找并在该位置调用函数指针.

我的问题是:多重继承会发生什么?

让我们添加一个Pet类.Pet有虚函数speak()和eat().HouseCat扩展了Pet,而Lion则没有.现在,我需要确保这一点

pet.eat()
Run Code Online (Sandbox Code Playgroud)

编译为

pet.vtable[1]()
Run Code Online (Sandbox Code Playgroud)

那就是vtable [0]需要说话().Pet.eat需要是插槽1.这是因为cat.speak()需要访问vtable中的插槽0,如果对于HouseCat,插槽0恰好吃了,这将是非常错误的.

编译器如何确保vtable索引适合在一起?

c++ compiler-construction multiple-inheritance vtable vptr

8
推荐指数
1
解决办法
213
查看次数

python 扩展上的地址消毒剂

我正在尝试使用 Address Sanitizer 编译一个 python 扩展。当我加载扩展时,我得到

Traceback (most recent call last):
  File "test.py", line 2, in <module>
    from extension import package
  File "/tmp/python_test/extension/package.py", line 28, in <module>
    from extension._ext import *
ImportError: /tmp/python_test/extension/_ext.so: undefined symbol: __asan_version_mismatch_check_v8
Run Code Online (Sandbox Code Playgroud)

编译器调用是

clang -g -o _ext.so code.ll -fsanitize=address -lrt -lpthread -ldl -lstdc++ -lm -fPIC -shared
Run Code Online (Sandbox Code Playgroud)

因此,它不会从 asan 正确加载符号。我试过使用-static-libsan,但结果是一样的。

我已经看到有些人习惯LD_PRELOAD将 Asan 放入共享对象中,但是,似乎libasan.so我系统上的 Address Sanitizer 来自不同版本的 Address Sanitizer(从 Debian 的 libasan3 包安装,而我从 deb http://apt .llvm.org/stretch/ llvm-toolchain-stretch-8 主)。

那么,如何使 Address Sanitizer 与共享对象库一起使用?要么,我需要正确的版本 …

python clang address-sanitizer

8
推荐指数
1
解决办法
2110
查看次数

kapt:如何处理测试源?

我有一个项目,它使用kapt进行注释处理和代码生成(基于注释).它适用于主要来源,但不适用于测试来源.

一些来源(例如如何在androidTest范围内使用kapt)建议运行gradle kaptTest,但这也不起作用.它将任务报告为"最新",即使在干净之后也是如此.也许这个建议对于android来说是独一无二的.

我从https://github.com/JetBrains/kotlin-examples/tree/master/gradle/kotlin-code-generation下载了示例项目,在测试源中添加了注释用法,我在那里得到了相同的行为.它适用于主要来源,并不适用于测试源.

输出中唯一奇怪的事情是:

> Task :example:compileKotlin
Using kotlin incremental compilation

w: [kapt] Sources output directory is not specified, skipping annotation processing
Run Code Online (Sandbox Code Playgroud)

但正如您所看到的,这不是测试源,而是主要来源和注释处理器应用于那些.

我在注释处理器中添加了一个打印输出.它确实显示为compileKotlin,但不适用于compileTestKotlin.

那么,让kapt在测试源上工作的神奇技巧是什么?

PS:我想有人会要求我的build.gradle.它与我链接的示例中的相同,因此如果您可以使其适用于示例,我可以集成到我的构建文件中.

PPS:我发现的类似问题是Kotlin的gradle kapt插件不适用于自定义源集(JMH),他们建议发布错误报告.也许这是kapt-gradle-plugin中的一个错误?

annotations gradle kotlin

6
推荐指数
1
解决办法
783
查看次数

在SIGNAL中继续使用gdb中的python脚本

我试图用gdb中的python脚本生成一些关于分段错误(和其他信号)的输出.该脚本如下所示:

import gdb

def event_handler(event):
    gdb.execute("set scheduler-locking on") # this is needed to avoid parallel exec of the handler

    gdb.write("\n[ME] SIG " + event.stop_signal)
    frame = gdb.selected_frame()
    while frame:
        gdb.write("\n[ME] FN " + str(frame.name()))
        frame = frame.older()

# make sure output goes to a file
gdb.execute("set logging on") 
gdb.execute("set logging file gdbout")
gdb.events.stop.connect(event_handler)
Run Code Online (Sandbox Code Playgroud)

问题是我需要在每个分段错误上按c和Enter,脚本不会继续.

如果我做

gdb.execute("continue")
Run Code Online (Sandbox Code Playgroud)

在处理程序中,我得到一个StackOverflow.我认为这是因为execute()永远不会返回.如果我做

handle SIGSEGV nostop
Run Code Online (Sandbox Code Playgroud)

我的处理程序不再被调用.如何在处理程序后继续?

python gdb

5
推荐指数
1
解决办法
1033
查看次数

这是LLVM中的错误吗?

我正在编译这段代码(使用clang 3.4.2):

#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>

typedef struct __entry {
    char *name;
    int value;
} entry;

int main(int argv, char **argc) {
            printf("Size of entry: %lu\n", sizeof(entry));
        entry *entry = malloc(sizeof(entry));
        printf("entry is at %lu\n", (uint64_t) entry);
}
Run Code Online (Sandbox Code Playgroud)

我收到这个bitcode:

define i32 @main(i32 %argv, i8** %argc) #0 {
entry:
  %argv.addr = alloca i32, align 4
  %argc.addr = alloca i8**, align 8
  %entry1 = alloca %struct.__entry*, align 8
  store i32 %argv, i32* %argv.addr, align 4
  store i8** %argc, i8*** %argc.addr, …
Run Code Online (Sandbox Code Playgroud)

c sizeof llvm clang

-1
推荐指数
1
解决办法
93
查看次数