реклама на сайте
подробности

 
 
5 страниц V  < 1 2 3 4 > »   
Reply to this topicStart new topic
> Hard Fault Exception на кортексе м3, как узнать откуда прилезло
jcxz
сообщение Feb 27 2014, 06:09
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(AHTOXA @ Feb 27 2014, 11:21) *
Потому что обычно там находится адрес возврата И обычно компилятор использует LR именно для этих целей.

Адрес возврата в LR внутри функции хранится только если в функции нет вложенных вызовов других функций. Подумайте почему.
Цитата(AHTOXA @ Feb 27 2014, 11:21) *
С этого места в LR как раз адрес возврата. Так работает инструкция BL.

Как работает инструкция BL я прекрасно знаю. Но не она возвращает управление из функции some_func. Управление возвращается обычно или BX LR или чем-то вроде POP {...,PC}
(если в той функции было сохранение LR на стеке (были вложенные вызовы других функций)).
Во втором случае в LR будет не то что вы ожидаете.
Цитата(AHTOXA @ Feb 27 2014, 11:21) *
Не встречал такого. Компилятор знает, что там находится адрес возврата (он сам его туда положил). Поэтому обычно старается его не трогать. Если вы встречали такое, то приведите пример.

То что вы этого не встречали, говорит о том, что вы никогда не заглядывали в листинги компилятора.
После того как LR был сохранён на стеке, содержимое LR больше не нужно и при необходимости может использоваться для временных переменных компилятором.
Если угодно, вот пример из моего проекта (IAR6.50):
CODE
static void KeyboardScan()
{
_Z12KeyboardScanv:
0xE92D 0x41F0 PUSH {R4-R8,LR}
static u8 m[ncell(kbdKeyPins)] = {0, 0 Depend3Keys(, 0)};
static u16 tLight;
int c = 0, c1, n = ncell(kbdKeyPins) - 1;
0x.... 0x.... LDR.W R2,??DataTable28_5
0x.... 0x.... ADR.W R4,kbdKeyPins+0x4
0x.... 0x.... LDR.W R6,??DataTable28_1
0x.... 0x.... LDR.W R7,??DataTable28_4
0x2000 MOVS R0,#+0
0x2102 MOVS R1,#+2
0xF202 0x0306 ADDW R3,R2,#+6
0xF44F 0x5500 MOV R5,#+8192
do {
if (Pdat2(kbdKeyPins[n].port, kbdKeyPins[n].pin)) {
??KeyboardScan_0:
0xF894 0xE000 LDRB LR,[R4, #+0]
0xF893 0xC000 LDRB R12,[R3, #+0]
0xEB07 0x1E4E ADD LR,R7,LR, LSL #+5
0xF8DE 0xE014 LDR LR,[LR, #+20]
0xF894 0x8001 LDRB R8,[R4, #+1]
0xFA2E 0xFE08 LSR LR,LR,R8
0xEA5F 0x7ECE LSLS LR,LR,#+31
0xD50D BPL.N ??KeyboardScan_1


Цитата(ViKo @ Feb 27 2014, 11:51) *
При прерываниях адрес возврата сохраняется в стек (там его можно и найти, положение известно). А в LR заносится специальное слово EXC_RETURN (там почти одни единицы).

Разговор не о LR в CPU, а о LR из фрейма, сохранённом на стеке при стекинге перед входом в ISR.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 27 2014, 06:56
Сообщение #17


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(jcxz @ Feb 27 2014, 08:09) *
Адрес возврата в LR внутри функции хранится только если в функции нет вложенных вызовов других функций. Подумайте почему.
Почему? PUSH LR уже изменяет содержимое LR?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 27 2014, 07:48
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Функции как вызываются? Правильно: обычно через BL.
BL что делает с LR?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 27 2014, 08:46
Сообщение #19


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(jcxz @ Feb 27 2014, 12:09) *
Адрес возврата в LR внутри функции хранится только если в функции нет вложенных вызовов других функций. Подумайте почему.

Я бы сформулировал это по другому: "Бывают случаи, когда LR не содержит адрес возврата. Но чаще всего - содержат".
Цитата(jcxz @ Feb 27 2014, 12:09) *
Как работает инструкция BL я прекрасно знаю.

Ой ли. Я отвечал на вот эту конкретную вашу фразу:
Цитата(jcxz @ Feb 27 2014, 08:20) *
BL some_func
С этого места в LR - может быть, что угодно

Судя по ней, вы не знаете как работает BL.
Цитата(jcxz @ Feb 27 2014, 12:09) *
Если угодно, вот пример из моего проекта (IAR6.50):

Ну вот и посмотрите на свой пример. Более половины времени выполнения функции в LR находится адрес возвратаsm.gif

И ещё одно соображение. Если HardFault вызван переходом по несуществующему адресу (а это как раз случай, о котором спрашивал juvf), то LR содержит адрес возврата гарантированно, поскольку по несуществующему адресу нет кода, который может "сохранить на стек LR и использовать его для каких-то других целей".


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 27 2014, 09:11
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(AHTOXA @ Feb 27 2014, 14:46) *
Судя по ней, вы не знаете как работает BL.

Из чего вы сделали такой вывод? Что же там по вашему в LR???

Цитата(AHTOXA @ Feb 27 2014, 14:46) *
Ну вот и посмотрите на свой пример. Более половины времени выполнения функции в LR находится адрес возвратаsm.gif

Каким образом интересно вы вычислили время выполнения и размер функции???
И причём это тут вообще?

Цитата(AHTOXA @ Feb 27 2014, 14:46) *
И ещё одно соображение. Если HardFault вызван переходом по несуществующему адресу (а это как раз случай, о котором спрашивал juvf), то LR содержит адрес возврата гарантированно, поскольку по несуществующему адресу нет кода, который может "сохранить на стек LR и использовать его для каких-то других целей".

И что? С чего вы решили что до перехода там содержался адрес возврата???

PS: Блин - вместо того чтобы тут нести чушь, почитайте лучше описание системы команд!
Большего количества чуши в одном сообщении трудно найти....
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 27 2014, 09:51
Сообщение #21


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(jcxz @ Feb 27 2014, 09:48) *
BL что делает с LR?
Уже даже боюсь спросить, что же BL делает с LR? Всегда думал, что записывает в него... (ужас!) адрес возврата.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 27 2014, 10:54
Сообщение #22


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(jcxz @ Feb 27 2014, 15:11) *
И что? С чего вы решили что до перехода там содержался адрес возврата???

Потому что так в кортексах происходит вызов функций - командой BL.
Эта команда заносит в LR адрес следующей инструкции (адрес возврата). И затем заносит в PC новый адрес.
Если этот новый адрес не существует, то происходит HardFault. И если в обработчике HardFault-а достать из стека сохранённый в момент возникновения исключения LR, то он будет содержать адрес возврата.
Вашу следующую реплику я возвращаю вам:
Цитата(jcxz @ Feb 27 2014, 15:11) *
PS: Блин - вместо того чтобы тут нести чушь, почитайте лучше описание системы команд!
Большего количества чуши в одном сообщении трудно найти....



--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 27 2014, 11:42
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Сергей Борщ @ Feb 27 2014, 15:51) *
Уже даже боюсь спросить, что же BL делает с LR? Всегда думал, что записывает в него... (ужас!) адрес возврата.

Теперь ещё немного дальше подумайте - что будет если внутри 1-й функции будет вызов 2-й функции? А если ещё дальше - в функции2 вызов функции3?
Что будет в LR после всего этого?
Go to the top of the page
 
+Quote Post
juvf
сообщение Feb 27 2014, 11:48
Сообщение #24


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Думаю, что я нашел граблю. я в одном потоке делаю if(--(*(MyClass*)p) ), а в дркгом потоке

....
delete p;
p = new MyClass(...);
...

иногда, оператор -- выполняется между delete и new.

Всем спасибо за помощь!
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 27 2014, 11:51
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(AHTOXA @ Feb 27 2014, 16:54) *
Потому что так в кортексах происходит вызов функций - командой BL.

Причём тут "вызов функций"??
Вы пишете переходом по несуществующему адресу.
Неужто такие переходы могут быть только по команде BL?
Может тогда просто - удалить её нафик из системы команд и не будет проблем? wink.gif
А как же всякие BX Rx, POP {PC}, LDR PC, ... и пр.? Вы такие команды знаете?
И что происходит при нехватке стека? Уж-ли не из-за POP {PC} за пределами стека может вызвать
переход по несуществующему адресу?
И как интересно команда BL addr может вызвать переход по несуществующему адресу,
если адрес перехода находится в теле самой команды, которая скорее всего находится во FLASH и этот адрес формирует линкёр???
Go to the top of the page
 
+Quote Post
juvf
сообщение Feb 27 2014, 12:05
Сообщение #26


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(jcxz @ Feb 27 2014, 16:51) *
если адрес перехода находится в теле самой команды, которая скорее всего находится во FLASH и этот адрес формирует линкёр???

эээ..... может я инфы мало дал.... сори...

ну адрес оператора MyClass::operator--() находится в озу. точнее не сам оператор, а только его адрес. сам оператор конечно же во флешь. но дело в том, что объект класса MyClass создан динамически в куче. И соответственно в озу лежит таблица с указателями на методы этого класса.
Если объект удален, и сделать по пустому указателю вызов метода, как раз процессор полезит в озу, чтобы получить адресс нужного метода, а потом по этому адресу сделает переход. и далее куда там попало..... там может до HF выполниться ещё несколько команд.

Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 27 2014, 12:50
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(juvf @ Feb 27 2014, 18:05) *
ну адрес оператора MyClass::operator--() находится в озу. точнее не сам оператор, а только его адрес. сам оператор конечно же во флешь. но дело в том, что объект класса MyClass создан динамически в куче. И соответственно в озу лежит таблица с указателями на методы этого класса.

Не факт. Это очень неэффективно - тратить кучу ОЗУ, сохраняя таблицу указателей на методы для каждого объекта в ОЗУ.
Если у вас имеется класс с перегруженными функциями, то для каждого такого класса компилятор скорей всего создаёт таблицу член-функций и сохраняет её во флеш.
А в самом объекте класса хранит только адрес такой таблицы.
Хотя тут конечно от компилятора зависит, но в embedded-области ОЗУ - очень ценный ресурс.
Go to the top of the page
 
+Quote Post
juvf
сообщение Feb 27 2014, 13:03
Сообщение #28


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(jcxz @ Feb 27 2014, 17:50) *
Если у вас имеется класс с перегруженными функциями, то для каждого такого класса компилятор скорей всего создаёт таблицу член-функций и сохраняет её во флеш.
А в самом объекте класса хранит только адрес такой таблицы.
Хотя тут конечно от компилятора зависит, но в embedded-области ОЗУ - очень ценный ресурс.

Да, всё верно. В озу храниться только указатель на таблицу указателей. Но тем не менее, после delete .... обращение по указателю... можно получить неправильный указатель из озу на таблицу указателей во флешь, ну и неправильный переход. В том числе PC может перескочить на озу и выполится какая нибудь команда из озу.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 27 2014, 15:00
Сообщение #29


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(juvf @ Feb 27 2014, 17:48) *
Думаю, что я нашел граблю.

Аминь! sm.gif

Цитата(jcxz @ Feb 27 2014, 17:51) *
Причём тут "вызов функций"??

При том, что мы с вами вели речь про оператор BL. Помните, я вам объяснял, как он работает? Так вот. Оператор BL - это вызов функции. Поэтому я и пишу про вызов функции.
Напомню также, что у juvf речь шла о вызове перегруженного оператора. А это - тоже вызов функции.

Цитата(jcxz @ Feb 27 2014, 17:51) *
Вы пишете переходом по несуществующему адресу.
Неужто такие переходы могут быть только по команде BL?

Переходы, вызванные вызовом функции - да.
Цитата(jcxz @ Feb 27 2014, 17:51) *
Может тогда просто - удалить её нафик из системы команд и не будет проблем? wink.gif
А как же всякие BX Rx, POP {PC}, LDR PC, ... и пр.? Вы такие команды знаете?

Я знаю много разных команд. А ещё я знаю стихи Маяковского. Но ни то ни другое не связано с предметом обсуждения.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 28 2014, 02:32
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(AHTOXA @ Feb 27 2014, 21:00) *
При том, что мы с вами вели речь про оператор BL. Помните, я вам объяснял, как он работает? Так вот. Оператор BL - это вызов функции. Поэтому я и пишу про вызов функции.
Напомню также, что у juvf речь шла о вызове перегруженного оператора. А это - тоже вызов функции.

Вот только не надо передёргивать! Тут есть история и всегда можно посмотреть о чём и когда шла речь.
Во-первых - вызов перегруженного члена класса не может осуществляться BL, а только командами BLX; BX; LDR PC, ...; (возможно ещё TBB/TBH) - почитайте
последние сообщения тут, чтобы понять почему.
Во-вторых - речь тут не шла о вызове функции. Это вы не понятно почему решили, что уход исполнения по неверному адресу почему-то должен осуществляться именно по BL.
А я вам напомнил о других командах передачи управления (причём - с косвенной адресацией). И непонятно почему вы решили, что значение в LR как-то связано с местом
возникновения fault-а, хотя там просто может быть адрес возврата из последней когда-то вызванной функции (никак не связанный с местом текущего выполнения и fault-a)
или вообще случайные данные (если после последнего BL/BLX регистр LR использовался как РОН).
И ещё раз повторю если вы не поняли - по BL в принципе не может быть передачи управления по случайному адресу (если конечно нет ошибок компоновки и код
не компонуется для работы в ОЗУ) так как адрес перехода (смещение) находится в коде команды (во флеш).

Цитата(AHTOXA @ Feb 27 2014, 21:00) *
Я знаю много разных команд. А ещё я знаю стихи Маяковского. Но ни то ни другое не связано с предметом обсуждения.

Предмет обсуждения был - HardFault из-за выполнения данных как кода. И размышлений как туда попали. А попасть туда могли по любой команде
передачи управления с косвенной адресацией, например одной из приведённых мной. А не только по BLX как вы почему-то решили.
Например - любой случай разрушения стека (из-за его переполнения, или выхода указателя за пределы массива на стеке и т.п.) мог привести к выборке
неверного адреса и перехода по нему по команде POP {PC}. При этом LR может продолжать указывать на какой-то адрес возврата из когда вызванной функции
непонятно где в месте никак не относящемся к адресу fault-а.
Go to the top of the page
 
+Quote Post

5 страниц V  < 1 2 3 4 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 10th July 2025 - 08:08
Рейтинг@Mail.ru


Страница сгенерированна за 0.01525 секунд с 7
ELECTRONIX ©2004-2016