¼ò½é
½ø³ÌÎÞ·¨Æô¶¯£¬Èí¼þÔËÐÐËÙ¶ÈͻȻ±äÂý£¬³ÌÐòµÄ"Segment Fault"µÈµÈ¶¼ÊÇÈÃÿ¸öUnixϵͳÓû§Í·Í´µÄÎÊÌ⣬±¾ÎÄͨ¹ýÈý¸öʵ¼Ê°¸ÀýÑÝʾÈçºÎʹÓÃtruss¡¢straceºÍltraceÕâÈý¸ö³£Óõĵ÷ÊÔ¹¤¾ßÀ´¿ìËÙÕï¶ÏÈí¼þµÄ"ÒÉÄÑÔÓÖ¢"¡£
truss ºÍstraceÓÃÀ´ ¸ú×ÙÒ»¸ö½ø³ÌµÄϵͳµ÷ÓûòÐźŲúÉúµÄÇé¿ö£¬¶ø ltraceÓÃÀ´ ¸ú×Ù½ø³Ìµ÷Óÿ⺯ÊýµÄÇé¿ö¡£truss ÊÇÔçÆÚΪ System V R4¿ª·¢µÄµ÷ÊÔ³ÌÐò£¬°üÀ¨Aix¡¢FreeBSDÔÚÄڵĴ󲿷ÖUnixϵͳ¶¼×Ô´øÁËÕâ¸ö¹¤¾ß£»¶østrace×î³õÊÇΪSunOSϵͳ±àдµÄ£¬ltrace ×îÔç³öÏÖÔÚGNU/Debian LinuxÖС£ÕâÁ½¸ö¹¤¾ßÏÖÔÚÒ²Òѱ»ÒÆÖ²µ½Á˴󲿷ÖUnixϵͳÖУ¬´ó¶àÊýLinux·¢Ðа涼×Ô´øÁËstraceºÍltrace£¬¶øFreeBSDÒ²¿Éͨ¹ýPorts°²×°ËüÃÇ¡£
Äã²»½ö¿ÉÒÔ´ÓÃüÁîÐе÷ÊÔÒ»¸öпªÊ¼µÄ³ÌÐò£¬Ò²¿ÉÒÔ°Ñtruss¡¢strace»òltrace°ó¶¨µ½Ò»¸öÒÑÓеÄPIDÉÏÀ´µ÷ÊÔÒ»¸öÕýÔÚÔËÐеijÌÐò¡£Èý¸öµ÷ÊÔ¹¤¾ßµÄ»ù±¾Ê¹Ó÷½·¨´óÌåÏàͬ£¬ÏÂÃæ½ö½éÉÜÈýÕß¹²ÓУ¬¶øÇÒÊÇ×î³£ÓõÄÈý¸öÃüÁîÐвÎÊý£º
-f £º³ýÁ˸ú×Ùµ±Ç°½ø³ÌÍ⣬»¹¸ú×ÙÆä×Ó½ø³Ì¡£
-o file £º½«Êä³öÐÅϢдµ½ÎļþfileÖУ¬¶ø²»ÊÇÏÔʾµ½±ê×¼´íÎóÊä³ö£¨stderr£©¡£
-p pid £º°ó¶¨µ½Ò»¸öÓÉpid¶ÔÓ¦µÄÕýÔÚÔËÐеĽø³Ì¡£´Ë²ÎÊý³£ÓÃÀ´µ÷ÊÔºǫ́½ø³Ì¡£
ʹÓÃÉÏÊöÈý¸ö²ÎÊý»ù±¾ÉϾͿÉÒÔÍê³É´ó¶àÊýµ÷ÊÔÈÎÎñÁË£¬ÏÂÃæ¾Ù¼¸¸öÃüÁîÐÐÀý×Ó£º
truss -o ls.truss ls -al£º ¸ú×Ùls -alµÄÔËÐУ¬½«Êä³öÐÅϢдµ½Îļþ/tmp/ls.trussÖС£
strace -f -o vim.strace vim£º ¸ú×Ùvim¼°Æä×Ó½ø³ÌµÄÔËÐУ¬½«Êä³öÐÅϢдµ½Îļþvim.strace¡£
ltrace -p 234£º ¸ú×ÙÒ»¸öpidΪ234µÄÒѾÔÚÔËÐеĽø³Ì¡£
Èý¸öµ÷ÊÔ¹¤¾ßµÄÊä³ö½á¹û¸ñʽҲºÜÏàËÆ£¬ÒÔstraceΪÀý£º
brk(0) = 0x8062aa8
brk(0x8063000) = 0x8063000
mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0x92f) = 0x40016000
ÿһÐж¼ÊÇÒ»Ìõϵͳµ÷Ó㬵ȺÅ×ó±ßÊÇϵͳµ÷Óõĺ¯ÊýÃû¼°Æä²ÎÊý£¬ÓÒ±ßÊǸõ÷Óõķµ»ØÖµ¡£ truss¡¢straceºÍltraceµÄ¹¤×÷ÔÀí´óͬСÒ죬¶¼ÊÇʹÓÃptraceϵͳµ÷Óøú×Ùµ÷ÊÔÔËÐÐÖеĽø³Ì£¬ÏêϸÔÀí²»ÔÚ±¾ÎÄÌÖÂÛ·¶Î§ÄÚ£¬ÓÐÐËȤ¿ÉÒԲο¼ËüÃǵÄÔ´´úÂë¡£
ÏÂÃæ¾ÙÁ½¸öʵÀýÑÝʾÈçºÎÀûÓÃÕâÈý¸öµ÷ÊÔ¹¤¾ßÕï¶ÏÈí¼þµÄ"ÒÉÄÑÔÓÖ¢"£º
°¸ÀýÒ»£ºÔËÐÐclint³öÏÖSegment Fault´íÎó
²Ù×÷ϵͳ£ºFreeBSD-5.2.1-release
clintÊÇÒ»¸öC++¾²Ì¬Ô´´úÂë·ÖÎö¹¤¾ß£¬Í¨¹ýPorts°²×°ºÃÖ®ºó£¬ÔËÐУº
# clint foo.cpp
Segmentation fault (core dumped)
ÔÚUnixϵͳÖÐÓö¼û"Segmentation Fault"¾ÍÏñÔÚMS WindowsÖе¯³ö"·Ç·¨²Ù×÷"¶Ô»°¿òÒ»ÑùÁîÈËÌÖÑá¡£OK£¬ÎÒÃÇÓÃtruss¸øclint"°Ñ°ÑÂö"£º
# truss -f -o clint.truss clint
Segmentation fault (core dumped)
# tail clint.truss
739: read(0x6,0x806f000,0x1000) = 4096 (0x1000)
739: fstat(6,0xbfbfe4d0) = 0 (0x0)
739: fcntl(0x6,0x3,0x0) = 4 (0x4)
739: fcntl(0x6,0x4,0x0) = 0 (0x0)
739: close(6) = 0 (0x0)
739: stat("/root/.clint/plugins",0xbfbfe680) ERR#2 'No such file or directory'
SIGNAL 11
SIGNAL 11
Process stopped because of: 16
process exit, rval = 139
ÎÒÃÇÓÃtruss¸ú×ÙclintµÄϵͳµ÷ÓÃÖ´ÐÐÇé¿ö£¬²¢°Ñ½á¹ûÊä³öµ½Îļþclint.truss£¬È»ºóÓÃtail²é¿´×îºó¼¸ÐС£×¢Òâ¿´clintÖ´ÐеÄ×îºóÒ»Ìõϵͳµ÷Ó㨵¹ÊýµÚÎåÐУ©£º stat("/root/.clint/plugins",0xbfbfe680) ERR#2 'No such file or directory'£¬ÎÊÌâ¾Í³öÔÚÕâÀclintÕÒ²»µ½Ä¿Â¼ "/root/.clint/plugins"£¬´Ó¶øÒý·¢Á˶δíÎó¡£ÔõÑù½â¾ö£¿ºÜ¼òµ¥£º mkdir -p /root/.clint/plugins£¬²»¹ýÕâ´ÎÔËÐÐclint»¹ÊÇ»á"Segmentation Fault"9¡£¼ÌÐøÓÃtruss¸ú×Ù£¬·¢ÏÖclint»¹ÐèÒªÕâ¸öĿ¼ "/root/.clint/plugins/python"£¬½¨ºÃÕâ¸öĿ¼ºóclintÖÕÓÚÄܹ»Õý³£ÔËÐÐÁË¡£
°¸Àý¶þ£ºvimÆô¶¯ËÙ¶ÈÃ÷ÏÔ±äÂý
²Ù×÷ϵͳ£ºFreeBSD-5.2.1-release
vim °æ±¾Îª6.2.154£¬´ÓÃüÁîÐÐÔËÐÐvimºó£¬ÒªµÈ´ý½ü°ë·ÖÖÓ²ÅÄܽøÈë±à¼½çÃæ£¬¶øÇÒûÓÐÈκδíÎóÊä³ö¡£×Ðϸ¼ì²éÁË.vimrcºÍËùÓеÄvim½Å±¾¶¼Ã»ÓдíÎóÅäÖã¬ÔÚÍøÉÏÒ²ÕÒ²»µ½ÀàËÆÎÊÌâµÄ½â¾ö°ì·¨£¬ÄѲ»³ÉÒªhacking source code£¿Ã»ÓбØÒª£¬ÓÃtruss¾ÍÄÜÕÒµ½ÎÊÌâËùÔÚ£º
# truss -f -D -o vim.truss vim
ÕâÀï-D²ÎÊýµÄ×÷ÓÃÊÇ£ºÔÚÿÐÐÊä³öǰ¼ÓÉÏÏà¶Ôʱ¼ä´Á£¬¼´Ã¿Ö´ÐÐÒ»Ìõϵͳµ÷ÓÃËùºÄ·ÑµÄʱ¼ä¡£ÎÒÃÇÖ»Òª¹Ø×¢ÄÄЩϵͳµ÷ÓúķѵÄʱ¼ä±È½Ï³¤¾Í¿ÉÒÔÁË£¬ÓÃless×Ðϸ²é¿´Êä³öÎļþvim.truss£¬ºÜ¿ì¾ÍÕÒµ½ÁËÒɵ㣺
735: 0.000021511 socket(0x2,0x1,0x0) = 4 (0x4)
735: 0.000014248 setsockopt(0x4,0x6,0x1,0xbfbfe3c8,0x4) = 0 (0x0)
735: 0.000013688 setsockopt(0x4,0xffff,0x8,0xbfbfe2ec,0x4) = 0 (0x0)
735: 0.000203657 connect(0x4,{ AF_INET 10.57.18.27:6000 },16) ERR#61 'Connection refused'
735: 0.000017042 close(4) = 0 (0x0)
735: 1.009366553 nanosleep(0xbfbfe468,0xbfbfe460) = 0 (0x0)
735: 0.000019556 socket(0x2,0x1,0x0) = 4 (0x4)
735: 0.000013409 setsockopt(0x4,0x6,0x1,0xbfbfe3c8,0x4) = 0 (0x0)
735: 0.000013130 setsockopt(0x4,0xffff,0x8,0xbfbfe2ec,0x4) = 0 (0x0)
735: 0.000272102 connect(0x4,{ AF_INET 10.57.18.27:6000 },16) ERR#61 'Connection refused'
735: 0.000015924 close(4) = 0 (0x0)
735: 1.009338338 nanosleep(0xbfbfe468,0xbfbfe460) = 0 (0x0)
vim ÊÔͼÁ¬½Ó 10.57.18.27Õą̂Ö÷»úµÄ6000¶Ë¿Ú£¨µÚËÄÐеÄconnect£¨£©£©£¬Á¬½Óʧ°Üºó£¬Ë¯ÃßÒ»ÃëÖÓ¼ÌÐøÖØÊÔ£¨µÚ6ÐеÄnanosleep £¨£©£©¡£ÒÔÉÏÆ¬¶ÏÑ»·³öÏÖÁËÊ®¼¸´Î£¬Ã¿´Î¶¼ÒªºÄ·ÑÒ»Ãë¶àÖÓµÄʱ¼ä£¬Õâ¾ÍÊÇvimÃ÷ÏÔ±äÂýµÄÔÒò¡£¿ÉÊÇ£¬Äã¿Ï¶¨»áÄÉÃÆ£º"vimÔõô»áÎÞÔµÎÞ¹ÊÁ¬½ÓÆäËü¼ÆËã»úµÄ 6000¶Ë¿ÚÄØ£¿"¡£Îʵúã¬ÄÇôÇëÄã»ØÏëÒ»ÏÂ6000ÊÇʲô·þÎñµÄ¶Ë¿Ú£¿Ã»´í£¬¾ÍÊÇX Server¡£¿´À´vimÊÇÒª°ÑÊä³ö¶¨Ïòµ½Ò»¸öÔ¶³Ì X Server£¬ÄÇôShellÖп϶¨¶¨ÒåÁËDISPLAY±äÁ¿£¬²é¿´.cshrc£¬¹ûÈ»ÓÐÕâôһÐУº setenv DISPLAY ¡ç {REMOTEHOST}:0£¬°ÑËü×¢Ê͵ô£¬ÔÙÖØÐµÇ¼£¬ÎÊÌâ¾Í½â¾öÁË¡£
°¸ÀýÈý£ºÓõ÷ÊÔ¹¤¾ßÕÆÎÕÈí¼þµÄ¹¤×÷ÔÀí
²Ù×÷ϵͳ£ºRed Hat Linux 9.0
Óõ÷ÊÔ¹¤¾ßʵʱ¸ú×ÙÈí¼þµÄÔËÐÐÇé¿ö²»½öÊÇÕï¶ÏÈí¼þ"ÒÉÄÑÔÓÖ¢"µÄÓÐЧµÄÊֶΣ¬Ò²¿É°ïÖúÎÒÃÇÀíÇåÈí¼þµÄ"ÂöÂç"£¬¼´¿ìËÙÕÆÎÕÈí¼þµÄÔËÐÐÁ÷³ÌºÍ¹¤×÷ÔÀí£¬²»Ê§ÎªÒ»ÖÖѧϰԴ´úÂëµÄ¸¨Öú·½·¨¡£ÏÂÃæÕâ¸ö°¸ÀýÕ¹ÏÖÁËÈçºÎʹÓÃstraceͨ¹ý¸ú×Ù±ðµÄÈí¼þÀ´"´¥·¢Áé¸Ð"£¬´Ó¶ø½â¾öÈí¼þ¿ª·¢ÖеÄÄÑÌâµÄ¡£
´ó¼Ò¶¼ÖªµÀ£¬ÔÚ½ø³ÌÄÚ´ò¿ªÒ»¸öÎļþ£¬¶¼ÓÐΨһһ¸öÎļþÃèÊö·û£¨fd£ºfile descriptor£©ÓëÕâ¸öÎļþ¶ÔÓ¦¡£¶ø±¾ÈËÔÚ¿ª·¢Ò»¸öÈí¼þ¹ý³ÌÖÐÓöµ½ÕâÑùÒ»¸öÎÊÌ⣺ÒÑÖªÒ»¸öfd £¬ÈçºÎ»ñÈ¡Õâ¸öfdËù¶ÔÓ¦ÎļþµÄÍêÕû·¾¶£¿²»¹ÜÊÇLinux¡¢FreeBSD»òÊÇÆäËüUnixϵͳ¶¼Ã»ÓÐÌṩÕâÑùµÄAPI£¬Ôõô°ìÄØ£¿ÎÒÃÇ»»¸ö½Ç¶È˼¿¼£º UnixÏÂÓÐûÓÐʲôÈí¼þ¿ÉÒÔ»ñÈ¡½ø³Ì´ò¿ªÁËÄÄЩÎļþ£¿Èç¹ûÄã¾Ñé×ã¹»·á¸»£¬ºÜÈÝÒ×Ïëµ½lsof£¬Ê¹ÓÃËü¼È¿ÉÒÔÖªµÀ½ø³Ì´ò¿ªÁËÄÄЩÎļþ£¬Ò²¿ÉÒÔÁ˽âÒ»¸öÎļþ±»Äĸö½ø³Ì´ò¿ª¡£
ºÃ£¬ÎÒÃÇÓÃÒ»¸öС³ÌÐòÀ´ÊÔÑéÒ»ÏÂlsof£¬¿´ËüÊÇÈçºÎ»ñÈ¡½ø³Ì´ò¿ªÁËÄÄЩÎļþ¡£
/* testlsof.c */
#include
#include
#include
#include
#include
int main(void)
{
open("/tmp/foo", O_CREAT O_RDONLY); /* ´ò¿ªÎļþ/tmp/foo */
sleep(1200); /* ˯Ãß1200Ã룬ÒÔ±ã½øÐкóÐø²Ù×÷ */
return 0;
}
½«testlsof·ÅÈëºǫ́ÔËÐУ¬ÆäpidΪ3125¡£ÃüÁîlsof -p 3125²é¿´½ø³Ì3125´ò¿ªÁËÄÄЩÎļþ£¬ÎÒÃÇÓÃstrace¸ú×ÙlsofµÄÔËÐУ¬Êä³ö½á¹û±£´æÔÚlsof.straceÖУº
# gcc testlsof.c -o testlsof
# ./testlsof &
3125
# strace -o lsof.strace lsof -p 3125
ÎÒÃÇÒÔ"/tmp/foo"Ϊ¹Ø¼ü×ÖËÑË÷Êä³öÎļþlsof.strace£¬½á¹ûÖ»ÓÐÒ»Ìõ£º
# grep '/tmp/foo' lsof.strace
readlink("/proc/3125/fd/3", "/tmp/foo", 4096) = 8
ÔÀ´lsofÇÉÃîµÄÀûÓÃÁË /proc/nnnn/fd/Ŀ¼£¨nnnnΪpid£©£ºLinuxÄں˻áΪÿһ¸ö½ø³ÌÔÚ/proc/½¨Á¢Ò»¸öÒÔÆäpidΪÃûµÄĿ¼ÓÃÀ´±£´æ½ø³ÌµÄÏà¹ØÐÅÏ¢£¬¶øÆä×ÓĿ¼fd±£´æµÄÊǸýø³Ì´ò¿ªµÄËùÓÐÎļþµÄfd¡£Ä¿±êÀëÎÒÃǺܽüÁË¡£ºÃ£¬ÎÒÃǵ½/proc/3125/fd/¿´¸ö¾¿¾¹£º
# cd /proc/3125/fd/
# ls -l
total 0
lrwx------ 1 root root 64 Nov 5 09:50 0 -> /dev/pts/0
lrwx------ 1 root root 64 Nov 5 09:50 1 -> /dev/pts/0
lrwx------ 1 root root 64 Nov 5 09:50 2 -> /dev/pts/0
lr-x------ 1 root root 64 Nov 5 09:50 3 -> /tmp/foo
# readlink /proc/3125/fd/3
/tmp/foo
´ð°¸ÒѾºÜÃ÷ÏÔÁË£º/proc/nnnn/fd/Ŀ¼ÏµÄÿһ¸öfdÎļþ¶¼ÊÇ·ûºÅÁ´½Ó£¬¶ø´ËÁ´½Ó¾ÍÖ¸Ïò±»¸Ã½ø³Ì´ò¿ªµÄÒ»¸öÎļþ¡£ÎÒÃÇÖ»ÒªÓÃreadlink()ϵͳµ÷ÓþͿÉÒÔ»ñȡij¸öfd¶ÔÓ¦µÄÎļþÁË£¬´úÂëÈçÏ£º
#include
#include
#include
#include
#include
#include
int get_pathname_from_fd(int fd, char pathname[], int n)
{
char buf[1024];
pid_t pid;
bzero(buf, 1024);
pid = getpid();
snprintf(buf, 1024, "/proc/%i/fd/%i", pid, fd);
return readlink(buf, pathname, n);
}
int main(void)
{
int fd;
char pathname[4096];
bzero(pathname, 4096);
fd = open("/tmp/foo", O_CREAT O_RDONLY);
get_pathname_from_fd(fd, pathname, 4096);
printf("fd=%d; pathname=%sn", fd, pathname);
return 0;
}
¡¾×¢¡¿³öÓÚ°²È«·½ÃæµÄ¿¼ÂÇ£¬ÔÚFreeBSD 5 Ö®ºóϵͳĬÈÏÒѾ²»ÔÙ×Ô¶¯×°ÔØprocÎļþϵͳ£¬Òò´Ë£¬ÒªÏëʹÓÃtruss»òstrace¸ú×Ù³ÌÐò£¬Äã±ØÐëÊÖ¹¤×°ÔØprocÎļþϵͳ£ºmount -t procfs proc /proc£»»òÕßÔÚ/etc/fstabÖмÓÉÏÒ»ÐУº
proc /proc procfs rw 0 0
ltrace²»ÐèҪʹÓÃprocfs¡£
²Î¿¼×ÊÁÏ
* truss(1) manual page
* strace(1) manual page
* ltrace(1) manual page
* ptrace(2) manual page
* lsof(1) manual page
* Debugging with strace£º http://www.devchannel.org/devtoolschannel/03/10/24/2057246.shtml