Re[9]: про расстрелы разных storages
От: Erop Россия  
Дата: 20.08.10 10:35
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Другое дело, что нынешний VC такие гадости четко отлавливает. Ну а соответствующий ворнинг лично я всегда назначаю ошибкой.


Ну так в том-то и фишка, что такие ошибки долго не живут и проблем никому не доставляют. ОБЫЧНО, так скажем.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[11]: про расстрелы разных storages
От: Erop Россия  
Дата: 20.08.10 10:42
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Правильно мыслишь. Добавлю — не только выйти оттуда, но и зайти еще куда-то. Это само по себе отнюдь не хитрое стечение обстоятельств, и уж во всяком случае не более хитрое, чем запись по освобожденному указателю в куче. Строго говоря, это вообще практически эквивалентные ситуации. В обоих случаях речь идет о попытке записи туда, где раньше было то, что надо , но теперь уже нечто иное.


Ну так такие ошибки обычно легко обнаруживаются. Трудность обнаружения расстрела кучи именно в том и состоит, то наблюдаемые последствия очень сильно отдалены от самого акта расстрела. Со стеком так ОБЫЧНО не бывает.

PD>Увы, нет кнопки "Господи, помилуй". Минусы я ставить не очень люблю, а смайлики ставлю в основном по прямому назначению — когда мне действительно смешно. А тут плакать хочется

"минус" -- это " не согласен"...

В общем я думаю, что ответ на вопрос "почему расстреливают обычно кучи, а не остальные структуры данных в памяти?" мы совместными усилиями нашли. На том предлагаю и завязать, если у тебя нет добавить ещё чего-то по существу вопроса
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: про расстрелы разных storages
От: Тот кто сидит в пруду Россия  
Дата: 20.08.10 10:48
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Можно и проще


PD>
PD>int* f()
PD>{
PD>    int a[100];
PD>    int* t = a + 50;
PD>    return t;
PD>}

PD>void g(int* p)
PD>{
PD>    int a[100];
PD>    for (int i = 0; i < 100; i++)
PD>        a[i] = i;
PD>    *p = 666;
PD>// это что же такое с a[51] случилось ??? 
PD>}

PD>int _tmain(int argc, _TCHAR* argv[])
PD>{
PD>    int* p = f();
PD>    g(p);
PD>    return 0;
PD>}

PD>


PD>И предупреждений нет, даже при Level4.


Вероятность написать такое случайно на порядки ниже, чем, например, вероятность пропустить амперсенд в цепочке функций, возвращающих ссылку на объект. По крайней мере, для вменяемого разработчика.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[11]: про расстрелы разных storages
От: Pavel Dvorkin Россия  
Дата: 20.08.10 11:01
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Вероятность написать такое случайно на порядки ниже, чем, например, вероятность пропустить амперсенд в цепочке функций, возвращающих ссылку на объект. По крайней мере, для вменяемого разработчика.


Да не случайно я это написал, не случайно. Просто раньше массив int a[100] из функции f был глобальным. Глобальные данные — это не хорошо . Показалось, что он вроде как и не нужен за пределами f, ну вот его туда и перенес

P.S. "Я" тут иносказательно. А то прочтет Егор и устроит новые поучения
With best regards
Pavel Dvorkin
Re[12]: про расстрелы разных storages
От: Тот кто сидит в пруду Россия  
Дата: 20.08.10 11:18
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

ТКС>>Вероятность написать такое случайно на порядки ниже, чем, например, вероятность пропустить амперсенд в цепочке функций, возвращающих ссылку на объект. По крайней мере, для вменяемого разработчика.


PD>Да не случайно я это написал, не случайно. Просто раньше массив int a[100] из функции f был глобальным. Глобальные данные — это не хорошо . Показалось, что он вроде как и не нужен за пределами f, ну вот его туда и перенес


Ну про вменяемого разработчика я тоже не случайно написал
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[13]: про расстрелы разных storages
От: Pavel Dvorkin Россия  
Дата: 20.08.10 11:21
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

PD>>Да не случайно я это написал, не случайно. Просто раньше массив int a[100] из функции f был глобальным. Глобальные данные — это не хорошо . Показалось, что он вроде как и не нужен за пределами f, ну вот его туда и перенес


