Well, dwarf2 buduje tabele dla każdej funkcji, które zawierają co wywoływany zapisane rejestry są i gdzie w stosie są one zapisane, a gdzie wskaźnik ramki/adres zwrotny w callstack jest i kilka innych rzeczy. Jeśli użyjesz dwarf2, kompilator może użyć tych informacji i skutecznie przywrócić rejestry i odskoczyć do rozmówców w przypadku wyjątku. Operatorzy zaplecza muszą dostarczyć informacji w swoim kodzie generowania prologów ich implementacji, aby poinformować GCC, które rejestry są zapisywane w pamięci i kiedy wskaźnik ramki został zapisany i takie rzeczy.
Użycie setjmp/longjmp jest po prostu hackerem. Ponieważ setjmp/longjmp nie wie o strukturze rzucania funkcją, przywróci wszystkie rejestry zapisane w buforze skoku przez setjmp, nawet jeśli nie zostały one nadpisane przez funkcję rzucania. Naprawdę nie jestem ekspertem w tej dziedzinie, ale myślę, że to oczywiste, że nie będzie to skuteczne. Ponadto za każdym razem, gdy uruchamiasz blok try, należy wywołać setjmp, aby skonfigurować bufor zawierający zapisane rejestry, podczas gdy przy użyciu dwarf2 kompilator już dostarcza wszystkie niezbędne informacje w czasie kompilacji.
Jeśli backend nie dostarczy niezbędnych informacji, GCC automatycznie powróci do obsługi wyjątków opartej na setjmp/longjmp.
Uwaga Nie jestem ekspertem GCC. Właśnie przeportowałem toolchain na jakimś łatwym procesorze mojego profesora, w tym GCC. Mam nadzieję, że mogę ci trochę pomóc.
Zauważ, że istnieje http://www.nongnu.org/libunwind/, który ma wydajną implementację 'setjmp', która sama jest oparta na tabelach karłów. Tak więc 'setjmp' po prostu musi przechowywać stackpointer i pozostawić resztę do już działającego odwijaka karłów. –