Re[9]: бесконечная рекурсия: почему нет ограничений?
От: merk Россия  
Дата: 08.07.08 23:28
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Кстати вот занятный код:


А>
А>class SehException
А>{
А>public:
А>    DWORD code;
А>    PVOID stk_handler, stk_exception, address;

А>    SehException(EXCEPTION_POINTERS* pExp)
А>        : code(pExp->ExceptionRecord->ExceptionCode),
А>        address(pExp->ExceptionRecord->ExceptionAddress)
А>    {
А>        stk_handler = (PVOID)&pExp;
А>        stk_exception = (PVOID)pExp->ContextRecord->Esp;
А>    }
А>};

А>void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp )
А>{
А>    throw SehException(pExp);
А>}


А>void foo()
А>{
А>    volatile char c;
А>    foo();
А>}

А>int main()
А>{
А>    volatile char stk;
А>    MEMORY_BASIC_INFORMATION mbi = {0};
А>    VirtualQuery((LPCVOID)&stk, &mbi, sizeof(mbi));
А>    ULONG size = 0;
А>    for(;;size+=0x1000)
А>    {
А>        MEMORY_BASIC_INFORMATION mbi_test = {0};
А>        VirtualQuery((PCHAR)mbi.AllocationBase+size, &mbi_test, sizeof(mbi_test));
А>        if (mbi_test.AllocationBase!=mbi.AllocationBase)  break;
А>    }
А>    _set_se_translator(trans_func);
А>    try
А>    {
А>        foo();
А>    }
А>    catch(SehException &seh)
А>    {
А>        printf("caught code=0x%x address=0x%x\nstack: base=0x%x before=0x%x handler=0x%x exception=0x%x remain=0x%x size=0x%x\n", 
А>            seh.code, seh.address, mbi.AllocationBase, &stk, seh.stk_handler, seh.stk_exception, 
А>            (unsigned int)seh.stk_exception - (unsigned int)mbi.AllocationBase, size);
А>    }

А>    return 0;
А>}

А>


А>результат у меня

А>[quote]
А>caught code=0xc00000fd address=0x401060
А>stack: base=0x30000 before=0x12ff18 handler=0x32ab8 exception=0x33000 remain=0x3000 size=0x100000
А>[/quote]
А>Походу я ошибся насчет 4 кб, ядро венды кидает SEH на 3й странице от базы, обработчику остается 12кб
я вот тоже подумал, почему они должны оставлять одну страницу в запас, а не N? оказалось три. где-то может и конфигурируется типо хак
Re: бесконечная рекурсия: почему нет ограничений?
От: elcste  
Дата: 09.07.08 09:52
Оценка:
Здравствуйте, varnie, Вы писали:

V>интересуюсь, почему в языках С/C++ никаким образом не предусмотрено предотвращение бесконечной рекурсии.


Видимо, потому что в языках C/C++ бесконечная рекурсия вполне легальна. Ее незачем предотвращать.

V>берем простой пример:

V>void f(){
V>   f();
V>}

V>int main()
V>{
V>    f();
V>    return 0;
V>}

Это полностью корректная программа, которую абстрактная машина должна выполнять бесконечно.

V>stack overflow, но разве нельзя было на уровне языка(ов) это предуcмотреть


А на уровне языка нет никакого stack. Соответственно, не может быть никакого overflow.
Re[2]: бесконечная рекурсия: почему нет ограничений?
От: varnie  
Дата: 09.07.08 12:03
Оценка:
вопрос в догонку. правильно ли я понимаю, что в коде ниже под каждый инстанциированный объект класса Test в его методе-функции foo() при её вызове будет заведена _своя_ статическая переменная?
#define MAX_EXECUTION_DEPTH 100
class Test{
public:
   //...
   void foo() const{
       static int cnt = 0;
       if (cnt++ < MAX_EXECUTION_DEPTH){
          
           //do smth useful here

           --cnt;
       }
   }
};

int main(){
  Test t1, t2, t3;
  t1.foo(); t2.foo(); t3.foo();

  return 0;
}
"Я женился на первой же женщине, которая обратилась ко мне по мейлу." © Л. Торвальдс
Re[9]: бесконечная рекурсия: почему нет ограничений?
От: Юрий Жмеренецкий ICQ 380412032
Дата: 09.07.08 13:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Кстати вот занятный код:


А>
А>...
А>    _set_se_translator(trans_func);
А>...
А>


А старый обработчик кто будет восстанавливать ?
Re: бесконечная рекурсия: почему нет ограничений?
От: alexsy Россия  
Дата: 09.07.08 13:27
Оценка:
Здравствуйте, varnie, Вы писали:

