The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Источник SIGSEGV"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Источник SIGSEGV"
Сообщение от Solnuh emailИскать по авторуВ закладки on 28-Май-03, 20:27  (MSK)
Есть код который выводит имена функций после выполнения которых был вызван сигнал, аля backtrace в gdb, путем прохода вверх по стэку.
Работает прекрасно, только саму функцию в которой произошёл SIGSEGV выявить не получается, получается только с той которая вызвала функцию неблагополучную.
Нету ни одного адреса указывающего на тело функции... как узнать откуда SIGSEGV свалился? gdb прекрасно всё показывает, но как он это делает не знаю. Хелп.

int BP,faddr;
void sighandler(int sig, siginfo_t *info, void *c)
{
        __asm__ ("
                movl ebp,BP
        ");    
        printf("%x\n<br>",info->si_addr);
        while((void*)*((int*)BP)) {    
                faddr=BP;
                BP+=4;
                if(dladdr((void*)*((int*)BP),&a)) {  
                        printf("%s<br>\n",a.dli_sname);
                }
                BP=*((int*)faddr);
        }
}

  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "Источник SIGSEGV"
Сообщение от qq Искать по авторуВ закладки on 29-Май-03, 02:52  (MSK)
дык gdb использует debug info, засунутое в бинарник компилером, для определения имен ф-ций
а ты используешь ф-цию для получения _экспортированных_ символов
соотв. и видишь ты только те ф-ции, которые экспортированы модулкм...

а почему бы просто не вставить DBGPRINT("entering function X")
где надо?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "Источник SIGSEGV"
Сообщение от Solnuh emailИскать по авторуВ закладки on 29-Май-03, 12:16  (MSK)
>дык gdb использует debug info, засунутое в бинарник компилером, для определения имен
>ф-ций
>а ты используешь ф-цию для получения _экспортированных_ символов
>соотв. и видишь ты только те ф-ции, которые экспортированы модулкм...
>
>а почему бы просто не вставить DBGPRINT("entering function X")
>где надо?

Кажется ты не понял в чём суть и дело воопще :)
Когда вызывается функция то в стэке сохраняются значение esp предыдущей функции и точка куда возвращаться. Дебаг инфа тут в принципе не нужна, нужно только таблицу символов в ELF иметь.
Проблема в том что когда приходит сигнал, я магу найти точку куда функция должна возвратить управление, в стэке неблагополучной функции, и через dladdr() я магу найти имя символа которому пренадлежит этот адрес. А вот адрес тела функции при исполнении которой произошёл сигнал я не знаю и не знаю где его откапать можно.
Расширенный обработчик сигналов:
void sa_sigaction(int, siginfo_t *, void *);
В структуре siginfo_t есть поле:
        void    *si_addr;               /* faulting instruction */
но для SIGSEGV это адрес памяти обращение к которому вызвало ошибку.
В общем ХЕЛП ещё раз :)

  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "Источник SIGSEGV"
Сообщение от qq Искать по авторуВ закладки on 29-Май-03, 20:02  (MSK)
>>дык gdb использует debug info, засунутое в бинарник компилером, для определения имен
>>ф-ций
>>а ты используешь ф-цию для получения _экспортированных_ символов
>>соотв. и видишь ты только те ф-ции, которые экспортированы модулкм...
>>
>>а почему бы просто не вставить DBGPRINT("entering function X")
>>где надо?
>
>Кажется ты не понял в чём суть и дело воопще :)
>Когда вызывается функция то в стэке сохраняются значение esp предыдущей функции и
>точка куда возвращаться. Дебаг инфа тут в принципе не нужна, нужно
>только таблицу символов в ELF иметь.
>Проблема в том что когда приходит сигнал, я магу найти точку куда
>функция должна возвратить управление, в стэке неблагополучной функции, и через dladdr()
>я магу найти имя символа которому пренадлежит этот адрес. А вот
>адрес тела функции при исполнении которой произошёл сигнал я не знаю
>и не знаю где его откапать можно.
>Расширенный обработчик сигналов:
>void sa_sigaction(int, siginfo_t *, void *);
>В структуре siginfo_t есть поле:
>        void    
>*si_addr;          
>    /* faulting instruction */
>но для SIGSEGV это адрес памяти обращение к которому вызвало ошибку.
>В общем ХЕЛП ещё раз :)

хмм.. ну в 90% случаев, прямо перед тем местом куда должно возвратиться управление, будет команда call func,или call [func]
анализируя, можно попытаться что то найти...
хотя это и корявенький метод, но другого что-то не придумывается, похоже состояние процессора на момент сбоя недоступно обычными (известными мне) методами...
ну и ессно что это будет специфично для аппаратной платформы..


  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "Источник SIGSEGV"
Сообщение от vnp emailИскать по авторуВ закладки on 29-Май-03, 21:14  (MSK)
>Есть код который выводит имена функций после выполнения которых был вызван сигнал,
>аля backtrace в gdb, путем прохода вверх по стэку.
>Работает прекрасно, только саму функцию в которой произошёл SIGSEGV выявить не получается,
>получается только с той которая вызвала функцию неблагополучную.
>Нету ни одного адреса указывающего на тело функции... как узнать откуда SIGSEGV
>свалился? gdb прекрасно всё показывает, но как он это делает не
>знаю. Хелп.

gdb делает стойку на ушах. См. i386-linux-tdep.c, например
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gdb/i386-linux-tdep.c?rev=1.27&content-type=text/x-cvsweb-markup&cvsroot=src>

  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "Источник SIGSEGV"
Сообщение от Solnuh emailИскать по авторуВ закладки on 29-Май-03, 23:05  (MSK)
/* When the i386 Linux kernel calls a signal handler and the
   SA_RESTORER flag isn't set, the return address points to a bit of
   code on the stack.  This function returns whether the PC appears to
   be within this bit of code.

   The instruction sequence for normal signals is
       pop    eax
       mov    $0x77,eax
       int    $0x80
   or 0x58 0xb8 0x77 0x00 0x00 0x00 0xcd 0x80.

   Checking for the code sequence should be somewhat reliable, because
   the effect is to call the system call sigreturn.  This is unlikely
   to occur anywhere other than a signal trampoline.

Не понял я канешно как они найдя этот код находят адрес в котором фолт произошёл. Когда делаем return в sighandler после получения SIGSEGV, выполнение взвращается на место фолта и опять происходит SIGSEGV %)
Код который возвращает:
0xbfbfffbd:     mov    $0x158,eax
0xbfbfffc2:     push   eax
0xbfbfffc3:     int    $0x80
Это кажется системный вызов, где поглядеть что за вызов это?:)
PS. Система FreeBSD 4.5

  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "Источник SIGSEGV"
Сообщение от qq Искать по авторуВ закладки on 30-Май-03, 01:00  (MSK)

>0xbfbfffbd:     mov    $0x158,eax
>0xbfbfffc2:     push   eax
>0xbfbfffc3:     int    $0x80
>Это кажется системный вызов, где поглядеть что за вызов это?:)
>PS. Система FreeBSD 4.5  

#define SYS_sigreturn   344

  Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "Источник SIGSEGV"
Сообщение от vnp emailИскать по авторуВ закладки on 30-Май-03, 02:46  (MSK)

>Не понял я канешно как они найдя этот код находят адрес в
>котором фолт произошёл.

Они там дальше описывают, как найти sigcontext; в нем уже есть все
необходимое, в том числе eip (см. /usr/include/asm/sigcontext.h)

  Рекомендовать в FAQ | Cообщить модератору | Наверх

8. "Вдогонку: Источник SIGSEGV"
Сообщение от vnp emailИскать по авторуВ закладки on 30-Май-03, 02:53  (MSK)

>PS. Система FreeBSD 4.5


Тогда вам надо смотреть i386bsd-tdep.c (он рядышком лежит); и bsd
трамплин по-другому устроен.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

9. "Вдогонку: Источник SIGSEGV"
Сообщение от Solnuh emailИскать по авторуВ закладки on 30-Май-03, 10:20  (MSK)
>
>>PS. Система FreeBSD 4.5
>
>Тогда вам надо смотреть i386bsd-tdep.c (он рядышком лежит); и bsd
>трамплин по-другому устроен.

Жалко что по разному :)
Лана, покапаем, но думаю придёца обойтись только предшествующими функциями.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

10. "Источник SIGSEGV"
Сообщение от Solnuh emailИскать по авторуВ закладки on 02-Июн-03, 13:00  (MSK)
Всем спасибо :)
Вот работающий код для FreeBSD 4.5 выуживающий цепочку функций при выполнении которых вызвался сигнал(полезно для отладки без дебагера когда появляется SIGSEGV при работе).

int BP,faddr;

void sighandler(int sig, siginfo_t *info, void *c)
{
        sigcontext *sc;
        Dl_info a;
        int i=1;
        __asm__ (" movl ebp,BP "); //Перед ebp надо вставить знак процента
                                   //каверкается что-то при посте это дело
        sc=(sigcontext*)*((int*)(BP+16));
        BP=*((int*)BP);
        if(dladdr((void*)sc->sc_eip,&a)) {
                printf("%d: %s<br>\n",i,a.dli_sname);
                i++;
        }
        while((void*)*((int*)BP)) {
                faddr=BP;
                BP+=4;
                if(dladdr((void*)*((int*)BP),&a)) {
                        printf("%d: %s<br>\n",i,a.dli_sname);
                        i++;
                }
                BP=*((int*)faddr);
        }
        exit(1);
}

Для линуха сделаю поже если кому нужно.

  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Спонсоры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2023 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру