Всем привет.
удивительно работает такой код с longjmp вызывает деструкторы все как полагается
написал как тест при чтении книги а оно корректно работает оказывается
ясно что фишка по всей видимости чисто майкрософтовская
этот код организует вечный цикл
void zzz(jmp_buf&jbuf)
{
longjmp(jbuf, 1);
}
void rcu(jmp_buf&jbuf)
{
std::vector<char> vec(1000000);
zzz(jbuf);
}
int main()
{
jmp_buf jbuf;
setjmp(jbuf);
rcu(jbuf);
}
поствил бряк в деструкторе вектора
> testlinkage.exe!std::vector<char,std::allocator<char> >::~vector<char,std::allocator<char> >() Line 558 C++
msvcr90d.dll!_CallSettingFrame(unsigned long funclet=0x0013fec4, unsigned long pRN=0x00000103, unsigned long dwInCode=0x17e512f3) Line 73 Asm
msvcr90d.dll!__FrameUnwindToState(EHRegistrationNode * pRN=0x0013fec4, void * pDC=0x0013fab0, const _s_FuncInfo * pFuncInfo=0x00418600, int targetState=0xffffffff) Line 1151 C++
msvcr90d.dll!__InternalCxxFrameHandler(EHExceptionRecord * pExcept=0x0013fdac, EHRegistrationNode * pRN=0x0013fec4, _CONTEXT * pContext=0x0013fabc, void * pDC=0x0013fab0, const _s_FuncInfo * pFuncInfo=0x00418600, int CatchDepth=0x00000000, EHRegistrationNode * pMarkerRN=0x00000000, unsigned char recursive=0x00) Line 479 + 0x13 bytes C++
msvcr90d.dll!__CxxFrameHandler3(EHExceptionRecord * pExcept=0x0013fec4, EHRegistrationNode * pRN=0x0013fabc, void * pContext=0x0013fab0, void * pDC=0x0013fec4) Line 311 + 0x1f bytes C++
ntdll.dll!ExecuteHandler2@20() + 0x26 bytes
ntdll.dll!ExecuteHandler@20() + 0x24 bytes
msvcr90d.dll!_longjmp() + 0x4e bytes Asm
testlinkage.exe!__tmainCRTStartup() Line 582 + 0x19 bytes C
testlinkage.exe!mainCRTStartup() Line 399 C
kernel32.dll!_BaseProcessStart@4() + 0x23 bytes
В тесте на gcc под cgwyn деструктор в аналогичной ситуации не вызвался.
А вообще реализовать такое, наверное, не очень трудно. Ведь всё равно нужно знать, на сколько уровней вверх прыгаем... Или как иначе реализуется longjmp в рекурсивной функции?
jmp_buf envs[11];
int done = 0;
void recur(int i)
{
setjmp(envs[i]);
std::cout << i << std::endl;
if ( done )
{
return;
}
if ( i == 0 )
{
done = 1;
longjmp(envs[5], 5);
}
recur(i-1);
std::cout << i << std::endl;
}
int main(char argc, char* argv[])
{
recur(10);
return 0;
}
Или просто указатель на стек обратно возвращается

Но я имел дело с симулятором линукса, который в трассу вызовов умел писать, насколько уровней longjmp возвращается
Здравствуйте, wvoquine, Вы писали:
W>А вообще реализовать такое, наверное, не очень трудно. Ведь всё равно нужно знать, на сколько уровней вверх прыгаем... Или как иначе реализуется longjmp в рекурсивной функции?
без знания асма этого не понять
Здравствуйте, BulatZiganshin, Вы писали:
BZ>Здравствуйте, wvoquine, Вы писали:
W>>А вообще реализовать такое, наверное, не очень трудно. Ведь всё равно нужно знать, на сколько уровней вверх прыгаем... Или как иначе реализуется longjmp в рекурсивной функции?
BZ>без знания асма этого не понять
без знания того, о каком конкретно асме речь?
или тут имеется в виду что-то типа того, что в x86 это через ljmp на tss созранённый делается?
ничего удивительного нет, объявите функции без исключений.
и оптимизатор лучше будет отключить — unwind работать не будет.
void zzz(jmp_buf&jbuf) throw();
void rcu(jmp_buf&jbuf) throw();