V>интересуюсь, почему в языках С/C++ никаким образом не предусмотрено предотвращение бесконечной рекурсии. в инете искал, не нашел инфы.

V>берем простой пример:
V>
V>void f(){
V>   f();
V>}

V>int main()
V>{
V>    f();
V>    return 0;
V>}
V>

V>компилим, запускаем: "segmentation fault: 11 (core dumped)".
V>stack overflow, но разве нельзя было на уровне языка(ов) это предуcмотреть, введя директиву для установления максимальной глубины вызовов, плюс прицепить вызов а-ля abort() при превышении этого значения.
V>или же создатели С/C++ руководствовались правилом "если вы хотите выстрелить себе в ногу, окей, мы не будем вам в этом мешать"? (вольный пересказ известного крылатого высказывания).
V>спрашиваю из чистого любопытства. спасибо за инфу.

Но ВЕДЬ НЕЛЬЗЯЖЕ ЗАПРЕТИТЬ РУГАТСЯ МАТОМ??
Re: бесконечная рекурсия: почему нет ограничений?
От: Infix Россия http://polos75.livejournal.com/
Дата: 09.07.08 16:03
Оценка:
Но ведь и сборки мусора нет в С++. И в этом его прелесть. Программы получаются быстрые, максимально приближенные к программам на ассемблере.
Re[2]: бесконечная рекурсия: почему нет ограничений?
От: varnie  
Дата: 09.07.08 16:09
Оценка:
все понял (собственно, что я предполагал, то и оказалось верным), но все же хотел на всякий случай поинтересоваться ввиду моего пытливого ума.
еще бы кто-нибудь прояснил мне касаемо моего утверждения двумя постами выше, и я бы успокоилса
"Я женился на первой же женщине, которая обратилась ко мне по мейлу." © Л. Торвальдс
Re: бесконечная рекурсия: почему нет ограничений?
От: Clevelus Россия http://clevelus.ru
Дата: 09.07.08 16:33
Оценка:
Здравствуйте, varnie, Вы писали:

Поведенческого анализа нет практически во всех языках.
Его очень сложно реализовать. Вы привели простой пример, а если в f() много еще чего натыкано и даже return есть (но никогда не вызовется).
Проверка есть только синтаксическая ...

Думаю этого анализа нет, так как по идее нужно анализировать одновременно и код и синтаксис, то есть в общем случае сделать невозможно для release компиляции, но для debug реально.

Вероятно в скором времени появится. Сейчас идет работа над внедрением PHP в структуру ASP.NET. А PHP нетипитизированный язык, придется делать какие-то проверки ... тогда и это внедрят по ходу дела.

ЗЫ: а кто Вам мешает подобную проверку разработать самому?
Доброго времени суток! Мир Вам! С уважением Clevelus.
Если мой ответ понравился — оцените, ни на что не влияет, но будет приятно.
Re[3]: бесконечная рекурсия: почему нет ограничений?
От: merk Россия  
Дата: 09.07.08 17:23
Оценка:
Здравствуйте, varnie, Вы писали:

V>вопрос в догонку. правильно ли я понимаю, что в коде ниже под каждый инстанциированный объект класса Test в его методе-функции foo() при её вызове будет заведена _своя_ статическая переменная?

V>
V>#define MAX_EXECUTION_DEPTH 100
V>class Test{
V>public:
V>   //...
V>   void foo() const{
V>       static int cnt = 0;
V>       if (cnt++ < MAX_EXECUTION_DEPTH){
          
V>           //do smth useful here

V>           --cnt;
V>       }
V>   }
V>};

V>int main(){
V>  Test t1, t2, t3;
V>  t1.foo(); t2.foo(); t3.foo();

V>  return 0;
V>}
V>
Re[4]: бесконечная рекурсия: почему нет ограничений?
От: varnie  
Дата: 09.07.08 17:27
Оценка:
Здравствуйте, merk, Вы писали:
//skipped

эээ, а ответ где?
"Я женился на первой же женщине, которая обратилась ко мне по мейлу." © Л. Торвальдс
Re[3]: бесконечная рекурсия: почему нет ограничений?
От: merk Россия  
Дата: 09.07.08 17:27
Оценка:
Здравствуйте, varnie, Вы писали:

V>вопрос в догонку. правильно ли я понимаю, что в коде ниже под каждый инстанциированный объект класса Test в его методе-функции foo() при её вызове будет заведена _своя_ статическая переменная?

V>
V>#define MAX_EXECUTION_DEPTH 100
V>class Test{
V>public:
V>   //...
V>   void foo() const{
V>       static int cnt = 0;
V>       if (cnt++ < MAX_EXECUTION_DEPTH){
          
V>           //do smth useful here

V>           --cnt;
V>       }
V>   }
V>};

