2012-11-13 94 views
1

我以這種方式使用strace的: strace的輸出處理

strace -xf -eopen -o out_configure.log ./configure 
strace -xf -eopen -o out_make.log make 

然後我得到明確的文件列表中使用sed:

sed -n 's/.*open("\(.*\)".*)\s*=.*/\1/p' out_configure.log out_make.log | sort -u 

有一個輸出例子:

/usr/share/locale-langpack/en.utf8/LC_MESSAGES/gcc-4.6.mo 
/usr/share/locale-langpack/en.UTF-8/LC_MESSAGES/gcc-4.6.mo 
/usr/share/locale-langpack/en.utf8/LC_MESSAGES/grep.mo 
/usr/share/locale-langpack/en.UTF-8/LC_MESSAGES/grep.mo 
/usr/share/locale-langpack/en.utf8/LC_MESSAGES/make.mo 
/usr/share/locale-langpack/en.UTF-8/LC_MESSAGES/make.mo 
/usr/share/locale/locale.alias 
/usr/share/misc/magic.mgc 
/usr/x86_64-linux-gnu/lib64/libc_r.a 
/usr/x86_64-linux-gnu/lib64/libc_r.so 
/usr/x86_64-linux-gnu/lib64/libsendfile.a 
/usr/x86_64-linux-gnu/lib64/libsendfile.so 
/usr/x86_64-linux-gnu/lib64/libtruerand.a 
/usr/x86_64-linux-gnu/lib64/libtruerand.so 
/usr/x86_64-linux-gnu/lib64/libuuid.a 
/usr/x86_64-linux-gnu/lib64/libuuid.so 
util.c 
util_cfgtree.c 
./util_cfgtree.h 
util_cfgtree.h 
util_cfgtree.i 
./util_cfgtree.lo 
util_cfgtree.lo 
util_cfgtree.loT 
util_cfgtree.o 
util_cfgtree.s 
util_charset.c 
./util_charset.h 

我的問題是非全名條目(如「util.c」或「./util_cfgtree.h」)。 有沒有什麼辦法在strace輸出中獲得全名?

我已經寫了這個劇本:

#!/usr/bin/python 
# coding=UTF8 
import subprocess 
import os 

fileList = [] 
for dirname, dirnames, filenames in os.walk(os.path.abspath('.')): 
    for filename in filenames: 
     fileList.append(os.path.join(dirname, filename)) 

straceProcess = subprocess.Popen("strace -s 1000 -xf -o out_configure.sed.log ./configure".split(), stdout=subprocess.PIPE).communicate()[0] 
straceProcess2 = subprocess.Popen("strace -s 1000 -xf -o out_make.sed.log make".split(), stdout=subprocess.PIPE).communicate()[0] 


f = open("out_configure.sed.log", "r+") 
n = open("out_make.sed.log", "r+") 

lines = [] 
for l in f: 
    lines.append(l) 
for l in n: 
    lines.append(l) 

f.close() 
n.close() 

pids = {} 

filesInUse = [] 
currentDir = os.path.abspath('.') 
for line in lines: 
    parts = line.split() 

if not pids.has_key(parts[0]): 
    pids[parts[0]] = currentDir 

if parts[1].startswith("clone"): 
    pid = parts[parts.__len__() - 1] 
    if not pids.has_key(pid): 
     pids[pid] = os.path.abspath(pids.get(parts[0])) 


elif parts[1].startswith("chdir"): 
    if parts[1].split("\"")[1].startswith("/"): 
     pids[parts[0]] = os.path.abspath(parts[1].split("\"")[1]) 

    elif parts[1].split("\"")[1].startswith("."): 
     pids[parts[0]] = os.path.abspath(pids.get(pids[parts[0]]) + '/' + parts[1].split("\"")[1]) 
    else: 
     pids[parts[0]] = os.path.abspath(pids.get(parts[0]) + '/' + parts[1].split("\"")[1]) 

elif parts[1].startswith("open("): 
    if parts[1].split("\"")[1].startswith("/"): 
     filesInUse.append(os.path.abspath(parts[1].split("\"")[1])) 
    elif parts[1].split("\"")[1].startswith("."): 
     filesInUse.append(os.path.abspath(pids.get(parts[0]) + '/' + parts[1].split("\"")[1])) 
    else: 
     filesInUse.append(os.path.abspath(pids.get(parts[0]) + '/' + parts[1].split("\"")[1])) 


for l in filesInUse: 
    if l in fileList: 
     fileList.remove(l) 

for l in fileList: 
    print l 

但我的Python的知識是非常差的。

有沒有錯誤或不好的解決方案?

+3

'strace'會記錄系統調用。如果程序要求打開(「util_charset.c」,...)',那就是將被記錄的名稱。您需要知道進程的當前目錄以便能夠解釋相對路徑名(包括'open(「subdir/file.c」,...)')。爲此,您需要知道流程的當前目錄 - 流程啓動時的啓動以及流程運行期間所做的任何更改。如果您有兩個目錄,例如程序源代碼的舊版本和新版本,則可能無法從'strace'輸出中說出哪個版本被跟蹤。 –

回答

0

這些是與您正在製作的應用程序相關的本地文件。

您可以將列表解析爲另一個文件,然後查找以./開頭的任何內容或不以/開始並在腳本中查找映射路徑的內容。

在下面的例子中,我被編譯Apache和那些相同的文件出現在一個隱藏的文件夾(在服務器文件夾的構建過程的一部分)

find . -name vhost.o 
./server/.libs/vhost.o 
./server/vhost.o 

ls server/.libs/ 
config.o  core_filters.o eoc_bucket.o exports.o  libmain.a listen.o main.o  protocol.o request.o  util_cfgtree.o util_debug.o util_filter.o util.o  util_script.o util_xml.o 
connection.o core.o   error_bucket.o gen_test_char.o libmain.la log.o  mpm_common.o provider.o scoreboard.o util_charset.o util_ebcdic.o util_md5.o  util_pcre.o util_time.o vhost.o 

E2A: 這裏是一個內襯做什麼你需要:

command="sed -n 's/.*open(\"\(.*\)\".*)\s*=.*/\1/p' out_configure.log out_make.log | sort -u"; echo "remote: " && echo $command| /bin/sh|grep "^/" ;echo "______________________"; echo "local" && echo $command|/bin/sh|grep -v "^/" |xargs -I {} find . -name {} -print 
2

我認爲爲了做到這一點,你還需要跟蹤chdir()系統調用。後期處理將更加複雜,並且您可能需要切換到awk,perlpython或其他用於後期處理的內容,因爲您需要解釋每個chdir()以跟蹤當前工作目錄的變化,然後open()調用是相對的或本地的(即不是完整路徑),您需要預先安排當前路徑並對../等進行任何調整。