llvm例外 - RaiseException"?:未知信号"

时间:2016-12-23 16:25:33

标签: c++ exception exception-handling llvm llvm-ir

我尝试使用llvm处理异常,这是一个非常简单的例子,我可以稍后继续构建,但我遇到了一些真正的困难,我不知道为什么。

我得到clang给我以下llir代码,我要传递到MCJIT

; llvm-as c++exn.ll && llvm-ld -native c++exn.bc -lstdc++.6 && ./a.out

%"class.std::ios_base::Init" = type { i8 }
%"class.std::basic_ostream" = type { i32 (...)**, %"class.std::basic_ios" }
%"class.std::basic_ios" = type { %"class.std::ios_base", %"class.std::basic_ostream"*, i8, i8, %"class.std::basic_streambuf"*, %"class.std::ctype"*, %"class.std::num_put"*, %"class.std::num_get"* }
%"class.std::ios_base" = type { i32 (...)**, i64, i64, i32, i32, i32, %"struct.std::ios_base::_Callback_list"*, %"struct.std::ios_base::_Words", [8 x %"struct.std::ios_base::_Words"], i32, %"struct.std::ios_base::_Words"*, %"class.std::locale" }
%"struct.std::ios_base::_Callback_list" = type { %"struct.std::ios_base::_Callback_list"*, void (i32, %"class.std::ios_base"*, i32)*, i32, i32 }
%"struct.std::ios_base::_Words" = type <{ i8*, i32, [4 x i8] }>
%"class.std::locale" = type { %"class.std::locale::_Impl"* }
%"class.std::locale::_Impl" = type { i32, %"class.std::locale::facet"**, i64, %"class.std::locale::facet"**, i8** }
%"class.std::locale::facet" = type <{ i32 (...)**, i32, [4 x i8] }>
%"class.std::basic_streambuf" = type { i32 (...)**, i8*, i8*, i8*, i8*, i8*, i8*, %"class.std::locale" }
%"class.std::ctype" = type <{ %"class.std::locale::facet.base", [4 x i8], i32*, i8, [7 x i8], i32*, i32*, i16*, i8, [256 x i8], [256 x i8], i8, [6 x i8] }>
%"class.std::locale::facet.base" = type <{ i32 (...)**, i32 }>
%"class.std::num_put" = type { %"class.std::locale::facet.base", [4 x i8] }
%"class.std::num_get" = type { %"class.std::locale::facet.base", [4 x i8] }
%class.new_exception = type { %"class.std::exception" }
%"class.std::exception" = type { i32 (...)** }

$_ZN13new_exceptionC2Ev = comdat any

$_ZN13new_exceptionD2Ev = comdat any

$__clang_call_terminate = comdat any

$_ZNSt9exceptionC2Ev = comdat any

$_ZN13new_exceptionD0Ev = comdat any

$_ZTS13new_exception = comdat any

$_ZTI13new_exception = comdat any

$_ZTV13new_exception = comdat any

@_ZStL8__ioinit = internal global %"class.std::ios_base::Init" zeroinitializer, align 1
@_ZTVN10__cxxabiv120__si_class_type_infoE = external global i8*
@_ZTS13new_exception = linkonce_odr constant [16 x i8] c"13new_exception\00", comdat
@_ZTISt9exception = external constant i8*
@_ZTI13new_exception = linkonce_odr constant { i8*, i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([16 x i8], [16 x i8]* @_ZTS13new_exception, i32 0, i32 0), i8* bitcast (i8** @_ZTISt9exception to i8*) }, comdat
@_ZSt4cout = external global %"class.std::basic_ostream", align 8
@.str = private unnamed_addr constant [11 x i8] c"caught !!!\00", align 1
@_ZTV13new_exception = linkonce_odr unnamed_addr constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI13new_exception to i8*), i8* bitcast (void (%class.new_exception*)* @_ZN13new_exceptionD2Ev to i8*), i8* bitcast (void (%class.new_exception*)* @_ZN13new_exceptionD0Ev to i8*), i8* bitcast (i8* (%"class.std::exception"*)* @_ZNKSt9exception4whatEv to i8*)], comdat, align 8
@_ZTVSt9exception = external unnamed_addr constant [5 x i8*]
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_runtime_gen.cpp, i8* null }]

; Function Attrs: uwtable
define internal void @__cxx_global_var_init() #0 {
  call void @_ZNSt8ios_base4InitC1Ev(%"class.std::ios_base::Init"* @_ZStL8__ioinit)
  %1 = call i32 @atexit(void ()* @__dtor__ZStL8__ioinit) #2
  ret void
}

declare void @_ZNSt8ios_base4InitC1Ev(%"class.std::ios_base::Init"*) #1

declare void @_ZNSt8ios_base4InitD1Ev(%"class.std::ios_base::Init"*) #1

; Function Attrs: uwtable
define internal void @__dtor__ZStL8__ioinit() #0 {
  call void @_ZNSt8ios_base4InitD1Ev(%"class.std::ios_base::Init"* @_ZStL8__ioinit)
  ret void
}

; Function Attrs: nounwind
declare i32 @atexit(void ()*) #2

