Перейти к содержанию
    

Получить адресс возврата на cortex

Пилю менеджер кучи от zltigo. Решил добавить пару сервисных функций для отладки. В частности хочу знать, откуда был вызов на выделение памяти. Для этого как-то нужно выдернуть содержимое регистра LR. В асме не силен. Так что все потуги пока не увенчались успехом. Может кто подскажет обертку/функцию для получения LR?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может кто подскажет обертку/функцию для получения LR?

Компилятор-то как зовут?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Примерно вот так:

inline __attribute__((__always_inline__)) uint32_t get_return_address()
{
    unsigned int ret;
    __asm__ __volatile__ ("mov %0, LR" : "=r"(ret) );
    return ret - 4;
}

void __attribute__((__noinline__)) print_calee(void)
{
    volatile uint32_t ret = get_return_address();
    uart << "called from \t"; uart.put_hex(ret);
}

void test1(void)
{
    print_calee();
}

void test2(void)
{
    print_calee();
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пилю менеджер кучи от zltigo.

Вообще-то проще и уж точно удобнее для отладки, передавать уже готовый указатель на владельца, что и сделано через void *owner в функции void *malloc_z( heap_t *heap, size_t size, int type, void *owner );

При этом у меня владельцем обычно является указатель на TCB задачи. Хотя естественно, можно и хоть указатель на имя подставлять, хоть явно адрес вызывающей подпрограммы , а не вытаскивать его постфактум.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Примерно вот так:...

Вот так лучше:

inline __attribute__((__always_inline__)) uint32_t get_return_address()
{
    unsigned int ret;
    __asm__ __volatile__ ("sub   %0, LR, #4" : "=r"(ret) );
    return ret;
}

 

Вообще-то проще и уж точно удобнее для отладки, передавать уже готовый указатель на владельца

 

Если есть такая возможность, то конечно лучше так. Потому что адрес возврата может испортиться по ходу выполнения malloc (потому приходится его извлекать в самом начале), а параметр уж никуда не денется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если компилятор от Keil/ARM, то есть интринсик __return_address().

 

А если gcc, то __builtin_return_address(unsigned in level)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо всем! Компиляторы Keil и CrossWorks (GCC).

По поводу достаточности указателя на TCB задачи - не всегда достаточно. Во-первых у меня некоторое выделение происходит еще вне задач, потом и в задачах бывает по несколько вызовов. Поэтому найти "неправильный" вызов проще по адресу возврата.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По поводу достаточности указателя на TCB задачи - не всегда достаточно.

Вообще-то были предложены и еще другие варианты. Можете вообще хоть указатель на имя файла и номер строки передавать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за помощь. Бага найдена.

 

З.Ы. Мало ли кому пригодиться: lwIP имеет свой heap, который несколько больше указанного в настройках MEM_SIZE. Это надо учитывать выделяя эту память malloc'ом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...