2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3, 4, 5  След.
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 18:02 
Заслуженный участник


20/08/14
11763
Россия, Москва
mustitz в сообщении #1196053 писал(а):
В случае, если в какой-то проге таки произойдёт бесконечная рекурсия, то такая программа может быстро выжрать все ресурсы плюс своп,
Да я в общем-то и не спорю. Но это удобнее и логичнее отлавливать ОС, размещением ниже выделенной памяти под стек несуществующей страницы. При обращении к ней - т.е. переполнению стека - произойдёт прерывание в ОС, которая и решит что делать дальше, добавить программе памяти или закрыть. Я именно так и сказал, что это отдано на откуп ОС.
Кстати вытеснение стека в своп не так уж страшно, к стеку обращения не рандомные, а существенно последовательные, а значит обычно достаточно хранить в физической памяти лишь десяток-сотню-тысячу страниц в районе вершины стека. И оно так и будет из-за вытеснения старых страниц в своп.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 19:20 


10/04/12
705
mihaild в сообщении #1196058 писал(а):
А в чем принципиальная разница между выжиранием всей памяти в стеке и в куче?


Выжирание памяти в стеке приведёт быстро и превышению лимита и приложение будет убито. Ну а выжирание в куче часто приводит к неприятным последствиям. Выжирание памяти у меня было пару раз в результате того, что битая память воспринималась как вектор и передавала свой размер куда-нить в другое место, которое сходило с ума. Всё работало, но о-о-о-очень медленно...

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 19:30 
Заслуженный участник
Аватара пользователя


16/07/14
9144
Цюрих
mustitz, я имею в виду, почему есть смысл бороться с половиной проблемы (выжирание стека), если мы можем легко получить все те же самые проблемы из-за выжирания кучи.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 21:52 


10/04/12
705
Если мы можем бороться с половиной проблем — уже хлеб.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 22:35 


09/05/10
122
Ростов-на-Дону
Dmitriy40 в сообщении #1196035 писал(а):
Скорее страница (4к), но это зависит от ОС.

Вот именно, зависит от ОС. В DOSе это и будет как я уже сказал один параграф.
Dmitriy40 в сообщении #1196035 писал(а):
Точнее указатель то можно настроить с точностью до байта

Я бы сказал, что нельзя. Если в 16-ти битном режиме указатель не будет кратен 2, в 32-ух битном режиме указатель не будет кратен
4, ну и так далее, то обращение к стеку вызовет исключение. И если это исключение не обрабатывается, то программа "вылетит", в лучшем случае, а может быть и BSOD.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 23:12 
Заслуженный участник


20/08/14
11763
Россия, Москва
Tod Leben в сообщении #1196128 писал(а):
Я бы сказал, что нельзя. Если в 16-ти битном режиме указатель не будет кратен 2, в 32-ух битном режиме указатель не будет кратен 4, ну и так далее, то обращение к стеку вызовет исключение. И если это исключение не обрабатывается, то программа "вылетит", в лучшем случае, а может быть и BSOD.

Не совсем так. В документе под страшным названием 64-ia-32-architectures-software-developer-manual-325462.pdf от производителя процессоров (Intel) в разделе 6 в пункте 6.2.2 Stack Alignment прямо сказано следующее:
Цитата:
The stack pointer for a stack segment should be aligned on 16-bit (word) or 32-bit (double-word) boundaries, depending on the width of the stack segment.
...
The processor does not check stack pointer alignment. It is the responsibility of the programs, tasks, and system procedures running on the processor to maintain proper alignment of stack pointers. Misaligning a stack pointer can cause serious performance degradation and in some instances program failures.
Обратите внимание на выделенное жирным. Никаких исключений из-за невыровненного стека быть не должно, лишь замедление и в некоторых случаях сбой программы.
Их и нет, вот тестовая программка:
код: [ скачать ] [ спрятать ]
Используется синтаксис Delphi
var     s0, s1, s2, s3, s4: longword;
begin
        asm
                mov     s0,ESP
                dec     ESP
                mov     s1,ESP
                push    EAX
                mov     s2,ESP
                push    AX
                mov     s3,ESP
                pop     EAX
                mov     s4,ESP
                mov     EBX,s3
                mov     [EBX],EAX
                mov     ESP,s0
        end;
        Writeln(IntToHex(s0, 8), 'h,', IntToHex(s1, 8), 'h,', IntToHex(s2, 8), 'h,', IntToHex(s3, 8), 'h,', IntToHex(s4, 8), 'h');
