我对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索引适合在一起?
我正在尝试使用 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 与共享对象库一起使用?要么,我需要正确的版本 …
我有一个项目,它使用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中的一个错误?
我试图用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)
我的处理程序不再被调用.如何在处理程序后继续?
我正在编译这段代码(使用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)