From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Date: Mon, 28 Oct 2002 17:04:05 +0300 From: Sergey Vlasov To: community@altlinux.ru Subject: Re: [Comm] =?koi8-r?B?+s7B1M/LwQ==?= =?koi8-r?Q?=CD?= gcc (3.2, C++) Message-ID: <20021028140405.GA31218@vcserver.mivlgu.internal> Mail-Followup-To: community@altlinux.ru References: <20021028135052.GZ19060@bebi.novosoft.ru> Mime-Version: 1.0 Content-Type: text/plain; charset=koi8-r Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20021028135052.GZ19060@bebi.novosoft.ru> Sender: community-admin@altlinux.ru Errors-To: community-admin@altlinux.ru X-BeenThere: community@altlinux.ru X-Mailman-Version: 2.0.9 Precedence: bulk Reply-To: community@altlinux.ru List-Unsubscribe: , List-Id: List-Post: List-Help: List-Subscribe: , List-Archive: Archived-At: List-Archive: List-Post: On Mon, Oct 28, 2002 at 19:50:52 +0600, Alexey Morozov wrote: > В задаче имеется: > 1. библиотека, написанная на C (libpopt) > 2. код на C++, ее использующий > > Постановка задачи: > > имеется C'шная функция, принимающая в качестве аргумента коллбэк и дергающая > его (при определенных условиях): > /* ------------------- test_lib.c ------------ */ > void some_func(void (*callback_func)(void)) > { > callback_func(); > } > /* ------------------ end of test_lib.c ---------- */ > > С++-ный код коллбэка и функции, инициирующей вызов some_func: > /* ------------------- test.cc --------------- */ > #include > using namespace std; > struct A {}; > void callback_func(void) > { > throw A(); > } > > extern "C" { > void some_func(void (*callback)(void)); > } > int main(void) > { > try { > some_func(callback_func); > } catch (...) { > cerr << "An exception caught" << endl; > } > } > /* ----------------- end of test.cc --------------*/ > > Проблема: происходит аварийное завершение указанной программы (abort), > как если бы брошенный exception не соответствовал throw-спецификации. > > Вопрос: как бы это обойти, и таки поймать в main брошенный в коллбэке > эксепшн? > > Повторю, все происходит на gcc-3.2.1, менять библиотечную функцию по > условию задачи нельзя. Похоже, никак. Новый gcc производит разбор стека при поиске обработчика по записям таблицы, генерируемой при компиляции (по адресам возврата). Для кода на C эта таблица не генерируется, поэтому при обнаружении в цепочке вызовов адреса из такого участка кода происходит облом (как раз в виде вызова unexpected()). Варианты: 1) Избавиться в этом месте от exception вообще и работать старым дедовским способом - по кодам возврата. Если что-то бросается из глубины - ловить внутри callback-a, не допуская распространения в код на C. 2) info gcc рекомендует в подобных случаях компилировать код на C с опцией -fexceptions - тогда работает (но, разумеется, память, выделенная в C-коде, не освобождается - будет утечка). 3) Можно задействовать setjmp/longjmp - но тогда утечка будет уже в C++-частях.