执行LLVM代码导致Segmentation fault



我有以下代码:

@.str_specifier = constant [4 x i8] c"%sA0"
@.int_specifier = constant [4 x i8] c"%dA0"
@.string_var1 = constant [2 x i8] c"f0"
@.string_var2 = constant [6 x i8] c"Error0"
;    >>> Start Program
declare i32 @printf(i8*, ...)
declare void @exit(i32)
define void @print(i8*) {
call i32 (i8*, ...) @printf(i8* getelementptr ([4 x i8], [4 x i8]* @.str_specifier, i32 0, i32 0), i8* %0)
ret void
}
define void @printi(i32) {
call i32 (i8*, ...) @printf(i8* getelementptr ([4 x i8], [4 x i8]* @.int_specifier, i32 0, i32 0), i32 %0)
ret void
}
declare i8* @malloc(i32)
declare void @free(i8*)
declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)

define void @main()
{   ; >>> Adding function scope
%funcArgs1 = alloca [50 x i32]
; >>> Adding function arguments allocation
; >>> Function body of main
call void @print(i8* getelementptr ([2 x i8], [2 x i8]* @.string_var1, i32 0, i32 0))
%register1 = call i8* @malloc(i32 48)
%register2 = bitcast i8* %register1 to i32*
%register3 = getelementptr inbounds [50 x i32], [50 x i32]* %funcArgs1, i32 0, i32 0
%register4 = ptrtoint i32* %register2 to i32
store i32 %register4, i32* %register3
%register5 = getelementptr inbounds i32, i32* %register2, i32 0
%register6 = add i32 0, 12
store i32 %register6, i32* %register5
%register7 = getelementptr inbounds i32, i32* %register2, i32 1
%register8 = add i32 0, 2
store i32 %register8, i32* %register7
%register9 = getelementptr inbounds i32, i32* %register2, i32 2
store i32 0, i32* %register9
%register10 = getelementptr inbounds i32, i32* %register2, i32 3
store i32 0, i32* %register10
%register11 = getelementptr inbounds i32, i32* %register2, i32 4
store i32 0, i32* %register11
%register12 = getelementptr inbounds i32, i32* %register2, i32 5
store i32 0, i32* %register12
%register13 = getelementptr inbounds i32, i32* %register2, i32 6
store i32 0, i32* %register13
%register14 = getelementptr inbounds i32, i32* %register2, i32 7
store i32 0, i32* %register14
%register15 = getelementptr inbounds i32, i32* %register2, i32 8
store i32 0, i32* %register15
%register16 = getelementptr inbounds i32, i32* %register2, i32 9
store i32 0, i32* %register16
%register17 = getelementptr inbounds i32, i32* %register2, i32 10
store i32 0, i32* %register17
%register18 = getelementptr inbounds i32, i32* %register2, i32 11
store i32 0, i32* %register18
%register19 = load i32, i32* %register3 ; Get variable x
%register20 = add i32 0, 2
%register21 = inttoptr i32 %register20 to i32*
%register22 = getelementptr inbounds i32, i32* %register21, i32 1
%register23 = load i32, i32* %register22
%register24 = getelementptr inbounds i32, i32* %register21, i32 0
%register25 = load i32, i32* %register24
%register26 = add i32 %register23, %register25
%register27 = sub i32 %register26, 4
%register28 = icmp sgt i32 %register20, %register27
br i1 %register28, label %label1, label %label_cont1
label_cont1:
br label %label2
label1:
call void @print(i8* getelementptr ([6 x i8], [6 x i8]* @.string_var2, i32 0, i32 0))
call void @exit(i32 1)
%register200 = add i32 0, 2
br label %label2
label2:
ret void
}   ; >>> Closing function scope

由于某种原因,当我运行它时,Segmentation fault (core dumped)失败了,没有打印一个可以理解的错误。奇怪的是,如果我注释label1中的命令并保留它:

;call void @print(i8* getelementptr ([6 x i8], [6 x i8]* @.string_var2, i32 0, i32 0))
;call void @exit(i32 1)
;%register200 = add i32 0, 2
br label %label2

不会导致分割错误。如果我注释掉这些命令中的至少一个(例如print或sum),它将失败。为什么会这样呢?

编辑:我想我在这里得到相同的结果。(这里有注释)

我明白了"分割错误"。意味着我试图进入记忆我没有权限。但为什么我不能创建一个新的寄存器呢?

编辑2:看起来br i1 %register28, label %label1, label %label_cont1才是真正的原因。

Edit3:我想弄清楚的实际完整代码可以在这里找到。问题是将其更改为alloca i32将导致错误(而不是打印1)。它还包含我试图复制到LLVM的C代码。

段错误源自这一行

%register21 = inttoptr i32 %register20 to i32*

强制转换后,register21应该指向某个内存位置。但是什么内存位置??它的值是一个不存在的地址,不是通过allocainstr或malloc调用获得的。因此,所有其他试图解引用该指针的寄存器都会失望。

我已经改变了inttptr行

最新更新