В отношении источника, который вы опубликовали, если вы скомпилируете test.c с помощью компилятора C ++, все будет работать как положено (вам нужно будет сделать функции extern "C", что, как я понимаю, вы не сможете вне вашего примера).
Разница в генерируемых символах проливает свет на происходящее:
Компилятор C ++: g++ -c test.c
00000040 s EH_frame1
U ___gxx_personality_v0
0000001a T _callIt
0000005c S _callIt.eh
00000088 b _callback
00000000 T _setCallback
00000000 A _setCallback.eh
C компилятор: gcc -c test.c
00000019 T _callIt
0000003c b _callback
00000000 T _setCallback
Как видите, для каждой функции есть дополнительный символ, заканчивающийся на ".eh", и EH_frame1 - они содержат описание фреймов вызова, которые должны быть отменены в случае возникновения исключения. Если они отсутствуют ... ничего не делать, кроме вызова terminate ().
Учитывая, что C не поддерживает исключения, компилятор C не будет записывать эти символы в объектный файл.
Так что, если вы не контролируете, как эти библиотеки компилируются, вам лучше всего установить обработчик SIGABRT перед синтаксическим анализом и рассматривать его вызов как «исключение произошло». Вам все еще не хватает фактической информации об ошибке, но вы будете знать, что она произошла.