# -*- coding: utf-8 -*-
import re
import sys
import copy
import os
'''
脚本流程:
1. 用ps数据生成以线程id为key,进程名称为value的map:process_map;
2. 解析bufinfo数据,生成按线程分组的map:key为进程名称+线程名称+线程ID,value为该线程申请buffer size的相加;
3. 按申请size倒序解析thread_dma_buf_map,输出按线程分组的buffer申请数据。
'''
def main(fp_dma_buf_mem, fp_ps):
line_data_list = []
process_map = {}
thread_dma_buf_map = {}
thread_dma_buf_leak_map = {}
sum = 0
leak_sum = 0
with open(fp_ps, 'r') as f:
for line in f.readlines():
line_data_list = line.strip().split()
if len(line_data_list) < 9:
continue
if not line_data_list[1].isdigit():
continue
key = int(line_data_list[1])
if line_data_list[6] in ["fg","bg","ta"]:
value = line_data_list[7]
else:
value = line_data_list[6]
process_map[key] = value
f.close()
with open(fp_dma_buf_mem, 'r') as f:
for line in f.readlines():
line_data_list = line.strip().split()
if len(line_data_list) < 7:
continue
if not line_data_list[0].isdigit():
continue
if not line_data_list[5].isdigit():
continue
size = int(line_data_list[0])
pid = int(line_data_list[6])
name = line_data_list[4]
if pid in process_map:
key = "%s-%s-%d" % (process_map[pid], name, pid)
if key in thread_dma_buf_map:
thread_dma_buf_map[key] = thread_dma_buf_map[key] + int(size)
else:
thread_dma_buf_map[key] = int(size)
else:
key = "%s-%d" % (name, pid)
if key in thread_dma_buf_leak_map:
thread_dma_buf_leak_map[key] = thread_dma_buf_leak_map[key] + int(size)
else:
thread_dma_buf_leak_map[key] = int(size)
error_msg = "May be memory leak: %s-%d, size:%dKB" % (name, pid, int(size)/1024)
print(error_msg)
f.close()
fp_bufinfo_mem_out = os.path.splitext(fp_dma_buf_mem)[0] + "_out" + os.path.splitext(fp_dma_buf_mem)[1]
with open(fp_bufinfo_mem_out, 'w') as f:
for key,value in sorted(thread_dma_buf_map.items(), key = lambda x : x[1], reverse=True):
f.write("%s allocs %dKB, %dMB\n" % (key, value/1024, value/1024/1024))
sum += value
f.write('\n')
f.write('sum=%dKB, %dMB\n' % (sum/1024, sum/1024/1024))
f.write('\n')
f.write('-------------------------- \n')
f.write('\n')
for key,value in sorted(thread_dma_buf_leak_map.items(), key = lambda x : x[1], reverse=True):
f.write("%s leak %dKB, %dMB\n" % (key, value/1024, value/1024/1024))
leak_sum += value
f.write('\n')
f.write('leak_sum=%dKB, %dMB\n' % (leak_sum/1024, leak_sum/1024/1024))
f.close()
if __name__ == '__main__':
if len(sys.argv) != 3:
print ("Usage: python3 parse_dma_buf.py bufinfo.txt ps.txt")
exit(1)
main(sys.argv[1], sys.argv[2])