| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Программирование под Unix/Linux > [kernel] printk и va_start |
| Автор: cupper 23.2.2010, 23:54 | ||||||
Пытаюсь разобраться с тем как работает printk, в целом все понятно за исключением двух моментов:
как работают макросы va_start va_end va_arg
немогу понять как это работает. После вызова макроса va_start(args, fmt); args на что указывает ? на кусок памяти в котором расположены последовательно переменные которые передавались printk в качестве ... или что ? А в fmt ? 2.
как так передается не строка и строка как одно целое ?из анализа кода чета не понял как они распарсиваются (( |
| Автор: MAKCim 24.2.2010, 11:13 |
| cupper, непонятно, что может быть непонятного ;) у вас же все определения есть пошагово посмотрите, что происходит |
| Автор: cupper 24.2.2010, 12:15 |
| ну например непонятно что произойдет если в printk будут переданы параметры одного типа, а изыматься будут с другими типами (форматная строка другая) (положили 4 long сняли 4 char) таким образом в стеке остались часть данных и если не вызвать va_end то что произойдет ? получается можно изменить стек под свои "не хорошие" нужды ? |
| Автор: 586 24.2.2010, 17:29 | ||||
Не "сняли" а "прочли". va_end не влияет на освобождение параметров в стеке. va_end используется совместно с va_start. Если вызвали va_start, то нужно вызвать и va_end.
Может произойти ошибка. А может ничего не произойти. Подобные функции считаются опасными. В этом примере произойдёт Segmentation Fault:
|
| Автор: cupper 24.2.2010, 18:43 | ||
[QUOTE=586,24.2.2010, 17:29]
ну а что будет если не вызвать va_end, тобишь не выровнять стек ? что то неопределенное ? |
| Автор: MAKCim 24.2.2010, 22:47 | ||
| cupper, ну неужели из дефайнов не видно? ;)
ничего не будет |
| Автор: cupper 25.2.2010, 23:49 | ||||
этото видно, получает если каким либо образом в ворфматной строке задать одни параметры и передать другие типы то можно чтто оставить в стеке (в теории), как уже многими было сказано небезопастная конструкция. Но также везде пишется что нужно юзать va_end после va_start (хотя это пишут для пользовательких функий а не ядровых) И если ядровые va_end ничего неделают смысл тогда их в чем ? нахрена их писать ?) |
| Автор: MAKCim 26.2.2010, 09:55 | ||||
va_start/va_end/va_arg в оригинале являются частью стандартной библиотеки С ядро в этом смысле ее эмулирует точно не знаю, но даю процентов 95, что va_end в С также ничего не делает ;)
стек растет в сторону меньших адресов, поэтому если мы передали значения типов больших размеров, то ничего небезопасного тут нет, но это, безусловно, ошибка |
| Автор: cupper 26.2.2010, 13:15 | ||
[QUOTE=MAKCim,26.2.2010, 09:55]
хм, я когда читал про С функции va_start то там было обязательным условием вызов va_end для того чтобы 100% выровнять стек и избежать проблем проблем. |
| Автор: MAKCim 26.2.2010, 13:37 |
| я про то, что в 95% случаев реализация va_X вообще ничего не делает со стеком, поэтому ничего выравнивать не надо ;) но семантика использования va_X _требует_ вызова va_end в конце, поскольку таков интерфейс использования данной функциональности |