end.
Её вывод: 0018FF5Ch,0018FF5Bh,0018FF57h,0018FF55h,0018FF59h.
Жду Ваших объяснений как это я смог под Win7-x64 увидеть некратные четырём значения в ESP без вылета программы?

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение01.03.2017, 00:47 


09/05/10
122
Ростов-на-Дону
Я в английском не силён, пришлось пользоваться переводчиком.
Цитата:
Указатель стека в сегменте стека должен быть выровнен по 16-разрядное (слово) или 32-разрядное (двойное слово) границы, в зависимости от ширины сегмента стека.
...
Процессор не проверяет выравнивание указателя стека. Это является обязанностью программ, задач и процедур, работающих на процессоре для поддержания правильного выравнивания указателей стека. Разрегулировывая указатель стека может привести к серьезной деградации производительности и в некоторых случаях сбои программы.


Вы внимательно прочли то, что мне приводите? На счёт "кратным четырём" я может и ошибаюсь, хотя выше в цитате это написано явно "32-разрядное (двойное слово)". Хорошо, пусть будет кратным 2.
Dmitriy40 в сообщении #1196139 писал(а):
Жду Ваших объяснений как это я смог под Win7-x64 увидеть некратные четырём значения в ESP без вылета программы?

:lol: Вы бы ещё на Win10 это попробовали! У меня в то время стоял x486, если не ошибаюсь. Это так, на всякий случай, может сейчас процессоры принципиально иной архитектуры. Попробуйте в реальном режиме, или хотя бы под WinXP. И я посмотрю как Вы "с точностью до байта" настроите указатель. Если у меня XP-ишка в BSOD вылетала. Да, и возьмите реальный ассемблер(MASM), а не какой-то интерпретатор.
Про исключение я сейчас не вспомню где читал. Так как привести ссылку на литературу не могу, считайте что соврал. Хоть это и не суть, но я ясно помню, что читал именно об этом. Я писал о том, что известно мне по своему опыту. Литературы такой, что вы мне привели у меня нет, да и английским владею с трудом.
P.S. В этой статье, что Вы мне привели, говорится о защищенном режиме, а то чтиво, что читал я могло быть о реальном режиме. Скорее всего оно так и было. А в этих режимах разные механизмы, и многое не документировано.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение01.03.2017, 01:40 


11/12/14
893
Tod Leben в сообщении #1195995 писал(а):
SP настраивается только на стековый кадр. Переменные помещаются в стек до вызова функции.


Опять чушь говорите. Сами почитайте хоть какие то материалы по вопросу.
Переменные помещает на стек вызываемая функция. Тут вся тема началась с этого по сути вопроса, не сбивайте с толку топиккастера и сами приведите свои знания в порядок.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение01.03.2017, 02:41 
Заслуженный участник
Аватара пользователя


16/07/14
9144
Цюрих
aa_dav в сообщении #1196155 писал(а):
Переменные помещает на стек вызываемая функция
Это я чего-то не понимаю?
https://godbolt.org/g/OIZoza - вызывающая функция делает push.

И если на стек значения кладет вызываемая функция, то откуда она их берет?

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение01.03.2017, 02:53 
Заслуженный участник


20/08/14
11763
Россия, Москва

(Оффтоп)

Tod Leben в сообщении #1196150 писал(а):
Вы внимательно прочли то, что мне приводите?
Да. И даже сказал Вам куда обратить внимание, на эти вот слова: "Процессор не проверяет выравнивание указателя стека.". Не проверяет. Вообще. Никакой из семейства x86.

