【问题标题】:llvm exceptions - RaiseException "?:Unknown signal"llvm 异常 - RaiseException "?:Unknown signal"
【发布时间】:2017-05-09 08:33:42
【问题描述】:

我正在尝试让异常与 llvm 一起工作,这是一个非常简单的示例,我以后可以在此基础上进行构建,但我遇到了一些真正的困难,我不知道为什么。

我得到了以下 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 运行时,它会停止并显示消息“RaiseException() ?:Unknown signal”。

据我所知,异常得到了正确处理,被代码“捕获”了,所以不应该是问题。

我对个性功能的使用是否正确,我查看了表明在 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"

【问题讨论】:

  • 用 catch(const new_exception& o) 替换这个 catch(new_exception& o)
  • 它编译所以不会真正改变任何东西
  • 你的程序没有返回一个 int。您的异常已处理,但正常流程仍在继续。您必须返回类似 0 的值以避免该问题。
  • 为什么不改用libc++(支持C++11的LLVM标准库)?

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


【解决方案1】:

我开始在 Windows 的 C++ 中使用 clangmsvc 2015 中的异常,它们在标准 C++ 异常(Microsoft 文档中称为 同步)下工作得非常好——无需使用 Microsoft 称之为异步的 SEH(又名 结构化异常处理)。

【讨论】:

    【解决方案2】:

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

    改变这个

    int main() {
        ctch();
    }
    

    通过这个:

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

    【讨论】:

    • 未知信号错误是因为您的 MAIN 方法没有返回
    • 它可能不会在 C++ 中返回,但会在生成的 llvm 程序集中返回,所以这不是问题! 'ret i32 0'
    • 你能展示一下这个组件吗? GDB生成的那个
    猜你喜欢
    • 1970-01-01
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-11
    • 2021-08-23
    • 1970-01-01
    相关资源
    最近更新 更多