On Thu, 24 Jan 2008, Nick Rout wrote:
I often find strace gives more info than I can comprehend. Very often the
problems I am looking at solving are to do with libraries (missing,
outdated, updated etc)
For missing libraries sometimes
ldd -v /path/to/program
can be more explicit.
To handle the info flood I have my nifty "grace" script...
strace -o tlog ls
a.txt0 Makefile Makefile~ tlog uniqId #uniqId.cpp# uniqId.cpp
uniqId.cpp~ uniqId.o
$ grace < tlog
Unhandled set_robust_list(0xb7d35700, 0xc) = 0
Unhandled statfs64("/selinux", 84, 0xbfdad380) = -1 ENOENT (No such file or
directory)
. close fcntl64 fstat64 getdents64(2) open
/bin/ls execve
/etc/ld.so.cache close fstat64 open
/etc/ld.so.nohwcap access(9)
/etc/ld.so.preload access
/lib/libacl.so.1 close fstat64 open read
/lib/libattr.so.1 close fstat64 open read
/lib/libselinux.so.1 close fstat64 open read
/lib/libsepol.so.1 close fstat64 open read
/lib/tls/i686/cmov/libc.so.6 close fstat64 open read
/lib/tls/i686/cmov/libdl.so.2 close fstat64 open read
/lib/tls/i686/cmov/libpthread.so.0 close fstat64 open read
/lib/tls/i686/cmov/librt.so.1 close fstat64 open read
/proc/meminfo close fstat64 open read
/proc/mounts close fstat64 open read(3)
/usr/lib/gconv/gconv-modules.cache close fstat64 open
/usr/lib/locale/en_NZ.utf8/LC_ADDRESS close fstat64 open
/usr/lib/locale/en_NZ.utf8/LC_COLLATE close fstat64 open
/usr/lib/locale/en_NZ.utf8/LC_CTYPE close fstat64 open
/usr/lib/locale/en_NZ.utf8/LC_IDENTIFICATION close fstat64 open
/usr/lib/locale/en_NZ.utf8/LC_MEASUREMENT close fstat64 open
/usr/lib/locale/en_NZ.utf8/LC_MESSAGES close fstat64 open
/usr/lib/locale/en_NZ.utf8/LC_MESSAGES/SYS_LC_MESSAGES close fstat64 open
/usr/lib/locale/en_NZ.utf8/LC_MONETARY close fstat64 open
/usr/lib/locale/en_NZ.utf8/LC_NAME close fstat64 open
/usr/lib/locale/en_NZ.utf8/LC_NUMERIC close fstat64 open
/usr/lib/locale/en_NZ.utf8/LC_PAPER close fstat64 open
/usr/lib/locale/en_NZ.utf8/LC_TELEPHONE close fstat64 open
/usr/lib/locale/en_NZ.utf8/LC_TIME close fstat64 open
/usr/share/locale/locale.alias close fstat64 open read(2)
__NO FILE NAME NEEDED__ brk(3) exit_group futex getrlimit mmap2(41) mprotect munmap(5) rt_sigaction(2) rt_sigprocmask set_thread_area set_tid_address uname
John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : [EMAIL PROTECTED]
New Zealand
==~/bin/grace=========================================================
#!/usr/bin/ruby -w
require 'pp'
def printHelp(plaint = 'Usage:-')
print <<EOHELP;
#{plaint}
grace [-e] < tlog
An aid to grokking strace files, first create strace file like so...
strace -o tlog myprog
Will print out a list of all the files it
\(open|access|stat|unlink|exec|...\)ed.
-e Include files that couldn\'t be opened.
-f If you use \"strace -f\", then this option strip\'s the pid
off the front of the line.
EOHELP
exit(0);
end
enoent = false
strip_pid = false
while !ARGV.empty?
arg = ARGV.shift
if arg == '-e'
enoent = true
elsif arg == '-f'
strip_pid = true
else
printHelp("Invalid option #{arg}")
end
end
class Fog < Hash
def []=(k,v)
raise if k.nil?
super(k,v)
end
end
o = Fog.new {|hash,key|hash[key] = Hash.new(0)}
fd_to_file_name = {}
STDIN.each do |line|
line.chomp!;
if strip_pid
line.sub!( %r{^\s* \d+ \s+}x, '')
end
# Facilities of the form ^name("fileName",....) = fd
if line =~ %r{ ^(?:\d+ \s)? (open) \( \"([^\"]+ )\" .* \s+ = \s+ (\S+) }x
facility, fileName, fd = $1, $2, $3
next if !enoent && line =~ /ENOENT/;
o[fileName][facility] += 1
fd_to_file_name[fd] = fileName
elsif line =~ %r{ ^ (?:\d+ \s)? (connect|bind|getsockname) \( (\d+) .*
path="([^\"]+)" }x
facility, fd, fileName = $1, $2, $3
o[fileName][facility] += 1
fd_to_file_name[fd] = fileName
elsif line =~ %r{ ^ (?:\d+ \s)? (connect) \( (\d+) .*
sin_port=htons\((\d+)\),\s*sin_addr=inet_addr\("([^\"]+)"\) }x
facility, fd, port, inet_addr = $1, $2, $3, $4
fileName = "__IP_#{inet_addr}:#{port}"
o[fileName][facility] += 1
fd_to_file_name[fd] = fileName
elsif line =~ %r{ ^ (?:\d+ \s)?
(readv?|writev?|fchmod|fchown(?:32)?|send|recvfrom|close|
fstat\d*|ioctl|flock|ftruncate|fsync|fcntl\d*|getdents\d*|
(?:_ll|l)?seek|listen|[gs]etsockopt|accept|shutdown|getpeername) \( (\d+) }x
facility, fd = $1, $2
if fd_to_file_name.has_key? fd
fileName = fd_to_file_name[fd]
raise "I'm confused about #{fd}, #{fileName}, #{facility} '#{line}' \n"
unless o.has_key?( fileName)
o[fileName][facility] += 1
fd_to_file_name.delete( fd) if facility == 'close'
end
elsif line =~ %r{ ^ (?:\d+ \s)? (poll)\(.*fd=(\d+) }x
facility, fd = $1, $2
if fd_to_file_name.has_key? fd
fileName = fd_to_file_name[fd]
raise "I'm confused about #{fd}, #{fileName}, #{facility} '#{line}' \n"
unless o.has_key?( fileName)
o[fileName][facility] += 1
end
elsif line =~ %r{ ^ (?:\d+ \s)? (select)\(.*\[(\d+(?:\ \d+)*)\] }x
facility, fd_list = $1, $2
fd_list.split.each do |fd|
if fd_to_file_name.has_key? fd
fileName = fd_to_file_name[fd]
raise "I'm confused about #{fd}, #{fileName}, #{facility} '#{line}' \n"
unless o.has_key?( fileName)
o[fileName][facility] += 1
end
end
elsif line =~ %r{ ^ (?:\d+ \s)?
(exec[a-z]*|utime|getcwd|mkdir|unlink|readlink|l?stat\d*|access|chmod) \(
"([^\"]+)" }x
facility, fileName = $1, $2
o[fileName][facility] += 1
elsif line =~ %r{ ^ (?:\d+ \s)? (rename|(?:sym)?link) \( "([^\"]+)", \s*
"([^\"]+)" }x
facility, left, right = $1, $2,$3
p line
o[left][facility] += 1
o[right][facility] += 1
elsif line =~ %r{ ^ (?:\d+ \s)?
(uname|brk|(?:old_)?mmap2?|set_thread_area|munmap|times|
set_tid_address|sched_setscheduler|rt_sig(?:action|procmask)|
get(?:rlimit|pid|(?:res)?[ug]id)\d*|getppid|nanosleep|_exit|setitimer|
futex|(?:sched_)?get_?priority(?:_min|_max)?|fork|clock_gettime|
socket|exit_group|gettimeofday|time|shm(?:at|get|ctl)|alarm|
umask|mprotect|clone|gete[ug]id\d*|getgroups32|sigreturn|waitpid|sigprocmask)
\( }x
facility = $1
o["__NO FILE NAME NEEDED__"][facility] += 1
elsif line =~ %r{ ^ (?:\d+ \s)? ( select \( 0), }x
facility = $1
o["__NO FILE NAME NEEDED__"][facility] += 1
elsif line =~ %r{ ^ (?:\d+ \s)? ( sigaction ) \( (SIG[A-Z]+), }x
facility = $1
alarm = $2
o[alarm][facility] += 1
elsif line =~ %r{ ^ (?:\d+ \s)? (pipe) \(\[(\d+), \s* (\d+) \] \) }x
facility, left, right = $1, $2, $3
left = "__pipe_#{left}"
right = "__pipe_#{right}"
o[left][facility] += 1
fd_to_file_name[fd] = left
o[right][facility] += 1
fd_to_file_name[fd] = right
elsif line =~ %r{ ^ (?:\d+ \s)? ---\ (SIG(?:ALRM|INT|IO)) }x
sig = $1
o["__NO FILE NAME NEEDED__"][sig] += 1
elsif line =~ %r{ ^ (?:\d+ \s)? <\.\.\.\
((?:read|write|select|futex|brk|gettimeofday|clock_gettime)\ resumed)> }x
sig = $1.sub(/\s+/, '_')
o["__NO FILE NAME NEEDED__"][sig] += 1
else
puts "Unhandled #{line}"
end
end
o.keys.sort.each do |file|
printf "%-40s\t", file
o[file].keys.sort.each do |facility|
count = o[file][facility]
print facility
print "(#{count})" if count > 1
print ' '
end
puts
end