Tod Leben в сообщении #1196150 писал(а):
Вы бы ещё на Win10 это попробовали!
Чем Вам винда не угодила? Я же чистый ассемблерный код использовал, он идёт напрямую в процессор, ОС туда не вмешивается.

Tod Leben в сообщении #1196150 писал(а):
Попробуйте в реальном режиме, или хотя бы под WinXP.
Ну реального режима мне взять неоткуда, а вот на XP-x32 запустил - соотношение выведенных цифр то же, ошибок и вылетов не было.

Tod Leben в сообщении #1196150 писал(а):
может сейчас процессоры принципиально иной архитектуры.
Не может (точнее никак не влияет), они все совместимы по командам. И по большинству исключений.

Tod Leben в сообщении #1196150 писал(а):
Да, и возьмите реальный ассемблер(MASM), а не какой-то интерпретатор.
Это не интерпретатор, это натуральный компилятор, на выходе стандартный exe файл, именно с тем куском ассемблерного кода, что видите выше. А делать вывод текста на MASM я замучаюсь.

Tod Leben в сообщении #1196150 писал(а):
В этой статье, что Вы мне привели, говорится о защищенном режиме,
В этой статье говорится о всех режимах работы процессора. И когда есть разница - всегда обязательно оговаривается. И причём не конкретного процессора, а именно архитектуры x86 (и x64). Физически реализованной ещё с i386 процессора.

Исключение при невыровненном стеке вовсе не может являться недокументированной особенностью.

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

В общем, Вы вероятно спутали исключение невыравненного обращения к памяти (любого обращения, не только стека) и обращения в стек. Но первое включается лишь для отладки программ, если вообще кто-то до сих пор им пользуется ... А выравнивание стека (да и любых данных) на границу 16 или 32 битов (а лучше строки кэша) лишь повышает производительность, но не является обязательным. И это как повелось ещё с 8086, так и тянется для всех процессоров. (Для некоторых векторных команд данные должны быть выровнены, но это другое и к стеку и регистру ESP не относится.)

mihaild в сообщении #1196159 писал(а):
Это я чего-то не понимаю?
Это проблема терминологии, речь шла об локальных переменных в стеке уже вызванной функции, не о параметрах передаваемых в/из функцию. Но Tod Leben и за ним и Вы поняли по другому.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение01.03.2017, 03:07 
Аватара пользователя


07/02/12
1433
Питер
mihaild в сообщении #1196058 писал(а):
Серверам надо работать стабильно, да и для юзверя такая ситуация не очень приятна. Поэтому есть хорошее решение ограничить размер стека у всех приложений для безболезненного отлавливания таких ситуаций.

Вы недооцениваете наличие полезных костылей в современных ОС.
С Вами начнут бороться (в плане приоритетов) не только при неадекватном росте размера стека, но и при росте количества стеков. И даже при чрезмерно активной работе с файлами. Я уже молчу про рост размера вашей Кучи.

Бороться, кстати, относительно коряво, но чем богаты. В любом случае, говорить об ограничении стека в этом контексте совершенно бессмысленно.

Если грубо - дело в том, что все это (кеш файлов, память, стек, исполняемый код в DLL/EXE/ELF) с поправкой на коэффициенты - есть одно и то же в контексте кеширования в оперативной памяти и хранения на диске. Приложение при работе с любыми из этих ресурсов (и не только этих) и не знает, будут ли данные взяты/записаны из/в оперативной памяти, либо произойдет обращение к диску - ОС решает, что кешировать, а что сбрасывать (как правило, на страничном уровне). Давно нет понятия свободной физической памяти, его синтезируют для приложений довольно искуственно.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение01.03.2017, 03:41 


11/12/14
893
Dmitriy40 в сообщении #1196161 писал(а):
речь шла об локальных переменных в стеке уже вызванной функции


Не просто шла речь, а было явно черным по белому написано про локальные переменные, так что тонкости терминологии тут не причём, как Tod Leben мог понять нечто иное мне непонятно.

P.S.

Dmitriy40 в сообщении #1196161 писал(а):
Для некоторых векторных команд данные должны быть выровнены, но это другое и к стеку и регистру ESP не относится


