Ответ 1
Ну, dwarf2 создает таблицы для каждой функции, которые содержат то, что записаны в регистре, и где они находятся в стеке, и где указатель/обратный адрес фрейма в стоп-кадре и некоторые другие вещи. Если вы используете dwarf2, компилятор может использовать эту информацию и эффективно восстанавливать регистры и возвращаться к вызывающим в случае исключения. Бэкэндам необходимо предоставить информацию в коде генерации прологов, чтобы сообщить GCC, что регистры сохранены в памяти, и когда указатель кадра был сохранен и такие вещи.
Использование setjmp/longjmp - это просто взломать. Поскольку setjmp/longjmp не знает о структуре броска функции, он будет восстанавливать все регистры, сохраненные в jump-буфере, с помощью setjmp, даже если они не были переопределены функцией throwing. Я на самом деле не специалист в этом, но я думаю, что это очевидно, что это будет неэффективно. Кроме того, каждый раз, когда вы запускаете блок try, setjmp должен вызываться для настройки буфера, содержащего сохраненные регистры, тогда как при использовании dwarf2 компилятор уже предоставляет всю необходимую информацию во время компиляции.
Если серверы не предоставляют необходимую информацию, GCC автоматически откажется от обработки исключений на основе setjmp/longjmp.
Примечание. Я не эксперт GCC. Я просто портировал инструментальную цепочку на простой процессор моего профессора, включая GCC. Надеюсь, я немного помогу.