V>int main(){
V>  Test t1, t2, t3;
V>  t1.foo(); t2.foo(); t3.foo();

V>  return 0;
V>}
V>


нет конечно. все static переменные входят в область глобальных переменных. размер которой расчитывается линкером. таким образом это переменная одна на весь класс вообще.
static это просто декларация ГЛОБАЛЬНОЙ переменной ограниченной видимости. инициализируется тоже при инициализации глобальных переменных.
Re[5]: бесконечная рекурсия: почему нет ограничений?
От: merk Россия  
Дата: 09.07.08 17:29
Оценка:
Здравствуйте, varnie, Вы писали:

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

V>//skipped

V>эээ, а ответ где?

кнопочку нажал не ту...ответ ниже
Re[3]: бесконечная рекурсия: почему нет ограничений?
От: Юрий Жмеренецкий ICQ 380412032
Дата: 09.07.08 17:39
Оценка:
Здравствуйте, varnie, Вы писали:

V>вопрос в догонку. правильно ли я понимаю, что в коде ниже под каждый инстанциированный объект класса Test в его методе-функции foo() при её вызове будет заведена _своя_ статическая переменная?


Нет, будет одна на всех, от количества вызовов не зависит.
Вот так будет несколько:
template<int>
struct Test
{
  void foo() const{
       static int cnt = 0;
       //...
  }
};

int main()
{
  Test<__LINE__> t1, t2;
  Test<__LINE__> t3;
  Test<__LINE__> t4;

  t1.foo();
  t2.foo();
  t3.foo();
  t4.foo();
}

Здесь будет три статических объекта.
Re[7]: бесконечная рекурсия: почему нет ограничений?
От: OdesitVadim Украина  
Дата: 09.07.08 17:40
Оценка:
Здравствуйте, varnie, Вы писали:

V>Здравствуйте, c-smile, Вы писали:


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


V>>>собственно, я про что-то подобное применительно к миру С/С++ и осведомлялса изначально.


CS>>У тебя был выход по segmentation fault. Это такая форма abort().

CS>>А какой вариант выхода тебе нужен?
V>такой, чтобы я имел возможность его перехватить в самой программе и корректно его отработать.
Ага, обработаешь. у тебя ведь стековая память кончилась. запуск процедуры, у которой будут локальные параметры приведёт к исключению (нет то где их разместить), хотя банально может не быть места под собственно само сохранение адреса возврата.
... << RSDN@Home 1.2.0 alpha rev. 787>>
Re[4]: бесконечная рекурсия: почему нет ограничений?
От: merk Россия  
Дата: 09.07.08 17:45
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>Здравствуйте, varnie, Вы писали:


V>>вопрос в догонку. правильно ли я понимаю, что в коде ниже под каждый инстанциированный объект класса Test в его методе-функции foo() при её вызове будет заведена _своя_ статическая переменная?


ЮЖ>Нет, будет одна на всех, от количества вызовов не зависит.

ЮЖ>Вот так будет несколько:
ЮЖ>
ЮЖ>template<int>
ЮЖ>struct Test
ЮЖ>{
ЮЖ>  void foo() const{
ЮЖ>       static int cnt = 0;
ЮЖ>       //...
ЮЖ>  }
ЮЖ>};

ЮЖ>int main()
ЮЖ>{
ЮЖ>  Test<__LINE__> t1, t2;
ЮЖ>  Test<__LINE__> t3;
ЮЖ>  Test<__LINE__> t4;

ЮЖ>  t1.foo();
ЮЖ>  t2.foo();
ЮЖ>  t3.foo();
ЮЖ>  t4.foo();
ЮЖ>}
ЮЖ>

ЮЖ>Здесь будет три статических объекта.

вы человека путаете. если тут будут три обьекта, то тут будут три разных инстанцированных типа. а это уже высокие материи. а что такое __LINE__?
Re[8]: бесконечная рекурсия: почему нет ограничений?
От: merk Россия  
Дата: 09.07.08 17:49
Оценка:
Здравствуйте, OdesitVadim, Вы писали:

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


V>>Здравствуйте, c-smile, Вы писали:


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


V>>>>собственно, я про что-то подобное применительно к миру С/С++ и осведомлялса изначально.


CS>>>У тебя был выход по segmentation fault. Это такая форма abort().

CS>>>А какой вариант выхода тебе нужен?
V>>такой, чтобы я имел возможность его перехватить в самой программе и корректно его отработать.
OV>Ага, обработаешь. у тебя ведь стековая память кончилась. запуск процедуры, у которой будут локальные параметры приведёт к исключению (нет то где их разместить), хотя банально может не быть места под собственно само сохранение адреса возврата.

