|
|
Bu makalenin farkl� dillerde bulundu�u adresler: English Deutsch Francais Russian Turkce |
Guido Socher (homepage) Yazar hakk�nda: Guido, sorunlar� ara�t�rma f�rsat� tan�d�klar� i�in Linux gibi a��k kaynak kodlu sistemlerden ho�lanmaktad�r. E�er, zaman ay�rabilirseniz, sorunlar�n ana kayna��n� bulman�z olas�d�r. T�rk�e'ye �eviri: Erdal Mutlu <erdal(at)linuxfocus.org> ��erik: |
Bu neden �al��m�yor? Linux uygulamalar�ndaki hatalar nas�l belirlenebilir ve d�zeltilebilir?�zet:
Herkes Linux alt�nda �al��an uygulamalar�n hatalar�n� kolayca belirlenebilece�inden ve d�zeltilebilece�inden
s�z ediyor. Ne yaz�k ki, bunun nas�l yap�ld���n� anlatan belgeler bulmak �ok zor.
Bu yaz�da, bir uygulaman�n asl�nda nas�l �al��t���n� ��renmeden, uygulamada olu�an hatalar�
bulmay� ��reneceksiniz.
|
Kaynak kodu kapal� olan sistemlerde bir sorun ortaya ��kt���nda, yapabilecekleriniz genelde a�a��daki iki se�enekle s�n�rl�d�r:
Bu engellere kar��n, program�n t�m kaynak kodunu okumadan ve has�l �al��t���n� ��renmeden �nce, yapabilece�iniz �eyler vard�r.
#includeC programlama dilinde yaz�lan her program sistem �etele dosyas�na yazabilir. Di�er programlama dillerin de kendi olanaklar� vard�r. Kabuk betikleri bile �etele tutabilir:void openlog(const char *ident, int option, int facility); void syslog(int priority, const char *format, ...); void closelog(void); facility (olanak) iletiyi g�nderenin hangi t�rden bir uygulama oldu�unu belirler. priority (�ncelik) iletinin �nemini belirtmektedir. priority (�ncelik) i�in olas� de�erler �unlard�r: LOG_EMERG LOG_ALERT LOG_CRIT LOG_ERR LOG_WARNING LOG_NOTICE LOG_INFO LOG_DEBUG
logger -p err "Bu yaz� /var/log/messages dosyas�na yaz�lacakt�r."syslog'un standart yap�land�rma dosyas�nda (/etc/syslog.conf) ba�ka yap�land�rmalar�n yan�s�ra, a�a��dakine benzer bir sat�r olmas� gerekir:
# Log anything (except mail) of level info or higher. # Don't log private authentication messages. *.info;mail.none;authpriv.none /var/log/messages"*.info" �ncelik seviyesi LOG_INFO veya daha y�ksek olan her�eyi �etele dosyas�na yazacakt�r. Daha fazla bilgi g�rmek isterseniz, bunu "*.debug" yap�p syslog'u yeniden ba�latabilirsiniz (/etc/init.d/syslog restart).
1) tail -f /var/log/messages komutunu �al��t�r�n ve ba�ka bir kabuktan hatal� uygulamay� ba�lat�n. Belkide daha �imdiden yanl�� giden �eyler hakk�nda bilgi elde edebilrsiniz. 2) E�er, 1. ad�m yeterli olmazsa, /etc/syslog.conf'daki *.info yu *.debug olarak de�i�tirin ve "/etc/init.d/syslog restart" komutuyla syslog servisini yeniden ba�lat�p ve 1. ad�ma d�n�n.Bu y�ntemin eksi�i, yaz�l�mc�n�n kaynak kodunda ne kadar denetim yapt���na ve bunlar� �etele dosyas�na g�nderip g�ndermemesine olmas�d�r. E�er, �nemli yerlere syslog fonksiyonunu yere�tirmemi�se, hi�bir �ey g�remeyebilirsiniz. Ba�ka bir deyi�le, sorunlar� belirleyebilmenin �art�, yaz�l�mc�n�n baz� yerlerde sorunlar�n ��kabilece�ini �ng�rm�� olmas�d�r.
strace your_application��te bir �rnek:
# strace /usr/sbin/uucico execve("/usr/sbin/uucico", ["/usr/sbin/uucico", "-S", "uucpssh", "-X", "11"], [/* 36 vars */]) = 0 uname({sys="Linux", node="brain", ...}) = 0 brk(0) = 0x8085e34 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40014000 open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=70865, ...}) = 0 mmap2(NULL, 70865, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40015000 close(3) = 0 open("/lib/libnsl.so.1", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300;\0"..., 1024) = 1024 fstat64(3, {st_mode=S_IFREG|0755, st_size=89509, ...}) = 0 mmap2(NULL, 84768, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x40027000 mprotect(0x40039000, 11040, PROT_NONE) = 0 mmap2(0x40039000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x11) = 0x40039000 mmap2(0x4003a000, 6944, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x4003a000 close(3) = 0 open("/lib/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`X\1\000"..., 1024) = 1024 fstat64(3, {st_mode=S_IFREG|0755, st_size=1465426, ...}) = 0 mmap2(NULL, 1230884, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x4003c000 mprotect(0x40163000, 22564, PROT_NONE) = 0 mmap2(0x40163000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x126) = 0x40163000 mmap2(0x40166000, 10276, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40166000 close(3) = 0 munmap(0x40015000, 70865) = 0 brk(0) = 0x8085e34 brk(0x8086e34) = 0x8086e34 brk(0) = 0x8086e34 brk(0x8087000) = 0x8087000 open("/usr/conf/uucp/config", O_RDONLY) = -1 ENOENT (No such file or directory) rt_sigaction(SIGINT, NULL, {SIG_DFL}, 8) = 0 rt_sigaction(SIGINT, {0x806a700, [], SA_RESTORER|SA_INTERRUPT, 0x40064d58}, NULL, 8) = 0 rt_sigaction(SIGHUP, NULL, {SIG_DFL}, 8) = 0 rt_sigaction(SIGHUP, {0x806a700, [], SA_RESTORER|SA_INTERRUPT, 0x40064d58}, NULL, 8) = 0 rt_sigaction(SIGQUIT, NULL, {SIG_DFL}, 8) = 0 rt_sigaction(SIGQUIT, {0x806a700, [], SA_RESTORER|SA_INTERRUPT, 0x40064d58}, NULL, 8) = 0 rt_sigaction(SIGTERM, NULL, {SIG_DFL}, 8) = 0 rt_sigaction(SIGTERM, {0x806a700, [], SA_RESTORER|SA_INTERRUPT, 0x40064d58}, NULL, 8) = 0 rt_sigaction(SIGPIPE, NULL, {SIG_DFL}, 8) = 0 rt_sigaction(SIGPIPE, {0x806a700, [], SA_RESTORER|SA_INTERRUPT, 0x40064d58}, NULL, 8) = 0 getpid() = 1605 getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=1024}) = 0 close(3) = -1 EBADF (Bad file descriptor) close(4) = -1 EBADF (Bad file descriptor) close(5) = -1 EBADF (Bad file descriptor) close(6) = -1 EBADF (Bad file descriptor) close(7) = -1 EBADF (Bad file descriptor) close(8) = -1 EBADF (Bad file descriptor) close(9) = -1 EBADF (Bad file descriptor) fcntl64(0, F_GETFD) = 0 fcntl64(1, F_GETFD) = 0 fcntl64(2, F_GETFD) = 0 uname({sys="Linux", node="brain", ...}) = 0 umask(0) = 022 socket(PF_UNIX, SOCK_STREAM, 0) = 3 connect(3, {sa_family=AF_UNIX, path="/var/run/.nscd_socket"}, 110) = -1 ENOENT (No such file or directory) close(3) = 0 open("/etc/nsswitch.conf", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=499, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40015000 read(3, "# /etc/nsswitch.conf:\n# $Header:"..., 4096) = 499 read(3, "", 4096) = 0 close(3) = 0 munmap(0x40015000, 4096) = 0 open("/etc/ld.so.cache", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=70865, ...}) = 0 mmap2(NULL, 70865, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40015000 close(3) = 0 open("/lib/libnss_compat.so.2", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\25"..., 1024) = 1024 fstat64(3, {st_mode=S_IFREG|0755, st_size=50250, ...}) = 0 mmap2(NULL, 46120, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x40169000 mprotect(0x40174000, 1064, PROT_NONE) = 0 mmap2(0x40174000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0xa) = 0x40174000 close(3) = 0 munmap(0x40015000, 70865) = 0 uname({sys="Linux", node="brain", ...}) = 0 brk(0) = 0x8087000 brk(0x8088000) = 0x8088000 open("/etc/passwd", O_RDONLY) = 3 fcntl64(3, F_GETFD) = 0 fcntl64(3, F_SETFD, FD_CLOEXEC) = 0 fstat64(3, {st_mode=S_IFREG|0644, st_size=1864, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40015000 _llseek(3, 0, [0], SEEK_CUR) = 0 read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1864 close(3) = 0 munmap(0x40015000, 4096) = 0 getuid32() = 10 geteuid32() = 10 chdir("/var/spool/uucp") = 0 open("/usr/conf/uucp/sys", O_RDONLY) = -1 ENOENT (No such file or directory) open("/var/log/uucp/Debug", O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY, 0600) = 3 fcntl64(3, F_GETFD) = 0 fcntl64(3, F_SETFD, FD_CLOEXEC) = 0 fcntl64(3, F_GETFL) = 0x401 (flags O_WRONLY|O_APPEND) fstat64(3, {st_mode=S_IFREG|0600, st_size=296, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40015000 _llseek(3, 0, [0], SEEK_CUR) = 0 open("/var/log/uucp/Log", O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY, 0644) = 4 fcntl64(4, F_GETFD) = 0 fcntl64(4, F_SETFD, FD_CLOEXEC) = 0 fcntl64(4, F_GETFL) = 0x401 (flags O_WRONLY|O_APPEND)Burada ne g�r�yoruz? �sterseniz a�a��daki sat�rlara bir g�z atal�m:
open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3Elde edilen ��kt�ya bir bakal�m. Program ilk �nce /etc/ld.so.preload dosyas�n� okumaya �al���yor ve ba�ar�s�z oluyor, daha sonra /etc/ld.so.cache dosyas�n� okumaktad�r. Burada ba�ar�l� olmakta ve 3 nolu dosya tan�mlay�c�s�n� elde etmektedir. /etc/ld.so.preload dosyas�n� okuyamamas� tam olarak bir hata anlam�na gelmeyebilir, ��nk� belkide program varsa ilk �nce bu dosyay� okumak istemi�tir. Ba�ka bir deyi�le, bir dosyay� okuyamamak, mutlaka hata anlam�na gelmeyebilir. Her�ey program�n tasarlanma �ekline ba�l�d�r. strace ��kt�s�ndaki t�m open sistem �a�r�lar�na bir g�z atal�m:
open("/usr/conf/uucp/config", O_RDONLY)= -1 ENOENT (No such file or directory) open("/etc/nsswitch.conf", O_RDONLY) = 3 open("/etc/ld.so.cache", O_RDONLY) = 3 open("/lib/libnss_compat.so.2", O_RDONLY) = 3 open("/etc/passwd", O_RDONLY) = 3 open("/usr/conf/uucp/sys", O_RDONLY) = -1 ENOENT (No such file or directory) open("/var/log/uucp/Debug", O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY, 0600) = 3 open("/var/log/uucp/Log", O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY, 0644) = 4 open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3�imdi program /usr/conf/uucp/config dosyas�n� okumaya �al���yor. Ooo! Ama bu �ok garip benim dosyam /etc/uucp/config dir! Ve /etc/uucp/config dosyas�n� a�mak isteyen hi�bir sat�r ��kt�da g�r�nm�yor. Hata bu olmal� i�te. Herhalde yap�land�rma dosyas�n�n yeri, program�n derlenmesi s�ras�nda yanl�� belirtildi.
# ulimit -c unlimited # ./lshref -i index.html,index.htm test.html Segmentation fault (core dumped) Exit 139Olu�an core dosyas�, gdb hata ay�klay�c�s� kullan�larak sorunun neden kaynakland��� ara�t�rmas� yap�labilir. gdb'yi �al��t�rmadan �nce, do�ru core dosyas�na bakt���n�z� denetlemede yarar vard�r:
# file core.16897 core.16897: ELF 32-bit LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from 'lshref'Tamam, bozuk olan program lshref dir ve onu �imdi gdb'ye y�kleyebiliriz. gdb'yi bir core dosyas�n� incelemek i�in �al��t�rmak istedi�inizde, core dosyas�n�n ad�yla birlikte, bu dosyan�n olu�mas�na neden olan program� da belirtmeniz gerekmektedir.
# gdb ./lshref core.23061 GNU gdb Linux (5.2.1-4) Copyright 2002 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. Core was generated by `./lshref -i index.html,index.htm test.html'. Program terminated with signal 11, Segmentation fault. 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 #0 0x40095e9d in strcpy () from /lib/libc.so.6 (gdb)�imdi art�k program�n strcpy fonksiyonunu kullan�rken ��kt���n� biliyoruz. Ancak, program i�erisinde strcpy birden fazla yerde kullan�l�yor olabilir.
gdb ./lshref core.23061 GNU gdb Linux (5.2.1-4) Copyright 2002 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. Core was generated by `./lshref -i index.html,index.htm test.html'. Program terminated with signal 11, Segmentation fault. 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 #0 0x40095e9d in strcpy () from /lib/libc.so.6 (gdb) backtrace #0 0x40095e9d in strcpy () from /lib/libc.so.6 Cannot access memory at address 0xbfffeb38 (gdb) run ./lshref -i index.html,index.htm test.html Starting program: /home/guido/lshref ./lshref -i index.html,index.htm test.html Program received signal SIGSEGV, Segmentation fault. 0x40095e9d in strcpy () from /lib/libc.so.6 (gdb) backtrace #0 0x40095e9d in strcpy () from /lib/libc.so.6 #1 0x08048d09 in string_to_list () #2 0x080494c8 in main () #3 0x400374ed in __libc_start_main () from /lib/libc.so.6 (gdb)�imdi g�r�yoruz ki, sorun yarat strcpy fonksiyonunu string_to_list() fonksiyonu, onu da main() �a��rm��t�r. string_to_list() fonksiyonuna bir bakal�m:
char **string_to_list(char *string){ char *dat; char *chptr; char **array; int i=0; dat=(char *)malloc(strlen(string))+5000; array=(char **)malloc(sizeof(char *)*51); strcpy(dat,string);malloc sat�r�nda bir yaz�m hatas� var gibi g�z�k�yor. Asl�nda ��yle olmal�yd�:
dat=(char *)malloc(strlen(string)+5000);
#includeProgram� derliyor:#include int add(int *p,int a,int b) { *p=a+b; return(*p); } int main(void) { int i; int *p = 0; /* a null pointer */ printf("result is %d\n", add(p,2,3)); return(0); }
gcc -Wall -g -o exmp exmp.cve �al��t�r�yoruz ...
# ./exmp Segmentation fault (core dumped) Exit 139
gdb exmp core.5302 GNU gdb Linux (5.2.1-4) Copyright 2002 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. Core was generated by `./exmp'. Program terminated with signal 11, Segmentation fault. 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 #0 0x08048334 in add (p=Cannot access memory at address 0xbfffe020 ) at exmp.c:6 6 *p=a+b;gdb, hatan�n 6. sat�rda ve 'p' i�aret�isinin, eri�im hakk� olmad��� bir bellek alan�na eri�mek isterken olu�tu�unu s�ylemektedir.
|
G�rsely�re sayfalar�n�n bak�m�, LinuxFocus Edit�rleri taraf�ndan yap�lmaktad�r
© Guido Socher, FDL LinuxFocus.org |
�eviri bilgisi:
|
2004-07-02, generated by lfparser version 2.43