Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [kernel] printk и va_start 
:(
    Опции темы
cupper
Дата 23.2.2010, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Пытаюсь разобраться с тем как работает printk, в целом все понятно за исключением двух моментов:
Код

asmlinkage int printk(const char *fmt, ...) 
{ 
   va_list args; 
   int r; 
 
   va_start(args, fmt); 
   r = vprintk(fmt, args); 
   va_end(args); 
 
   return r; 
} 

как работают макросы va_start va_end va_arg
Код

typedef char *va_list;
#endif                /* _VALIST */

/*
 * Storage alignment properties
 */
#define  _AUPBND                (sizeof (acpi_native_int) - 1)
#define  _ADNBND                (sizeof (acpi_native_int) - 1)

/*
 * Variable argument list macro definitions
 */
#define _bnd(X, bnd)            (((sizeof (X)) + (bnd)) & (~(bnd)))
#define va_arg(ap, T)           (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
#define va_end(ap)              (void) 0
#define va_start(ap, A)         (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))

немогу понять как это работает. 
После вызова макроса 
va_start(args, fmt);
args на что указывает ? на кусок памяти в котором расположены последовательно переменные которые передавались printk в качестве ... или что ? А в fmt ?

2. 
Код

printk(KERN_ERR "bla bla bla\n"); 

как так передается не строка и строка как одно целое ?из анализа кода чета не понял как они распарсиваются ((
PM MAIL   Вверх
586
Дата 24.2.2010, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: нет
Всего: 146



Цитата(cupper @  23.2.2010,  23:54 Найти цитируемый пост)
немогу понять как это работает. 
После вызова макроса 
va_start(args, fmt);
args на что указывает ?

указывает на ((&fmt)+1)

Цитата(cupper @  23.2.2010,  23:54 Найти цитируемый пост)
printk(KERN_ERR "bla bla bla\n"); 

Это конкатенация строк:
Код
const char *s = "blablabla" "blablabla" "blablabla";

То есть, в функцию printk передаётся один аргумент.

Это сообщение отредактировал(а) 586 - 24.2.2010, 01:42
PM   Вверх
MAKCim
Дата 24.2.2010, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



cupper, 
непонятно, что может быть непонятного ;)
у вас же все определения есть
пошагово посмотрите, что происходит


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
cupper
Дата 24.2.2010, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



ну например непонятно что произойдет если в printk будут переданы параметры одного типа, а изыматься будут с другими типами (форматная строка другая)  (положили 4 long сняли 4 char) таким образом в стеке остались часть данных и если не вызвать va_end то что произойдет ? получается можно изменить стек под свои "не хорошие" нужды ?
PM MAIL   Вверх
586
Дата 24.2.2010, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: нет
Всего: 146



Цитата(cupper @  24.2.2010,  12:15 Найти цитируемый пост)
положили 4 long сняли 4 char

Не "сняли" а "прочли".
va_end не влияет на освобождение параметров в стеке. 
va_end используется совместно с va_start. Если вызвали va_start, то нужно вызвать и va_end.
Цитата
ну например непонятно что произойдет если в printk будут переданы параметры одного типа, а изыматься будут с другими типами

Может произойти ошибка. А может ничего не произойти. Подобные функции считаются опасными.
В этом примере произойдёт Segmentation Fault:
Код
printk("%s", 2);

PM   Вверх
cupper
Дата 24.2.2010, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



[QUOTE=586,24.2.2010,  17:29]
Цитата(cupper @  24.2.2010,  12:15 Найти цитируемый пост)

va_end используется совместно с va_start. Если вызвали va_start, то нужно вызвать и va_end.

ну а что будет если не вызвать va_end, тобишь не выровнять стек ? что то неопределенное ? 
PM MAIL   Вверх
MAKCim
Дата 24.2.2010, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



cupper, 
ну неужели из дефайнов не видно? ;)
Цитата

(void) 0

ничего не будет


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
cupper
Дата 25.2.2010, 23:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Цитата(MAKCim @ 24.2.2010,  22:47)
cupper, 
ну неужели из дефайнов не видно? ;)
Цитата

(void) 0

ничего не будет

этото видно, получает если каким либо образом в ворфматной строке задать одни параметры и передать другие типы то можно чтто оставить в стеке (в теории), как уже многими было сказано небезопастная конструкция. Но также везде пишется что нужно юзать va_end после va_start (хотя это пишут для пользовательких функий а не ядровых) И если ядровые va_end ничего неделают смысл тогда их в чем ? нахрена их писать ?)
PM MAIL   Вверх
MAKCim
Дата 26.2.2010, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



Цитата(cupper @  25.2.2010,  23:49 Найти цитируемый пост)
И если ядровые va_end ничего неделают смысл тогда их в чем ? нахрена их писать ?) 

va_start/va_end/va_arg в оригинале являются частью стандартной библиотеки С
ядро в этом смысле ее эмулирует
точно не знаю, но даю процентов 95, что va_end в С также ничего не делает ;)


Цитата(cupper @  25.2.2010,  23:49 Найти цитируемый пост)
этото видно, получает если каким либо образом в ворфматной строке задать одни параметры и передать другие типы то можно чтто оставить в стеке (в теории), как уже многими было сказано небезопастная конструкция

стек растет в сторону меньших адресов, поэтому если мы передали значения типов больших размеров, то ничего небезопасного тут нет, но это, безусловно, ошибка


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
cupper
Дата 26.2.2010, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



[QUOTE=MAKCim,26.2.2010,  09:55]
Цитата(cupper @  25.2.2010,  23:49 Найти цитируемый пост)

точно не знаю, но даю процентов 95, что va_end в С также ничего не делает ;)

хм, я когда читал про С функции va_start  то там было обязательным условием вызов va_end для того чтобы 100% выровнять стек и избежать проблем проблем.

Это сообщение отредактировал(а) cupper - 26.2.2010, 13:16
PM MAIL   Вверх
MAKCim
Дата 26.2.2010, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



я про то, что в 95% случаев реализация va_X вообще ничего не делает со стеком, поэтому ничего выравнивать не надо ;)
но семантика использования va_X _требует_ вызова va_end в конце, поскольку таков интерфейс использования данной функциональности


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0573 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.