google cpu profiler二进制结果读取
原文地址:http://www.708luo.com/?p=18
最近一段时间在google cpu profiler做性能热点采样。
用过的人都知道,cpu profiler产出的原始结果是二进制存储的。一般是得到这个结果再使用pprof工具去转化为人可读的文本形式的结果或者图片形式的结果。
但是最近有一些需求:
1. 对两个版本的profiler结果做比较
2. 根据历史数据,对单次profiler结果做一些分析,提示一些可以优化的点
要实现这两个功能,如果是基于pprof转化过的数据进行处理,总会有一些获取不到的信息。所以,最好是基于profiler的原始数据来完成上述的功能。
因为profiler的数据是二进制形式的,所以第一步先来做数据读取的操作。
google了一把,找到了一个profiler数据格式说明:http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile-fileformat.html。
有了这个说明,读取这个数据就方便了,写了个python实现,如下:
g_offset = 0
def Print(msg):
print time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()), " %s"%msg
def unpack_buff(fmt,buff):
global g_offset
last = g_offset+struct.calcsize(fmt)
tp = struct.unpack(fmt,buff[g_offset:last])
g_offset = last
return tp
def unpack_profile_header(buff):
Print("Unpack profile data header begin...")
tp = unpack_buff("<5Q",buff)
Print("Unpack profile data header succeed!")
return tp
def unpack_records(buff):
Print("Unpack sample records begin...")
records = []
while True:
tp = unpack_buff("<2Q",buff)
deep = tp[1]
fmt = "<%sQ" % deep
address_tp = unpack_buff(fmt,buff)
if address_tp[0] == 0:
break
x_address_tp = [ "%016x"%addr for addr in address_tp[1:] ]
record = [tp[0],tp[1],x_address_tp]
records.append(record)
Print("Unpack sample records succeed!")
return records
def unpack_mapped_libs(buff):
Print("Unpack mapped libs info begin...")
global g_offset
string = str(buff[g_offset:])
map_list = string.split("\n")
Print("Unpack mapped libs info succeed!")
return map_list
def read_profile_data(buff):
Print("Read profile data begin...")
unpack_profile_header(buff)
records = unpack_records(buff)
mapped_libs = unpack_mapped_libs(buff)
Print("Read profile data succeed!")
return records,mapped_libs
def main():
global g_profile_data_file
if not os.path.exists(g_profile_data_file):
Print("profile data file[%s] does not exist!"%(g_profile_data_file))
return 1
if not os.path.exists(g_execute_file):
Print("executable file[%s] does not exist!"%(g_execute_file))
return 1
bin_buff = None
with open(g_profile_data_file,"rb") as fd:
bin_buff = fd.read()
records,mapped_libs = read_profile_data(bin_buff)
浙公网安备 33010602011771号