2012-11-13 68 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()调用是相对的或本地的(即不是完整路径),您需要预先安排当前路径并对../等进行任何调整。