ТКС>Ну про вменяемого разработчика я тоже не случайно написал


Конечно, это уже доведено до абсурда. Но в более сложном виде вполне возможно, даже при вменяемом разработчике.
With best regards
Pavel Dvorkin
Re[8]: выделение памяти
От: Кодт Россия  
Дата: 20.08.10 14:41
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Мы вообще-то уже про порчу стека терли А с хипом самое полезное средство из MS'овских — отладочный флаг, запрещающий возврат освобожденного блока в хип. В многопоточных программах с фоновой активностью помогает радикально.


И что при этом происходит? Выжирание памяти?

Опять же, есть такая проблема "ABA" — когда из равенства адресов (текущего и запомненного) делают вывод о неизменности содержимого.
Она актуальна для лок-фри алгоритмов, но, мало ли где есть говнокод на основе этого антипаттерна...
С хипом это выглядит так: создали блок, запомнили, попользовались, удалили, создали новый, опа.
Перекуём баги на фичи!
Re[5]: выделение памяти
От: Кодт Россия  
Дата: 20.08.10 14:48
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Кстати, любопытный вопрос. Все, конечно, верно. Но почему мы то и дело слышим о попытках расстрелять кучу, но я почти не помню случаев, когда бы расстреляли стек — не около ESP, это добра навалом, а где-то в глубине ? То есть не выход инднекса за пределы, а просто пальнули по региону стека куда-нибудь. Эффект проявился бы так — в какой-то момент вместо возврата под точку вызова некоей функции управление передавалось бы черт знает куда с AV, конечно. Или испорчены были бы локальные данные.

PD>И про расстрел статических данных я тоже что-то не помню.

Потому что диагностировать запиленный стек несложно: увидим мусор прямо в отладчике.
А вот запиленная куча — это очень отдалённые и очень неявные последствия.

Хорошо, если мы повредили собственные данные. Увидим в них мусор и поймём, что случилась беда.
А если мы повредили список блоков в менеджере кучи (достаточно стрельнуть по отрицательному смещению от выделенного блока) — то в какой-то момент менеджер или решит, что память исчерпана, или повторно выделит уже занятый блок, или просто рухнет.
Перекуём баги на фичи!
Re: выделение памяти
От: Кодт Россия  
Дата: 20.08.10 14:53
Оценка: +1 :)
Топикстартер, наверно, обалдевает — как такой простой и невинный вопрос спровоцировал старожилов на флейм с мордобоем
Перекуём баги на фичи!
Re[2]: выделение памяти
От: Vamp Россия  
Дата: 20.08.10 16:20
Оценка:
К>Топикстартер, наверно, обалдевает — как такой простой и невинный вопрос спровоцировал старожилов на флейм с мордобоем
Стек, куча... Я вот никогда не забуду, как у меня приложение корилось из-за тернарного оператора!
Да здравствует мыло душистое и веревка пушистая.
Re[9]: выделение памяти
От: Тот кто сидит в пруду Россия  
Дата: 20.08.10 18:19
Оценка: +1
Здравствуйте, Кодт, Вы писали:

ТКС>>Мы вообще-то уже про порчу стека терли А с хипом самое полезное средство из MS'овских — отладочный флаг, запрещающий возврат освобожденного блока в хип. В многопоточных программах с фоновой активностью помогает радикально.


К>И что при этом происходит? Выжирание памяти?


Если проблема заключалась в записи в уже освобожденный блок, то исключается ситуация, когда из-за этого упадет совершенно другая подсистема. Программа доживет до вызова _CrtCheckMemory, при котором будет найден проблемный блок. В общем, стабильность воспроизведения ошибки увеличится во много раз.
Если проблема заключалась в записи вообще куда попало, то, очевидно, такой фокус не поможет.

К>Опять же, есть такая проблема "ABA" — когда из равенства адресов (текущего и запомненного) делают вывод о неизменности содержимого.

К>Она актуальна для лок-фри алгоритмов, но, мало ли где есть говнокод на основе этого антипаттерна...
К>С хипом это выглядит так: создали блок, запомнили, попользовались, удалили, создали новый, опа.

Тут я первым делом вспоминаю трекинг объектов в boost::serialization
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[10]: выделение памяти
От: McSeem2 США http://www.antigrain.com
Дата: 20.08.10 18:44
Оценка: -1
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Если проблема заключалась в записи в уже освобожденный блок, то исключается ситуация, когда из-за этого упадет совершенно другая подсистема. Программа доживет до вызова _CrtCheckMemory, при котором будет найден проблемный блок. В общем, стабильность воспроизведения ошибки увеличится во много раз.


По-моему, как раз все наоборот. Если освобожденные блоки всегда размапировать физически, то падать будет именно в том месте, где происходит обращение и виновник мгновенно обнаруживается.

А запрет на возврат памяти — это значит доблестно притвориться, что проблемы не существует. "Давайте задернем занавески и будем думать, что мы едем".
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[11]: выделение памяти
От: Тот кто сидит в пруду Россия  
Дата: 20.08.10 19:58
Оценка: +1
Здравствуйте, McSeem2, Вы писали:

ТКС>>Если проблема заключалась в записи в уже освобожденный блок, то исключается ситуация, когда из-за этого упадет совершенно другая подсистема. Программа доживет до вызова _CrtCheckMemory, при котором будет найден проблемный блок. В общем, стабильность воспроизведения ошибки увеличится во много раз.


MS>По-моему, как раз все наоборот. Если освобожденные блоки всегда размапировать физически, то падать будет именно в том месте, где происходит обращение и виновник мгновенно обнаруживается.


Это во-первых менеджер хипа свой ставить надо, что не всегда реально, во-вторых по странице на блок придется тратить, что еще менее реально.

MS>А запрет на возврат памяти — это значит доблестно притвориться, что проблемы не существует. "Давайте задернем занавески и будем думать, что мы едем".


Ну хоть чуть-чуть надо стараться понять, на что отвечаешь, перед тем как пишешь, а? Я вроде понятно написал — делается это для того, чтобы программа успела доработать до ближайшего вызова _CrtCheckMemory, который найдет битый блок и напишет об этом в debug output. Дальше по адресу и номеру блока можно разбираться дальше.
Была реальная ситуация — после некоторого действия в GUI из обработчика какого-то оконного события шла запись в только что удаленный узел tree control'а. Обычно это попадало в блок, используемый нитью, опрашивающей сервер (так совпадало — размер блока видимо как раз подходил) — и все падало не дожив до следующей аллокации, причем в другой подсистеме. После установки флага _CRTDBG_DELAY_FREE_MEM_DF все встало на свои места, падать начало вообще детерминированно. После пристального разглядывания вершины стека стало понятно, что память портится во время удаления узла дерева, даже сторонние инструментальные средства не понадобились.
А ты — "занавески задернем"
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[6]: выделение памяти
От: Pavel Dvorkin Россия  
Дата: 21.08.10 09:09
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Потому что диагностировать запиленный стек несложно: увидим мусор прямо в отладчике.


А как отличить мусор от немусора в глубине стека ?

К>А вот запиленная куча — это очень отдалённые и очень неявные последствия.


И в стеке могут быть тоже отдаленные.

К>Хорошо, если мы повредили собственные данные. Увидим в них мусор и поймём, что случилась беда.


И в стеке — тоже, если это числа. А если указатели ? адреса возврата ?

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


+1
With best regards
Pavel Dvorkin
Re[7]: выделение памяти
От: Кодт Россия  
Дата: 21.08.10 09:20
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

К>>Потому что диагностировать запиленный стек несложно: увидим мусор прямо в отладчике.

PD>А как отличить мусор от немусора в глубине стека ?

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

Не значит, что мы гарантированно распознаем, что стек запилен — но шансы есть.
Опять же, компиляторы умеют подвёрстывать проверки (ну, хотя бы согласованность значений ESP и EBP).
Перекуём баги на фичи!
Re[8]: выделение памяти
От: Pavel Dvorkin Россия  
Дата: 21.08.10 09:48
Оценка:
Здравствуйте, Кодт, Вы писали:

