LLVM IR:向GDB公开变量?

LLVM IR:向GDB公开变量?,gdb,clang,llvm,llvm-ir,llvmlite,Gdb,Clang,Llvm,Llvm Ir,Llvmlite,我正在编写一种自定义编程语言。我正在生成LLVMIR作为中间层(通过LLVMlite),并且我想将变量公开给GDB。这是生成的IR的一个示例: ;ModuleID=“tests/debuginfo.xan” source_filename=“debuginfo.xan” target triple=“x86_64-unknown-linux-gnu” 目标datalayout=“” 定义void@“main”(i32%.1),i8**%.2)!dbg!10 { 条目: %“$argc”=allo

我正在编写一种自定义编程语言。我正在生成LLVMIR作为中间层(通过LLVMlite),并且我想将变量公开给GDB。这是生成的IR的一个示例:

;ModuleID=“tests/debuginfo.xan”
source_filename=“debuginfo.xan”
target triple=“x86_64-unknown-linux-gnu”
目标datalayout=“”
定义void@“main”(i32%.1),i8**%.2)!dbg!10
{
条目:
%“$argc”=alloca i32
存储i32%“.1”,i32*%“$argc”
%“$argv”=alloca i8**
存储i8**%“.2”,i8***%“$argv”
%“$a”=alloca i32
调用void@“llvm.dbg.declare”(元数据i32*%“$a”,元数据!12,元数据!13),!dbg!14
调用void@“llvm.dbg.value”(元数据i32 0,元数据!12,元数据!13),!dbg!15
存储i32 0,i32*%“$a”
ret void
}
声明i32@“printf”(i8*%.”.1“,…)
declare void@“llvm.dbg.declare”(metadata%.”.1、“metadata%.”.2、“metadata%.”.3)不可读
声明void@“llvm.dbg.value”(metadata%.1、metadata%.2、metadata%.3)为READONE
@“NULL”=内部常数i8*inttoptr(i32 0到i8*)
!llvm.dbg.cu=!{ !2 }
!llvm.module.flags=!{ !3, !4, !5 }
!llvm.ident=!{ !6 }
!genby=!{ !16 }
!0 = !定义文件(目录:“/home/proc daemon/Dropbox/Xanathar/Xanathar/tests”,文件名:“debuginfo.xan”)
!1 = !{  }
!2=不同!双编译单元(emissionKind:FullDebug,枚举数:!1,文件:!0,isOptimized:false,语言:DW_LANG_Python,制作人:“Xanathar v.a0.0.1”,运行时版本:0)
!3 = !{i32 2,!“矮人版”,i32 4}
!4 = !{i32 2,!“调试信息版本”,i32 3}
!5 = !{i32 1,!“wchar_大小”,i32 4}
!6 = !{!“Xanathar a0.0.1”}
!7 = !DIDerivedType(基类型:null,大小:64,标记:DW\u标记\u指针\u类型)
!8 = !{ !7 }
!9 = !二聚体(类型:!8)
!10=不同!双程序(文件:!0,isDefinition:true,isLocal:false,isOptimized:false,名称:“main”,作用域:!0,作用域行:1,类型:!9,单位:!2,变量:!1)
!11 = !DIBasicType(编码:DW_ATE_signed,名称:“int”,大小:4)
!12 = !双局部变量(文件:!0,行:1,名称:“a”,作用域:!10,类型:!11)
!13 = !双表达式()
!14 = !位置(列:1,行:1,范围:!10)
!15 = !位置(列:1,行:2,范围:!10)
!16 = !{!“Xanathar”}
我删除了以前的编辑。可以找到生成代码。如您所见,我有一个变量
$a
,我正试图用
llvm.dbg.declare
声明它。然而,尽管
objdump--sym
列出了调试信息(),但gdb在运行
info locals
时不提供任何局部变量。导出变量的正确方法是什么?我如何使用LLVMlite生成它


以下是编译代码:

def编译(self、name、so):
sys.stderr.write('--COMPILE---\n')
若否:
command='clang{0}-g-fstandlone debug-O0'+name+'.ll'
其他:
command='clang{0}-g-fstandlone debug-O0-shared-undefined dynamic_lookup'+name+'.ll'
command=command.format(self.flags)
对于自加载_模块中的i:
如果i[“type”]=“LINKED_SO”:
command+=os.path.abspath(i[“文件”])+''
command=command+'-o'+name+('.so'if-so-else'.o')
#打印(命令)
操作系统(命令)
以下是LLVM确认代码:

def\u compile\u ir(self,builder):
"""
使用给定的引擎编译LLVM IR字符串。
将返回已编译的模块对象。
"""
#从IR创建LLVM模块对象
self.builder=builder
self.builder.ret_void()
self.module.add_named_元数据(“genby”,[“Xanathar”])
llvm_ir=str(self.module)
尝试:
mod=self.binding.parse_程序集(llvm_-ir)
运行时错误除外,如e:
sys.stderr.write(“[ERR]LLVM解析错误!\n”)
系统标准写入(str(e))
如果str(e)中的“预期指令操作码”:
sys.stderr.write(“\n是否忘记从函数返回?”)
出口(1)
mod=0#否则PyCharm会在下面抱怨mod的用法
mod.verify()
#现在添加模块并确保它已准备好执行
自我引擎添加模块(mod)
self.engine.finalize_对象()
self.engine.run\u static\u构造函数()
返回模式
(在此之后,将模块写入文件)

EDIT5(或6,idk):正如Chirag Patel所建议的,我在
ret
指令中添加了一条新的调试语句。然后,事情发生了

(gdb)r
启动程序:/home/proc daemon/Dropbox/Xanathar/Xanathar/tests/debuginfo.xan.o
debuginfo.xan处的断点1,main():1
1宣布$a为int32;
(gdb)本地信息
分段故障(堆芯转储)

IR在我看来是正确的,它包含调试信息。我不知道llvmlite是如何工作的。它与IR有什么关系?如果它调用clang,则可能缺少生成调试信息的选项。[注意:我不更新投票的唯一原因是因为您没有在配置llvmlite对IR所做操作的地方发布代码。]它调用
clang-g-O0
您可以尝试将作用域添加到返回指令吗?“ret void,!dbg!15”@ChiragPatel我这样做了,gdb又出现了几个问题,DIBasicType大小需要以位为单位,DIDerivedType基类型需要限定,并且缺少DisBProgram行。这是我能看到的飞行中的东西。有一个很好的文档介绍了这个主题。也