![]() |
|
Модераторы: xvr |
![]()
|
|
| cupper |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 525 Регистрация: 29.11.2006 Репутация: нет Всего: 1 |
Пытаюсь разобраться с тем как работает printk, в целом все понятно за исключением двух моментов:
как работают макросы va_start va_end va_arg
немогу понять как это работает. После вызова макроса va_start(args, fmt); args на что указывает ? на кусок памяти в котором расположены последовательно переменные которые передавались printk в качестве ... или что ? А в fmt ? 2.
как так передается не строка и строка как одно целое ?из анализа кода чета не понял как они распарсиваются (( |
||||||
|
|||||||
| 586 |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2243 Регистрация: 8.5.2006 Репутация: нет Всего: 146 |
указывает на ((&fmt)+1) Это конкатенация строк:
То есть, в функцию printk передаётся один аргумент. Это сообщение отредактировал(а) 586 - 24.2.2010, 01:42 |
||||
|
|||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
cupper,
непонятно, что может быть непонятного ;) у вас же все определения есть пошагово посмотрите, что происходит -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| cupper |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 525 Регистрация: 29.11.2006 Репутация: нет Всего: 1 |
ну например непонятно что произойдет если в printk будут переданы параметры одного типа, а изыматься будут с другими типами (форматная строка другая) (положили 4 long сняли 4 char) таким образом в стеке остались часть данных и если не вызвать va_end то что произойдет ? получается можно изменить стек под свои "не хорошие" нужды ?
|
|||
|
||||
| 586 |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2243 Регистрация: 8.5.2006 Репутация: нет Всего: 146 |
Не "сняли" а "прочли". va_end не влияет на освобождение параметров в стеке. va_end используется совместно с va_start. Если вызвали va_start, то нужно вызвать и va_end.
Может произойти ошибка. А может ничего не произойти. Подобные функции считаются опасными. В этом примере произойдёт Segmentation Fault:
|
||||
|
|||||
| cupper |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 525 Регистрация: 29.11.2006 Репутация: нет Всего: 1 |
||||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
cupper,
ну неужели из дефайнов не видно? ;)
ничего не будет -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| cupper |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 525 Регистрация: 29.11.2006 Репутация: нет Всего: 1 |
этото видно, получает если каким либо образом в ворфматной строке задать одни параметры и передать другие типы то можно чтто оставить в стеке (в теории), как уже многими было сказано небезопастная конструкция. Но также везде пишется что нужно юзать va_end после va_start (хотя это пишут для пользовательких функий а не ядровых) И если ядровые va_end ничего неделают смысл тогда их в чем ? нахрена их писать ?) |
||||
|
|||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
va_start/va_end/va_arg в оригинале являются частью стандартной библиотеки С ядро в этом смысле ее эмулирует точно не знаю, но даю процентов 95, что va_end в С также ничего не делает ;) стек растет в сторону меньших адресов, поэтому если мы передали значения типов больших размеров, то ничего небезопасного тут нет, но это, безусловно, ошибка -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| cupper |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 525 Регистрация: 29.11.2006 Репутация: нет Всего: 1 |
[QUOTE=MAKCim,26.2.2010, 09:55]
хм, я когда читал про С функции va_start то там было обязательным условием вызов va_end для того чтобы 100% выровнять стек и избежать проблем проблем. Это сообщение отредактировал(а) cupper - 26.2.2010, 13:16 |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
я про то, что в 95% случаев реализация va_X вообще ничего не делает со стеком, поэтому ничего выравнивать не надо ;)
но семантика использования va_X _требует_ вызова va_end в конце, поскольку таков интерфейс использования данной функциональности -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
![]()
|
| Правила форума "С/С++: Программирование под Unix/Linux" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |