#!/usr/local/bin/ruby Event = Struct.new(:pidtid, :proc, :time, :type, :call) CallAvg = Struct.new(:call,:min,:max,:total,:calls) Call = Struct.new(:call,:elapsed) calls = Hash.new {|h,k| h[k] = CallAvg.new(k,99,0,0,0) } last_calls = {} file = ARGV.first file ||= 'ktrace.out' IO.popen("kdump -HEnsf #{file}") do |kdump| kdump.each_line do |event| bits = event.split(/\s+/, 7) _, pid, tid, process, time, type, call = *bits id = pid.to_i | (tid.to_i << 16) event = Event.new(id, process, time.to_f, type, call) case event.type when "CALL" last_calls[id] = event when "RET" next unless last_call = last_calls[id] c = calls[event.call.scan(/\S+/).first] c.calls += 1 elapsed = event.time - last_call.time c.total += elapsed c.max = elapsed if elapsed > c.max c.min = elapsed if elapsed < c.min end end end calls.sort {|a,b| b[1].total <=> a[1].total }.each do |r| c = r[1] puts "%12.12s: %2.3fs/%5d calls = %.3fs per call. Max=%.3fs Min=%.4fs" % [c.call,c.total,c.calls,c.total/c.calls,c.max,c.min] end