стековая память еще не кончилась в нормальной ос.
ос начинает такую панику несколько ранее, имея в запасе некую часть пользовтательского стека, именно для возможности им обработки ошибок. например ос вводит в доступные еще одну страницу стека пользователя. но если пользователь и этот кусок исчерпает ос уронит весь процесс.
тут мы это с анонимом обсуждали.
и это правльное поведение оси.
Re[5]: бесконечная рекурсия: почему нет ограничений?
От: Юрий Жмеренецкий ICQ 380412032
Дата: 09.07.08 17:50
Оценка:
Здравствуйте, merk, Вы писали:
...
M>вы человека путаете. если тут будут три обьекта, то тут будут три разных инстанцированных типа. а это уже высокие материи.
Да, тут три разных типа. Просто хотел показать когда может быть "несколько" объектов.

M>а что такое __LINE__?

Число — номер строки.
Re: бесконечная рекурсия: почему нет ограничений?
От: Sergey Chadov Россия  
Дата: 09.07.08 17:52
Оценка:
Здравствуйте, varnie, Вы писали:

V>интересуюсь, почему в языках С/C++ никаким образом не предусмотрено предотвращение бесконечной рекурсии. в инете искал, не нашел инфы.


Стоит подумать, сколько раз в жижни среднего программиста — С++-ника встречается такая бага и сколько времени в среднем уходит на отладку. Я думаю и то и другое незначительно.
--
Sergey Chadov

... << RSDN@Home 1.2.0 alpha rev. 685>>
Re[6]: бесконечная рекурсия: почему нет ограничений?
От: varnie  
Дата: 09.07.08 17:53
Оценка:
Здравствуйте, merk

хмм, а как тогда объяснить вот это:

у меня есть класс примерно как класс Test выше (реализующий семантику "функция"), один в один с таким же механизмом предотвращения выполнения ф-ции на глубину превышающую MAX_EXECUTION_DEPTH (перед и после вызова самого исполнения ф-ции я воткнул printf("counter=%d\n", counter).
void CFunction::invoke() { 
    // printf("exec");
    
    static std::size_t counter = 0;
    
    if (_pStmtPtr != NULL) {
       if (counter++ < MAX_FUNCTION_EXECUTION_DEPTH){
          printf("counter=%d\n", counter);
        _pStmtPtr->exec();
         printf("counter=%d\n", counter);
        --counter;
       }else{
          throw CRunTimeException(NULL, "stack depth exceeded");
       }
        
    }
}

и интерпретируется у меня к примеру вот такой код на моем языке:
test1.src
bool test(){}          //для этой ф-ции заведется объект класса CFunction
void C(int i){ C(); }  //для этой еще один

{ //точка входа        //и для этой.
  C(1);
}

для этого случая я вижу:

counter=1
counter=2
counter=3
counter=4
counter=5
counter=6
...
counter=20
"stack depth exceeded" //сработала моя проверка на глубину больше 20. все верно.

далее, интерпретируемый сорец на своем языке я заменяю на:
test2.src
bool test(){}
void C(int i){ test(); test(); test(); test(); test(); test(); test(); test(); test(); test();

{ //точка входа
  C(1);
}

вывод:

counter=1
counter=2
counter=2
counter=1

это не беск. рекурсия, и мой вывод подтверждает корректность реализованных действий. (счетчик увеличился только дважды)
я несколько запутан о том, как понимать эти выводы, но факт в том что я вышерасписанным способом через заведние статич. переменной и отслеживанием её значения реализовал простое предотвращение превышение глубины вызова ф-ций самих из себя.

если взять на вооружение что вы сказали что статич. переменная в методе класса одна на все объекты этого класса, тогда я не догоняю, как тогда понять результаты выше?
спасибо за прояснение.
"Я женился на первой же женщине, которая обратилась ко мне по мейлу." © Л. Торвальдс
Re[7]: бесконечная рекурсия: почему нет ограничений?
От: varnie  
Дата: 09.07.08 18:02
Оценка:
добавочка:
если в src2 будут какие-либо действия в ф-ции test()
void test(){print(2);}
void C(int i){ test(); test(); test(); }

{ C(1); }

то вывод будет:

counter=1
counter=2
counter=3
2 //вывод из тела test()
counter=3
counter=3
2 //вывод из тела test()
counter=3
counter=3
2 //вывод из тела test()
counter=3
counter=2
counter=1

все логично опять же
"Я женился на первой же женщине, которая обратилась ко мне по мейлу." © Л. Торвальдс
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.