PD>>А как отличить мусор от немусора в глубине стека ?


К>Внезапные значения переменных, посторонние или уничтоженные точки вызова.

К>Увидел, что какая-то фигня началась, остановился, пробежал глазами... этто что ещё за штуки?!

Во-первых, это надо еще догадаться. что именно стек испорчен, а не что-то иное.
Во-вторых, как его просматривать ? Возле ESP — понятно, а на глубину, скажем, 30-40 Кб ? Будем в окошке Memory тупо листать страницы и пялить глаза в байты ?
В третьих, все же неясно, как фигню отличить от нефигни. Например, увижу я там что-то вроде 0xcdcdcdcd. Это фигня ? Да нет, совсем необязательно, просто неинициализированный пока что элемент автоматического массива. А 0x7e2345FCA — это фигня или нормальный адрес в области системных DLL ?

К>Не значит, что мы гарантированно распознаем, что стек запилен — но шансы есть.

К>Опять же, компиляторы умеют подвёрстывать проверки (ну, хотя бы согласованность значений ESP и EBP).

Я же говорю — возле ESP это обычно не проблема, хуже, когда в глубине.
With best regards
Pavel Dvorkin
Re[7]: выделение памяти
От: Sergey Chadov Россия  
Дата: 21.08.10 11:04
Оценка: 1 (1) :)
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Sergey Chadov, Вы писали:


SC>>Повезло просто в жизни Бывает все вышеперечисленное и даже гораздо веселее. Например, расстрел таблицы виртуальных функций

E>А хрен ли она не read-only? Типа из-за настройки адресов при загрузке?

А хрен-ли ей быть рид-онли?


struct A{
    virtual void M1(){
        printf("M1\n");
    }
    virtual void M2(){
        printf("M2\n");
    }
};

int main(int argc, char* argv[])
{
    A* a = new A;
    a->M1();
    *((int*)a)+=4;
    a->M1();
    return 0;
}
Re[8]: выделение памяти
От: Erop Россия  
Дата: 23.08.10 02:29
Оценка:
Здравствуйте, Sergey Chadov, Вы писали:

SC>>>Повезло просто в жизни Бывает все вышеперечисленное и даже гораздо веселее. Например, расстрел таблицы виртуальных функций

E>>А хрен ли она не read-only? Типа из-за настройки адресов при загрузке?

SC>А хрен-ли ей быть рид-онли?



SC>
SC>struct A{
SC>    virtual void M1(){
SC>        printf("M1\n");
SC>    }
SC>    virtual void M2(){
SC>        printf("M2\n");
SC>    }
SC>};

SC>int main(int argc, char* argv[])
SC>{
SC>    A* a = new A;
    a->>M1();
SC>    *((int*)a)+=4;
    a->>M1();
SC>    return 0;
SC>}
SC>

Это просто расстрел данных. В данном случае портится указатель на таблицу виртуальных функций, а не сама таблица...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[9]: выделение памяти
От: Erop Россия  
Дата: 23.08.10 02:37
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Во-вторых, как его просматривать ? Возле ESP — понятно, а на глубину, скажем, 30-40 Кб ? Будем в окошке Memory тупо листать страницы и пялить глаза в байты ?

Многие отладчики умеют показывать стек в читаемой форме

PD>Например, увижу я там что-то вроде 0xcdcdcdcd. Это фигня ? Да нет, совсем необязательно, просто неинициализированный пока что элемент автоматического массива.


Это, кстати, совсем нехарактерное значение для неинициализированной автоматической переменной...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: выделение памяти
От: carpenter СССР  
Дата: 24.08.10 21:26
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, Кодт, Вы писали:


К>>Это значит — когда-то и где-то выстрелить в произвольный адрес памяти. И случайно угробить внутренние структуры менеджера кучи.


PD>Кстати, любопытный вопрос. Все, конечно, верно. Но почему мы то и дело слышим о попытках расстрелять кучу, но я почти не помню случаев, когда бы расстреляли стек — не около ESP, это добра навалом, а где-то в глубине ?


в 7ке багу отловил — расстреливало стек при при отрисовке линий определенным типом карандаша
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.