longjmp
От: jyuyjiyuijyu  
Дата: 24.03.11 19:27
Оценка: 21 (1)
Всем привет.
удивительно работает такой код с 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
Re: longjmp
От: wvoquine  
Дата: 25.03.11 08:40
Оценка:
В тесте на 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;
}
To be is to be the value of a variable
Re[2]: longjmp
От: wvoquine  
Дата: 25.03.11 08:53
Оценка:
Или просто указатель на стек обратно возвращается
Но я имел дело с симулятором линукса, который в трассу вызовов умел писать, насколько уровней longjmp возвращается
To be is to be the value of a variable
Re[2]: longjmp
От: BulatZiganshin  
Дата: 25.03.11 09:15
Оценка:
Здравствуйте, wvoquine, Вы писали:

W>А вообще реализовать такое, наверное, не очень трудно. Ведь всё равно нужно знать, на сколько уровней вверх прыгаем... Или как иначе реализуется longjmp в рекурсивной функции?


без знания асма этого не понять
Люди, я люблю вас! Будьте бдительны!!!
Re[3]: longjmp
От: wvoquine  
Дата: 25.03.11 09:49
Оценка: :)
Здравствуйте, BulatZiganshin, Вы писали:

BZ>Здравствуйте, wvoquine, Вы писали:


W>>А вообще реализовать такое, наверное, не очень трудно. Ведь всё равно нужно знать, на сколько уровней вверх прыгаем... Или как иначе реализуется longjmp в рекурсивной функции?


BZ>без знания асма этого не понять


без знания того, о каком конкретно асме речь?
или тут имеется в виду что-то типа того, что в x86 это через ljmp на tss созранённый делается?
To be is to be the value of a variable
Re: longjmp
От: trans  
Дата: 25.03.11 11:23
Оценка:
ничего удивительного нет, объявите функции без исключений.
и оптимизатор лучше будет отключить — unwind работать не будет.


void zzz(jmp_buf&jbuf) throw();
void rcu(jmp_buf&jbuf) throw();
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.