我尝试使用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"
答案 0 :(得分:0)
我开始在clang
和msvc
2015的Windows C ++中使用异常,并且它们在标准C ++异常(Microsoft文档称为 synchronous )中也能很好地工作>)-无需使用SEH(又称为结构异常处理),Microsoft称之为异步。
答案 1 :(得分:-1)
您的代码包含错误。 main方法不返回int,请检查它:
更改此
int main() {
ctch();
}
由此:
int main() {
ctch();
return 0;
}