Кстати, для x64 уже нередко относится. По крайней мере в 64-битном WinAPI соглашение о вызовах предполагает, что FPU больше не используется, а вся арифметика вещественных ведется на SSE. Вполне может выстрелить на команде предполагающей выровненный адрес.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение01.03.2017, 04:07 
Заслуженный участник


20/08/14
11763
Россия, Москва

(PS. О x64)

aa_dav в сообщении #1196166 писал(а):
По крайней мере в 64-битном WinAPI соглашение о вызовах предполагает, что FPU больше не используется, а вся арифметика вещественных ведется на SSE. Вполне может выстрелить на команде предполагающей выровненный адрес.
Засада (ещё и из-за точности вычислений, int64 в double без заметного округления не засовывается). Поэтому стараюсь везде использовать vmovdqu вместо vmovdqa, на новых процессорах она не медленнее второй на выровненных данных, зато не будет исключений доступа. Правда даже и не вспомню где в WinAPI передаются вещественные значения т.к. ни разу такого не использовал. :-)

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение01.03.2017, 05:22 


11/12/14
893

(Оффтоп)

Dmitriy40 в сообщении #1196168 писал(а):
Правда даже и не вспомню где в WinAPI передаются вещественные значения т.к. ни разу такого не использовал.

Это да, но это соглашение о вызовах столь удачно подобрано, что компиляторы просто используют его даже для своих внутренних нужд (по крайней мере C++).
Причём за базис было взято сишное справа-налево с подчисткой стека вызывающим кодом для обеспечения поддержки vararg, но при этом еще 4 первых аргумента пихаются в регистры и на стеке всегда резервируется 32 байта под эти регистры, даже если не все параметры используются (ну в рамках sub esp это не играет роли).
И других соглашений просто уже нет.
На линуксе, насколько я знаю, похожая картина, хотя с некоторыми небольшими отличиями, но суть та же - OS ABI это одновременно единственная C/C++ calling convention.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение01.03.2017, 14:23 
Аватара пользователя


31/10/08
1244
Отвечу зачинщику темы.
Alex Fox
Alex Fox в сообщении #1195949 писал(а):
Но как он может подсчитать память в случае, когда определение функции ему не доступно? Например находится в другой единице трансляции.

Если не доступно, то никак будет ошибка.
Alex Fox в сообщении #1195973 писал(а):
Компилятор ведь не может видеть одновременно оба .cpp. Он отдельно смотрит main.cpp видит вызов fib(5), и должен как-то узнать на какую величину нужно будет передвинуть указатель стека, чтобы выполнить эту функцию.

Почему не может? Может. Просто динамически подгружает необходимые данные и части. И поэтому компиляторы Си++ очень медленные.
Alex Fox в сообщении #1195982 писал(а):
Как компилятор тогда высчитывает сколько всего нужно памяти выделить под стек? Или размер стека фиксирован и не зависит от компилятора?

В первом приближении размер стека фиксирован. А так есть ключи компиляции для его изменения.
Типично 8,16, 64 кб. 16 кб дос, 64 кб виндоус.
Но мы отвлеклись. Компилятор рассчитывает необходимый размер под стековый кадр(стековый фрейм), а не под весь стек.
https://ru.wikipedia.org/wiki/Стек_вызовов
И да делает это он путём суммирования переменных.
Вам уже говорили что вам надо ознакомиться с ассемблером. Вам подойдёт любой учебник к примеру Ирвин К. Язык ассемблера для процессоров Intel 2005.

Бинарный формат вызова(ABI) - описывает кто как помещает переменные и кто их освобождает и как он суммируется.
Это уже зависит от компилятора, а также есть общепринятые форматы и принятые в отдельных ОС.
Достаточно подробно это описано в книге: Денис Юричев; Reverse Engineering для начинающих. 933 литса 2017(сам.издат)
Учтите что использование реверса в не научных целях может подпадать под законы вашей страны и может быть запрещено. А в некоторых странах и в научных.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 61 ]  На страницу Пред.  1, 2, 3, 4, 5  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group