SVF icon indicating copy to clipboard operation
SVF copied to clipboard

loop does not terminate in debug mode, but terminates in release mode.

Open yuffon opened this issue 1 year ago • 2 comments

I am using SVF 2.7 on a simple IR file. In the debug version of SVF 2.7, I find a loop invocation in the following two functions. This loop invocation is a dead loop.

The function

LLVMModuleSet::getSVFType(const Type* T)

invokes collectTypeInfo(T); But collectTypeInfo(const Type* T) invokes collectSimpleTypeInfo(T);, which invokes getSVFType(ty); again.

This is a dead loop. Now I don't know why I do not meet this dead loop in release version of SVF.

yuffon avatar Oct 29 '23 07:10 yuffon

This is a C++ recursion. It terminates once you have all the types collected here : https://github.com/SVF-tools/SVF/blob/6877950c4a1cb8a9d5ac026e57f28528b4440e7a/svf-llvm/lib/LLVMModule.cpp#L1202

Where do you find the dead loop? Could you give me a case?

yuleisui avatar Oct 29 '23 07:10 yuleisui

This is a C++ recursion. It terminates once you have all the types collected here :

https://github.com/SVF-tools/SVF/blob/6877950c4a1cb8a9d5ac026e57f28528b4440e7a/svf-llvm/lib/LLVMModule.cpp#L1202

Where do you find the dead loop? Could you give me a case?

Hi Yulei @yuleisui, I am debuging SVF 2.7 using llvm 14.0.6. The input program is

#include <malloc.h>
int main(){
    int i;
    int * p;
    p = (int *)malloc(32);
    if(*p){
        free(p);
    }
    *p = 4;
    return 0;
}

The IR file is

; ModuleID = 'cond-free.c'
source_filename = "cond-free.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main() #0 {
entry:
  %retval = alloca i32, align 4
  %i = alloca i32, align 4
  %p = alloca i32*, align 8
  store i32 0, i32* %retval, align 4
  %call = call noalias i8* @malloc(i64 noundef 32) #2
  %0 = bitcast i8* %call to i32*
  store i32* %0, i32** %p, align 8
  %1 = load i32*, i32** %p, align 8
  %2 = load i32, i32* %1, align 4
  %tobool = icmp ne i32 %2, 0
  br i1 %tobool, label %if.then, label %if.end

if.then:                                          ; preds = %entry
  %3 = load i32*, i32** %p, align 8
  %4 = bitcast i32* %3 to i8*
  call void @free(i8* noundef %4) #2
  br label %if.end

if.end:                                           ; preds = %if.then, %entry
  %5 = load i32*, i32** %p, align 8
  store i32 4, i32* %5, align 4
  ret i32 0
}

; Function Attrs: nounwind
declare dso_local noalias i8* @malloc(i64 noundef) #1

; Function Attrs: nounwind
declare dso_local void @free(i8* noundef) #1

attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #2 = { nounwind }

!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"uwtable", i32 1}
!2 = !{i32 7, !"frame-pointer", i32 2}
!3 = !{!"clang version 14.0.6 (https://github.com/llvm/llvm-project.git f28c006a5895fc0e329fe15fead81e37457cb1d1)"}

I have checked the detail of function getSVFType. Line 1139 of LLVMModule.cpp is LLVMType2SVFType[T] = svftype; Here T has an ID as IntegerTyID, svftype is new constructed pointer. Here LLVMType2SVFType.size() increases continuously. But the new inserted type info is not found as expected in the recursion exit.

I killed the process after waiting for three hours. The release version of SVF does not has such issue. The size of LLVMType2SVFType increases to 15 and stops.

yuffon avatar Oct 30 '23 05:10 yuffon