| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Программирование под Unix/Linux > Запретить компиллятору использовать регистр |
| Автор: svlary 13.7.2015, 11:25 |
| Пишу драйвер. При работе драйвера, иногда (очень редко!) выскаивает "Oops!!!". По распечатке стека знаю, в какой функции это происходит. Но дальнешая локализация ошибки затруднена, так как: 1) Функция работает внутри обработки прерывания, поэтому вставить туда отладочную печать не могу. 2) Функция очень большая, но разбивать её на куски не хчется (есть на то причины). Так что найти ошибку просто читая код не получается. Возникла идея - писать в один из общих регистров значения типа 1...N, отмечающие ключевые точки кода. Тогда, по распечатке при "Oops!!!" можно будет опознать участок по значению в этом регистре. Как записать значение в регистр с помощью встроенного ассемблера, я знаю. Но как сделать так, что бы компиллятор этот регистр не тргал ? |
| Автор: xvr 13.7.2015, 16:40 |
| https://gcc.gnu.org/onlinedocs/gcc/Global-Reg-Vars.html#Global-Reg-Vars - оно? И еще опция -ffixed-reg (см https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options ) |
| Автор: svlary 13.7.2015, 20:23 | ||||||
Оно... В самую точку ! Вот только автор этого текста мучается той же самой проблемой:
А кака его выбрать ?!
Вот я тоже долго читал описание этой опции и так ни фига и не понял.... :-( Спасибо за ответ ! |
| Автор: xvr 14.7.2015, 12:31 |
Не использовать библиотечные функции. Если у вас это часть ядреного дравера, то проблем с ними не будет - их там просто нет Или пересобрать библиотеки с опцией -ffixed-reg и вашим регистром. По другому похоже никак |
| Автор: tzirechnoy 14.7.2015, 13:59 | ||
Простите, а чем вас для этого регистр EIP не устраивает? |
| Автор: svlary 14.7.2015, 14:50 |
Тем, что его нет.... Добавлено через 8 минут и 46 секунд Ну да, таких функций как sin() и printf() нет, зато у меня полно всякого добра типа pci_enable_device() ... Вот о них я беспокоюсь. |
| Автор: tzirechnoy 14.7.2015, 18:30 | ||
Очень смешно. А по делу есть что ответить или это всё ужэ неактуально? |
| Автор: xvr 14.7.2015, 20:15 |
Правильно беспокоитесь. Смотрите ABI на PowerPC и выбирайте регистр из callee saved списка. |
| Автор: tzirechnoy 15.7.2015, 10:55 | ||||||
Да какая разница, какая у него мненомника? rip, %pc, NIA...
Использовать его, разумеется, обязательно. Не в смысле -- что-то туда записывать, а в смысле -- прочесть его значение в дампе и выяснить, где конкретно гикнулась программа. Добавлено через 3 минуты и 6 секунд
И кстати, если драйвер под линукс -- то вполне можэт вставлять туда отладочную печать. printk() работает. |
| Автор: xvr 15.7.2015, 11:25 |
http://cache.freescale.com/files/32bit/doc/ref_manual/E500ABIUG.pdf (вас интересует страница 29) Это регистры, которые сохраняет вызываемая процедура. В вашем случае это 'Registers used for local variables' - r14-r31. Подойдет |
| Автор: bsa 15.7.2015, 12:04 |
| Я бы разделил большую функцию на несколько. Можно методом деления пополам. И таким бы образом локализовал бы проблему. |
| Автор: svlary 15.7.2015, 14:11 | ||
тут тоже какая-то дурацкая проблема, с которой я не справился - какие бы ключи я не ставил в Makefile в строке CFLAGS +=... мне так и не удалось получить билистинг, т.е. ассемблерную распечатку с выдачей смещения от начала модуля и исходным текстом в виде комментариев. Пробовал получить её через objdump или gdb, но им нужна для этого отладочная информация. а и этот ключ (-g) передать не удалось. У меня сложилось такоен впечатление, что когда Make начинает просматривать сорцы ядра, он забывает про мой Makefile и работает сам по себе. Этот Makefile писал сам и не совсем уверен в его адекватности... Добавлено через 4 минуты и 37 секунд Разумеется - работает! Вопрос в том, что в обработчике прерываний запрещается использование kmalloc так как выделение виртуальной памяти может занять неопределённое время или даже не завершиться успешно. А я сильно подозреваю, что для организации буфера печати этот вызов используется. Добавлено через 6 минут и 33 секунды За ссылку - большое спасибо ! |
| Автор: tzirechnoy 15.7.2015, 14:26 | ||
По факту, если есть вызовы функцый по телу, и их имена показывает objdump -- то и без билистинга быстро становится понятно, что есть какой оператор. Там всё достаточно линейно в итоге. Но вообще да, разобраться с -g -- в любом случае важная задача. Кстати, вероятно, там потребуются не только CLAGS, но и LDFLAGS. И да, кстати, у меня тожэ не получилось для gcc .map-файл с листингом сделать. Только -- отдельно ассэмблерный листинг с соответствием исходнику, отдельно -- .map-файл. Впрочем, мне и не нужно это особенно было, поскольку gdb более-менее всё показывал по debug info. |
| Автор: tzirechnoy 15.7.2015, 15:12 | ||
Не надо ничего подозревать. Он просто работает. Это его свойство, и Линус довольно много умственных усилий приложыл, чтобы оно таки работало. Да, форматированный вывод -- работать не будет (ну, наверное, не пробовал). Но printk -- вполне. Да, на размер есть какие-то ограничения. Ну, там теперь (после эскапады systemdшников) и безо всяких прерываний есть ограничения на количество. |