Находясь в состоянии ожидания сборки 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
если кому показалось, что мы получили бессмысленный набор символов - начинайте креститься, ибо вам действительно показалось
во-первых, видим адрес бажной инструкции
во-вторых, видим, что эта инструкция из нашей проги
ну а теперь, то ради чего все это делалось
# ./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
заряжал тел от розетки, вынул зарядку, получил
это на самом деле так ? и много я так сохраню ? (а не то тут есть любители оставлять зарядники в сети - узнают, что это бьет по их карману - точно перестанут
)
Для лентяев с анлимом
- segv.tar.gz (все уже собрано там segv1 - без дебага, segv2 - с дебагом (чтоб получить все что выше использовать надо его) addr2line не стрипал дабы сохранить размер большим)
Для остальных - catchsegv.tar (только скрипт)
29 просмотров, ни одного коммента
ну хоть напишите, что это чушь и зря я это писал (исправлюсь и больше не буду)
хм, когда было 13 сообщений рейтинг был 2
сейчас 14 сообщений рейтинг стал 5
мне-то в общем все равно просто интересно
не уловил суть алгоритма (как рейтинг коррелирует с кол-вом сообщений, наверное для понимания сути кол-во исходных данных не достаточно, буду ждать пока придет просветление или подскажите кто-нибудь)
Сообщение отредактировал eug - 9.12.2007, 23:02
Итак, нам понадобятся:
- бажный код
Код
#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
если кому показалось, что мы получили бессмысленный набор символов - начинайте креститься, ибо вам действительно показалось

во-первых, видим адрес бажной инструкции
Код
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
это на самом деле так ? и много я так сохраню ? (а не то тут есть любители оставлять зарядники в сети - узнают, что это бьет по их карману - точно перестанут

Для лентяев с анлимом

Для остальных - catchsegv.tar (только скрипт)
29 просмотров, ни одного коммента
ну хоть напишите, что это чушь и зря я это писал (исправлюсь и больше не буду)
хм, когда было 13 сообщений рейтинг был 2
сейчас 14 сообщений рейтинг стал 5
мне-то в общем все равно просто интересно
не уловил суть алгоритма (как рейтинг коррелирует с кол-вом сообщений, наверное для понимания сути кол-во исходных данных не достаточно, буду ждать пока придет просветление или подскажите кто-нибудь)
Сообщение отредактировал eug - 9.12.2007, 23:02