; Function Attrs: uwtable
define void @_Z5functv() #0 {
  %1 = call i8* @__cxa_allocate_exception(i64 8) #2
  %2 = bitcast i8* %1 to %class.new_exception*
  %3 = bitcast %class.new_exception* %2 to i8*
  call void @llvm.memset.p0i8.i64(i8* %3, i8 0, i64 8, i32 16, i1 false)
  call void @_ZN13new_exceptionC2Ev(%class.new_exception* %2) #2
  call void @__cxa_throw(i8* %1, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI13new_exception to i8*), i8* bitcast (void (%class.new_exception*)* @_ZN13new_exceptionD2Ev to i8*)) #11
  unreachable
                                                  ; No predecessors!
  ret void
}

declare i8* @__cxa_allocate_exception(i64)

; Function Attrs: argmemonly nounwind
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) #3

; Function Attrs: inlinehint nounwind uwtable
define linkonce_odr void @_ZN13new_exceptionC2Ev(%class.new_exception* %this) unnamed_addr #4 comdat align 2 {
  %1 = alloca %class.new_exception*, align 8
  store %class.new_exception* %this, %class.new_exception** %1, align 8
  %2 = load %class.new_exception*, %class.new_exception** %1, align 8
  %3 = bitcast %class.new_exception* %2 to %"class.std::exception"*
  call void @_ZNSt9exceptionC2Ev(%"class.std::exception"* %3) #2
  %4 = bitcast %class.new_exception* %2 to i32 (...)***
  store i32 (...)** bitcast (i8** getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTV13new_exception, i64 0, i64 2) to i32 (...)**), i32 (...)*** %4, align 8
  ret void
}

; Function Attrs: inlinehint nounwind uwtable
define linkonce_odr void @_ZN13new_exceptionD2Ev(%class.new_exception* %this) unnamed_addr #4 comdat align 2 {
  %1 = alloca %class.new_exception*, align 8
  store %class.new_exception* %this, %class.new_exception** %1, align 8
  %2 = load %class.new_exception*, %class.new_exception** %1, align 8
  %3 = bitcast %class.new_exception* %2 to %"class.std::exception"*
  call void @_ZNSt9exceptionD2Ev(%"class.std::exception"* %3) #2
  ret void
}

declare void @__cxa_throw(i8*, i8*, i8*)

; Function Attrs: uwtable
define void @_Z4ctchv() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_seh0 to i8*) {
  %1 = alloca i8*
  %2 = alloca i32
  %o = alloca %class.new_exception*, align 8
  invoke void @_Z5functv()
          to label %3 unwind label %4

; <label>:3                                       ; preds = %0
  br label %20

; <label>:4                                       ; preds = %0
  %5 = landingpad { i8*, i32 }
          catch i8* bitcast ({ i8*, i8*, i8* }* @_ZTI13new_exception to i8*)
  %6 = extractvalue { i8*, i32 } %5, 0
  store i8* %6, i8** %1, align 8
  %7 = extractvalue { i8*, i32 } %5, 1
  store i32 %7, i32* %2, align 4
  br label %8

; <label>:8                                       ; preds = %4
  %9 = load i32, i32* %2, align 4
  %10 = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8*, i8* }* @_ZTI13new_exception to i8*)) #2
  %11 = icmp eq i32 %9, %10
  br i1 %11, label %12, label %26

; <label>:12                                      ; preds = %8
  %13 = load i8*, i8** %1, align 8
  %14 = call i8* @__cxa_begin_catch(i8* %13) #2
  %15 = bitcast i8* %14 to %class.new_exception*
  store %class.new_exception* %15, %class.new_exception** %o, align 8
  %16 = invoke dereferenceable(272) %"class.std::basic_ostream"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(%"class.std::basic_ostream"* dereferenceable(272) @_ZSt4cout, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i32 0, i32 0))
          to label %17 unwind label %21

; <label>:17                                      ; preds = %12
  %18 = invoke dereferenceable(272) %"class.std::basic_ostream"* @_ZNSolsEPFRSoS_E(%"class.std::basic_ostream"* %16, %"class.std::basic_ostream"* (%"class.std::basic_ostream"*)* @_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_)
          to label %19 unwind label %21

; <label>:19                                      ; preds = %17
  call void @__cxa_end_catch()
  br label %20

; <label>:20                                      ; preds = %19, %3
  ret void

; <label>:21                                      ; preds = %17, %12
  %22 = landingpad { i8*, i32 }
          cleanup
  %23 = extractvalue { i8*, i32 } %22, 0
  store i8* %23, i8** %1, align 8
  %24 = extractvalue { i8*, i32 } %22, 1
  store i32 %24, i32* %2, align 4
  invoke void @__cxa_end_catch()
          to label %25 unwind label %31

; <label>:25                                      ; preds = %21
  br label %26

; <label>:26                                      ; preds = %25, %8
  %27 = load i8*, i8** %1, align 8
  %28 = load i32, i32* %2, align 4
  %29 = insertvalue { i8*, i32 } undef, i8* %27, 0
  %30 = insertvalue { i8*, i32 } %29, i32 %28, 1
  resume { i8*, i32 } %30

; <label>:31                                      ; preds = %21
  %32 = landingpad { i8*, i32 }
          catch i8* null
  %33 = extractvalue { i8*, i32 } %32, 0
  call void @__clang_call_terminate(i8* %33) #12
  unreachable
}

declare i32 @__gxx_personality_seh0(...)

; Function Attrs: nounwind readnone
declare i32 @llvm.eh.typeid.for(i8*) #5

declare i8* @__cxa_begin_catch(i8*)

declare dereferenceable(272) %"class.std::basic_ostream"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(%"class.std::basic_ostream"* dereferenceable(272), i8*) #1

declare dereferenceable(272) %"class.std::basic_ostream"* @_ZNSolsEPFRSoS_E(%"class.std::basic_ostream"*, %"class.std::basic_ostream"* (%"class.std::basic_ostream"*)*) #1

declare dereferenceable(272) %"class.std::basic_ostream"* @_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(%"class.std::basic_ostream"* dereferenceable(272)) #1

declare void @__cxa_end_catch()

; Function Attrs: noinline noreturn nounwind
define linkonce_odr hidden void @__clang_call_terminate(i8*) #6 comdat {
  %2 = call i8* @__cxa_begin_catch(i8* %0) #2
  call void @_ZSt9terminatev() #12
  unreachable
}

declare void @_ZSt9terminatev()

; Function Attrs: norecurse uwtable
define i32 @main() #7 {
  call void @_Z4ctchv()
  ret i32 0
}

; Function Attrs: nounwind uwtable
define linkonce_odr void @_ZNSt9exceptionC2Ev(%"class.std::exception"* %this) unnamed_addr #8 comdat align 2 {
  %1 = alloca %"class.std::exception"*, align 8
  store %"class.std::exception"* %this, %"class.std::exception"** %1, align 8
  %2 = load %"class.std::exception"*, %"class.std::exception"** %1, align 8
  %3 = bitcast %"class.std::exception"* %2 to i32 (...)***
  store i32 (...)** bitcast (i8** getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVSt9exception, i64 0, i64 2) to i32 (...)**), i32 (...)*** %3, align 8
  ret void
}

; Function Attrs: inlinehint nounwind uwtable
define linkonce_odr void @_ZN13new_exceptionD0Ev(%class.new_exception* %this) unnamed_addr #4 comdat align 2 {
  %1 = alloca %class.new_exception*, align 8
  store %class.new_exception* %this, %class.new_exception** %1, align 8
  %2 = load %class.new_exception*, %class.new_exception** %1, align 8
  call void @_ZN13new_exceptionD2Ev(%class.new_exception* %2) #2
  %3 = bitcast %class.new_exception* %2 to i8*
  call void @_ZdlPv(i8* %3) #13
  ret void
}

; Function Attrs: nounwind
declare i8* @_ZNKSt9exception4whatEv(%"class.std::exception"*) #9

; Function Attrs: nobuiltin nounwind
declare void @_ZdlPv(i8*) #10

; Function Attrs: nounwind
declare void @_ZNSt9exceptionD2Ev(%"class.std::exception"*) #9

; Function Attrs: uwtable
define internal void @_GLOBAL__sub_I_runtime_gen.cpp() #0 {
  call void @__cxx_global_var_init()
  ret void
}

attributes #0 = { uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
attributes #3 = { argmemonly nounwind }
attributes #4 = { inlinehint nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #5 = { nounwind readnone }
attributes #6 = { noinline noreturn nounwind }
attributes #7 = { norecurse uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #8 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #9 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #10 = { nobuiltin nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #11 = { noreturn }
attributes #12 = { noreturn nounwind }
attributes #13 = { builtin nounwind }

这是从以下C ++代码生成的llir代码。

#include <iostream>
#include <exception>

using namespace std;

class new_exception : public exception {
    const char* what() {
        return "new_exception";
    }
};

void funct() {
    throw new_exception();
}

void ctch() {
    try {
        funct();
    } catch(new_exception& o) {
        std::cout << "caught !!!" << std::endl;
    }
}

int main() {
    ctch();
}

当加载它由MCJIT在Windows上编译而没有问题但运行时崩溃,当使用gdb运行时它会停止并显示消息&#39; RaiseException()?:未知信号&#39;。

据我所知,正在正确处理异常,&#34;抓住&#34;通过代码,所以不应该是问题。

我对个性功能的使用是否正确,我已经查看了建议在Windows上使用基于SEH的个性可能是错误的答案。如果这是错误的,为什么clang会写错误的代码呢?

平台是Windows X86_64

target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-w64-windows-gnu"

2 个答案:

答案 0 :(得分:0)

我开始在clangmsvc 2015的Windows C ++中使用异常,并且它们在标准C ++异常(Microsoft文档称为 synchronous )中也能很好地工作>)-无需使用SEH(又称为结构异常处理),Microsoft称之为异步。

答案 1 :(得分:-1)

您的代码包含错误。 main方法不返回int,请检查它:

更改此

int main() {
    ctch();
}

由此:

int main() {
   ctch();
   return 0;
}