在此篇中,其目的是於corss platform中讓gdb找到正確的shared library path。
於native host環境中,執行程式時有時會有
error while loading shared libraries: ????????.so.?: cannot open
shared object file: No such file or directory
其可能的問題為不能找到需要的shared library,For examples...
$ pwd
/ImageMagick-6.5.7-10/utilities/.libs
$
$ ls
animate composite convert identify mogrify stream
compare conjure display import montage
$
$ echo $LD_LIBRARY_PATH
$
$ ldd convert
linux-gate.so.1 => (0xb7f23000)
libMagickCore.so.2 => not found
libMagickWand.so.2 => not found
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7efa000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7ef6000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7ed0000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7d6d000)
/lib/ld-linux.so.2 (0xb7f24000)
$
$ ./convert
./convert: error while loading shared libraries: libMagickCore.so.2:
cannot open shared object file: No such file or directory
$
以上之中,由ldd command觀察convert所需要額外的library中,
沒找到libMagickCore.so.2,libMagickWand.so.2此兩的shared linary的所在位址,
所以會有"not found"的訊息出現。
若是以LD_LIBRARY_PATH來註冊額外shared library的路徑,即可解決...
$ export LD_LIBRARY_PATH=/ImageMagick-6.5.7-10/magick/.libs:/ImageMagick-6.5.7-10/wand/.libs
$
$ echo $LD_LIBRARY_PATH
/ImageMagick-6.5.7-10/magick/.libs:/ImageMagick-6.5.7-10/wand/.libs
$
$ ldd convert
linux-gate.so.1 => (0xb7ee9000)
libMagickCore.so.2 => /ImageMagick-6.5.7-10/magick/.libs/libMagickCore.so.2 (0xb7d66000)
libMagickWand.so.2 => /ImageMagick-6.5.7-10/wand/.libs/libMagickWand.so.2 (0xb7c70000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7c49000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7c45000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7c1f000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7abc000)
/lib/ld-linux.so.2 (0xb7eea000)
$
Showing posts with label GCC. Show all posts
Showing posts with label GCC. Show all posts
Friday, December 27, 2013
Linux GDB breakpoint at _start
寫一個Linux上user mode最簡單的AP
$ cat foo.s
.text
.globl _start
_start:
movl $0,%ebx /* exit code */
movl $1,%eax /* exit function */
int $0x80
這樣就可以正常的執行並結束。
但怪的事...
$ as foo.s -o foo.o
$ ld foo.o -o foo
這樣邊一之後再用GDB來debug...
(gdb) break _start
Breakpoint 1 at 0x8048054
(gdb) run
Starting program: /home/lungswu/Working/application/hello/foo
(no debugging symbols found)
Program exited normally.
(gdb)
程式竟然直接結速,並不能breaking在_start上????
類似的編譯方式也會發生同樣問題
$ gcc -nostartfiles --static foo.s -o foo
$ gcc -nostartfiles -nostdlib foo.s -o foo
但是以下的方式就OK
$ gcc -nostartfiles foo.s -o foo
原因不明,但至少可以確定的事...
(1)可以用GDB停在_start上是一個動態連結檔
$ ldd foo
linux-gate.so.1 => (0xb80d2000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7f60000)
/lib/ld-linux.so.2 (0xb80d3000)
(2)觀察他的各區段,明顯複雜很多
$ objdump -h foo
foo: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 00000013 080480f4 080480f4 000000f4 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .hash 0000000c 08048108 08048108 00000108 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .gnu.hash 00000018 08048114 08048114 00000114 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .dynsym 00000000 0804812c 0804812c 0000012c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .dynstr 0000000b 0804812c 0804812c 0000012c 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .text 0000000c 08048138 08048138 00000138 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
6 .dynamic 00000070 08049f84 08049f84 00000f84 2**2
CONTENTS, ALLOC, LOAD, DATA
7 .got.plt 0000000c 08049ff4 08049ff4 00000ff4 2**2
CONTENTS, ALLOC, LOAD, DATA
$ cat foo.s
.text
.globl _start
_start:
movl $0,%ebx /* exit code */
movl $1,%eax /* exit function */
int $0x80
這樣就可以正常的執行並結束。
但怪的事...
$ as foo.s -o foo.o
$ ld foo.o -o foo
這樣邊一之後再用GDB來debug...
(gdb) break _start
Breakpoint 1 at 0x8048054
(gdb) run
Starting program: /home/lungswu/Working/application/hello/foo
(no debugging symbols found)
Program exited normally.
(gdb)
程式竟然直接結速,並不能breaking在_start上????
類似的編譯方式也會發生同樣問題
$ gcc -nostartfiles --static foo.s -o foo
$ gcc -nostartfiles -nostdlib foo.s -o foo
但是以下的方式就OK
$ gcc -nostartfiles foo.s -o foo
原因不明,但至少可以確定的事...
(1)可以用GDB停在_start上是一個動態連結檔
$ ldd foo
linux-gate.so.1 => (0xb80d2000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7f60000)
/lib/ld-linux.so.2 (0xb80d3000)
(2)觀察他的各區段,明顯複雜很多
$ objdump -h foo
foo: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 00000013 080480f4 080480f4 000000f4 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .hash 0000000c 08048108 08048108 00000108 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .gnu.hash 00000018 08048114 08048114 00000114 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .dynsym 00000000 0804812c 0804812c 0000012c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .dynstr 0000000b 0804812c 0804812c 0000012c 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .text 0000000c 08048138 08048138 00000138 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
6 .dynamic 00000070 08049f84 08049f84 00000f84 2**2
CONTENTS, ALLOC, LOAD, DATA
7 .got.plt 0000000c 08049ff4 08049ff4 00000ff4 2**2
CONTENTS, ALLOC, LOAD, DATA
Thursday, December 26, 2013
GDB中shared library問題
有時使用GDB做debug,會發生以下的warnning...
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
這意思是gdb做shared library的loading不正確,可以用以下的gdb command看看shared library的結果...
以下表示沒有任何shared library被load進gdb debugger中
(gdb) info shared
No shared libraries loaded at this time.
(gdb)
假設TARGET是ARM,rootfs於/home/nfs/arm
以下表示shared library symbol被load進gdb debugger,但不正確(因為gdb load host中的library)
(gdb) info shared
From To Syms Read Shared Object Library
0x50002080 0x5001a650 Yes /lib/ld-linux.so.2
0x500325b0 0x5003d118 Yes /usr/lib/libmad.so.0
0x5005d598 0x50064f58 Yes /usr/lib/libid3tag.so.0
0x5006d754 0x500782ec Yes /usr/lib/libz.so.1
0x5009a328 0x50138eec Yes /lib/libm.so.6
0x501b2ac8 0x502af008 Yes /lib/libc.so.6
(gdb)
GDB中的一個command....
set solib-search-path PATH
可以指定GDB尋找正確的shared library....
(gdb) set solib-search-path /home/nfs/arm/lib:/home/nfs/arm/usr/lib
(gdb) info shared
From To Syms Read Shared Object Library
0x50002080 0x5001a650 Yes /home/nfs/arm/lib/ld-linux.so.2
0x500325b0 0x5003d118 Yes /home/nfs/arm/usr/lib/libmad.so.0
0x5005d598 0x50064f58 Yes /home/nfs/arm/usr/lib/libid3tag.so.0
0x5006d754 0x500782ec Yes /home/nfs/arm/usr/lib/libz.so.1
0x5009a328 0x50138eec Yes /home/nfs/arm/lib/libm.so.6
0x501b2ac8 0x502af008 Yes /home/nfs/arm/lib/libc.so.6
(gdb)
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
這意思是gdb做shared library的loading不正確,可以用以下的gdb command看看shared library的結果...
以下表示沒有任何shared library被load進gdb debugger中
(gdb) info shared
No shared libraries loaded at this time.
(gdb)
假設TARGET是ARM,rootfs於/home/nfs/arm
以下表示shared library symbol被load進gdb debugger,但不正確(因為gdb load host中的library)
(gdb) info shared
From To Syms Read Shared Object Library
0x50002080 0x5001a650 Yes /lib/ld-linux.so.2
0x500325b0 0x5003d118 Yes /usr/lib/libmad.so.0
0x5005d598 0x50064f58 Yes /usr/lib/libid3tag.so.0
0x5006d754 0x500782ec Yes /usr/lib/libz.so.1
0x5009a328 0x50138eec Yes /lib/libm.so.6
0x501b2ac8 0x502af008 Yes /lib/libc.so.6
(gdb)
GDB中的一個command....
set solib-search-path PATH
可以指定GDB尋找正確的shared library....
(gdb) set solib-search-path /home/nfs/arm/lib:/home/nfs/arm/usr/lib
(gdb) info shared
From To Syms Read Shared Object Library
0x50002080 0x5001a650 Yes /home/nfs/arm/lib/ld-linux.so.2
0x500325b0 0x5003d118 Yes /home/nfs/arm/usr/lib/libmad.so.0
0x5005d598 0x50064f58 Yes /home/nfs/arm/usr/lib/libid3tag.so.0
0x5006d754 0x500782ec Yes /home/nfs/arm/usr/lib/libz.so.1
0x5009a328 0x50138eec Yes /home/nfs/arm/lib/libm.so.6
0x501b2ac8 0x502af008 Yes /home/nfs/arm/lib/libc.so.6
(gdb)
Wednesday, December 25, 2013
GDB Server 使用方式
假設於ARM platform中要debug madplay程式
TARGET(192.168.1.10):
gdbserver HOST:PORT AP_NAME AP_PARAMETER
gdberver 192.168.1.11:1234 /usr/bin/madplay /tmp/aa.mp3
HOST(192.168.1.11):
ddd --debugger arm-linux-gdb /nfs/armroot/usr/bin/madplay
(gdb) target remote 192.168.1.10:1234
(gdb) break main
Breakpoint 1 at 0x12958: file madplay.c, line 742.
(gdb) c
Breakpoint 1, main (argc=2, argv=0xef9f4d84) at madplay.c:742
(gdb)
TARGET(192.168.1.10):
gdbserver HOST:PORT AP_NAME AP_PARAMETER
gdberver 192.168.1.11:1234 /usr/bin/madplay /tmp/aa.mp3
HOST(192.168.1.11):
ddd --debugger arm-linux-gdb /nfs/armroot/usr/bin/madplay
(gdb) target remote 192.168.1.10:1234
(gdb) break main
Breakpoint 1 at 0x12958: file madplay.c, line 742.
(gdb) c
Breakpoint 1, main (argc=2, argv=0xef9f4d84) at madplay.c:742
(gdb)
GDB常用命令
help all:列出所有命令
file
- load
- run [argument]
- show arch:show出現有CPU architecture
- info target
- info break:列出breakpoint
- enable NUM:將breakpoint NUM enable
- disable NUM:將breakpoint NUM disable
- delete NUM:將breakpoint NUM delete掉
- break FILE:NUM:於FILE中第NUM行設一中斷點
- break *ADDRESS:於ADDRESS中設中斷點
- break FUNC:於FUNCTION設中斷點
- watch VAR:當VAR的值被改變時,停在VAR被改變點
- rwatch VAR:當VAR的值被讀取時,停在VAR被讀取點
- next:next statement,over function call
- nexti:下一個instruction,不進入function
- step:next statement,go into function call
- stepi:下一個instruction,進入function
- continue:continue run
- bt:backtrace
- kill
- list:list source code
- info reg:list registers value
- set $reg value:設定register的值
- monitor:送出命令供gdbserver執行
Monday, December 23, 2013
Strong/Weak function
GCC中有一個很好用的feature... strong/weak link
__attribute__((weak))
於C code中,可以先define一個function,其function型態為weak,如此可以library方式release出去。
若第三方要修改此function,他方可以重複定義此function,於連結時第三方function取代原有default的function。
example...
/Working # cat CodeBase.c
#include
void __attribute__((weak)) f()
{
printf("This is the original function\n");
}
int main(void)
{
f();
return 0;
}
/Working # gcc CodeBase.c -o CodeBase
/Working # ./CodeBase
This is the original function
/Working # cat CodeOverride.c
#include
void f(void)
{
printf("This is override function\n");
}
/Working # gcc -c CodeBase.c CodeOverride.c
/Working # nm *.o
CodeBase.o:
00000000 W f
0000001c T main
U puts
CodeOverride.o:
00000000 T f
U puts
/Working # gcc -o CodeBase CodeBase.o CodeOverride.o
/Working # ./CodeBase
This is override function
/Working #
__attribute__((weak))
於C code中,可以先define一個function,其function型態為weak,如此可以library方式release出去。
若第三方要修改此function,他方可以重複定義此function,於連結時第三方function取代原有default的function。
example...
/Working # cat CodeBase.c
#include
void __attribute__((weak)) f()
{
printf("This is the original function\n");
}
int main(void)
{
f();
return 0;
}
/Working # gcc CodeBase.c -o CodeBase
/Working # ./CodeBase
This is the original function
/Working # cat CodeOverride.c
#include
void f(void)
{
printf("This is override function\n");
}
/Working # gcc -c CodeBase.c CodeOverride.c
/Working # nm *.o
CodeBase.o:
00000000 W f
0000001c T main
U puts
CodeOverride.o:
00000000 T f
U puts
/Working # gcc -o CodeBase CodeBase.o CodeOverride.o
/Working # ./CodeBase
This is override function
/Working #
Monday, August 31, 2009
gcc使用參數
gcc help一般用法(一)
Lung.S.Wu@debian:~/tmp$ gcc --help
Usage: gcc [options] file...
gcc help一般用法(二)
Lung.S.Wu@debian:~/tmp$ man gcc
基本參數解釋
-E:只做將標頭檔及MACRO展開,不編譯、編譯、連結
-S:只做組譯,不做編譯、連結
-c:只做組譯、編譯,不做連結
-o filename:指定輸出檔名
-ansi:編譯依據ansi c標準
-Dmacro:定義巨集macro
-Dmarco=defn:定義巨集macro為defn
-Wa,<options>:將選項(option)傳給組譯器
-Wp,<options>:將選項(option)傳給preprocessor
-Wl,<options>:將選項(option)傳給連結器
-I:增加標頭檔的標準路徑
-L:增加library的標準路徑
-l:指定連結的函式庫(如-lpthread)
-Wall:顯示所有的警告訊息
-g:編入除錯資訊
-Os,-O,-O2,-O3:做最佳化
Lung.S.Wu@debian:~/tmp$ gcc --help
Usage: gcc [options] file...
gcc help一般用法(二)
Lung.S.Wu@debian:~/tmp$ man gcc
基本參數解釋
-E:只做將標頭檔及MACRO展開,不編譯、編譯、連結
-S:只做組譯,不做編譯、連結
-c:只做組譯、編譯,不做連結
-o filename:指定輸出檔名
-ansi:編譯依據ansi c標準
-Dmacro:定義巨集macro
-Dmarco=defn:定義巨集macro為defn
-Wa,<options>:將選項(option)傳給組譯器
-Wp,<options>:將選項(option)傳給preprocessor
-Wl,<options>:將選項(option)傳給連結器
-I:增加標頭檔的標準路徑
-L:增加library的標準路徑
-l:指定連結的函式庫(如-lpthread)
-Wall:顯示所有的警告訊息
-g:編入除錯資訊
-Os,-O,-O2,-O3:做最佳化
Subscribe to:
Posts (Atom)