motofan logo
> 

Ловим "родные" сегфолты без gdb

eug
сообщение 9.12.2007, 20:26


Мастер
****

Группа: Пользователи
Сообщений: 174
Регистрация: 7.12.2007
Из: 53 км на юг от града Петра
Пользователь №: 156 234
Модель телефона: -

Рейтинг: 139



Находясь в состоянии ожидания сборки gdb от scl (надеюсь она не станет перманентной) в голову пришли такие мысли (на форуме ничего такого не нашел - если было извиняйте, с а если не было и для кого это не новость, то почему не написали ?)

Итак, нам понадобятся:
- бажный код
Код

#include <stdio.h>

int main()
{
  char *s = 0;
  *s = 'a';
  return 0;
}

- слегка измененный скрипт catchsegv (он есть в кроссере)
- нативный шарик libSegFault.so (тоже есть в кроссере)
- нативный addr2line из binutils (будет нужен скрипту и нам)

собираем нативный addr2line (мне его было лень выдирать поэтому собрал весь binutils - это не долго (с опциями по умолчанию собирается отладочная версия, поздно заметил, а пересобрать пока лень, т.е. я хотел сказать некогда))
исходники должны были остаться после сборки кроссера
(у меня в ~/motofan/compile/ezx-crosstool-0.5/build/arm-linux/gcc-3.3.6-glibc-2.3.2/binutils-2.15)
(в --build указываете ваш хост)
Код

21:12 [eug@binutils-2.15]$ CC=arm-linux-gcc CXX=arm-linux-g++ ./configure --build=i686-pc-linux-gnu --host=arm-linux


собираем бажную прогу (вкл. отладочную инфу)
Код

21:00 [eug@smser]$ arm-linux-g++ -g main.cpp -o segv2


кидаем на флеху catchsegv segv2 шарик addr2line - все это д.б. в одном дире

все остальное будем делать на теле

проверим, что прога падает
Код

# ./segv2
Segmentation fault


проверим, что addr2line пашет и знакомимся с его опциями
Код

# ./addr2line -h


теперь делаем
Код

# ./catchsegv ./segv2
*** Segmentation fault
Register dump:

R0: 00000001   R1: befffdf4   R2: 00000000   R3: 00000061
R4: befffdf4   R5: 4101f000   R6: 000084c4   R7: 00000001
R8: 41186d5c   R9: 00008490   SL: 41184694   FP: befffdc4
IP: befffdc8   SP: befffdb0   LR: 4106fc84   PC: 000084b0

CPSR: 60000010

Trap: 0000000e   Error: ffffffff   OldMask: 80000000
Addr: 00000000

Backtrace:
./segv2(abort+0x140)[0x84b0]
/lib/libc.so.6(__libc_start_main+0xdc)[0x4106fc84]

Memory map:

00008000-00009000 r-xp 00000000 f3:01 46 /mmc/mmca1/segv/segv2
00010000-00011000 rw-p 00000000 f3:01 46 /mmc/mmca1/segv/segv2
00011000-00015000 rwxp 00000000 00:00 0
40000000-40001000 rw-p 00000000 00:00 0
40001000-40004000 r-xp 00000000 f3:01 47 /mmc/mmca1/segv/libSegFault.so
40004000-40009000 ---p 00003000 f3:01 47 /mmc/mmca1/segv/libSegFault.so
40009000-4000c000 rw-p 00000000 f3:01 47 /mmc/mmca1/segv/libSegFault.so
4000c000-4000d000 rw-p 00000000 00:00 0
41000000-41017000 r-xp 00000000 3e:00 858296 /lib/ld-linux.so.2
4101f000-41020000 rw-p 00017000 3e:00 858296 /lib/ld-linux.so.2
41058000-4117a000 r-xp 00000000 3e:00 913532 /lib/libc-2.3.2.so
4117a000-41180000 ---p 00122000 3e:00 913532 /lib/libc-2.3.2.so
41180000-41186000 rw-p 00120000 3e:00 913532 /lib/libc-2.3.2.so
41186000-41189000 rw-p 00000000 00:00 0
411f0000-412b9000 r-xp 00000000 3e:00 26536968 /usr/lib/libstdc++.so.5.0.5
412b9000-412c0000 ---p 000c9000 3e:00 26536968 /usr/lib/libstdc++.so.5.0.5
412c0000-412c8000 rw-p 000c8000 3e:00 26536968 /usr/lib/libstdc++.so.5.0.5
412c8000-412cd000 rw-p 00000000 00:00 0
412d0000-41376000 r-xp 00000000 3e:00 1593840 /lib/libm-2.3.2.so
41376000-41378000 ---p 000a6000 3e:00 1593840 /lib/libm-2.3.2.so
41378000-4137f000 rw-p 000a0000 3e:00 1593840 /lib/libm-2.3.2.so
41388000-41391000 r-xp 00000000 3e:00 1575876 /lib/libgcc_s.so.1
41391000-41398000 ---p 00009000 3e:00 1575876 /lib/libgcc_s.so.1
41398000-41399000 rw-p 00008000 3e:00 1575876 /lib/libgcc_s.so.1
beffe000-bf000000 rwxp fffff000 00:00 0


если кому показалось, что мы получили бессмысленный набор символов - начинайте креститься, ибо вам действительно показалось biggrin.gif

во-первых, видим адрес бажной инструкции
Код
PC: 000084b0

во-вторых, видим, что эта инструкция из нашей проги
Код
00008000-00009000 r-xp 00000000 f3:01 46 /mmc/mmca1/segv/segv2


ну а теперь, то ради чего все это делалось
Код

# ./addr2line -f -e ./segv2 0x84b0
main
/home/eug/MING/cc/smser/main.cpp:6


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

если соберете без ключика -g или пострипаете, то такой красоты естественно не увидите

а теперь, для чего мне gdb (поясню на этом же примере для тех кто не в курсе что мы могли бы сделать для начала, имея его на теле)

вернемся на хост (кстати этот способ и там работает если что (только там уже все есть и красиво распихано))

Код

21:38 [eug@smser]$ g++ -g main.cpp
21:38 [eug@smser]$ ulimit -c unlimited
21:38 [eug@smser]$ ./a.out
Ошибка сегментирования (core dumped)
21:39 [eug@smser]$ gdb ./a.out core
GNU gdb 6.7
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
Using host libthread_db library "/lib/libthread_db.so.1".

warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/libm.so.6...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /usr/lib/libgcc_s.so.1...done.
Loaded symbols for /usr/lib/libgcc_s.so.1
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0  0x08048e3f in main () at main.cpp:6
6         *s = 'a';
(gdb) p/x s
$1 = 0x0
(gdb) i s
#0  0x08048e3f in main () at main.cpp:6



теперь я знаю, что прога грохнулась потому, что s is null
ну а дальше можно и пошагово до этого кода добраться при желании и увидеть какой негодяй с ним так поступил, либо сразу читать сорцы

PS
заряжал тел от розетки, вынул зарядку, получил
Цитата
To help conserve energy, please unplug the charger from the power outlet when not in use

это на самом деле так ? и много я так сохраню ? (а не то тут есть любители оставлять зарядники в сети - узнают, что это бьет по их карману - точно перестанут biggrin.gif )

Для лентяев с анлимом smile.gif - segv.tar.gz (все уже собрано там segv1 - без дебага, segv2 - с дебагом (чтоб получить все что выше использовать надо его) addr2line не стрипал дабы сохранить размер большим)
Для остальных - catchsegv.tar (только скрипт)

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

хм, когда было 13 сообщений рейтинг был 2
сейчас 14 сообщений рейтинг стал 5
мне-то в общем все равно просто интересно
не уловил суть алгоритма (как рейтинг коррелирует с кол-вом сообщений, наверное для понимания сути кол-во исходных данных не достаточно, буду ждать пока придет просветление или подскажите кто-нибудь)

Сообщение отредактировал eug - 9.12.2007, 23:02
Прикрепленный файл catchsegv.tar   ( 10 килобайт ) Кол-во скачиваний: 139
Прикрепленный файл segv.tar.gz   ( 741.64 килобайт ) Кол-во скачиваний: 307
Юзер вышелВ друзьяВизиткаП/Я
К началу страницы
+Ответить

Сообщений в этой теме

Ловим "родные" сегфолты без gdb · Motorola ROKR E6, E6e, E6tv, MING A1200, A1200i, A1200e, A1200r, A1200w, A1600 · Forum
 

Ответ в темуСоздание новой темы
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 2.8.2025, 14:23

Форум живёт: