''' @brief Tool to process VM trace reports and generate callgrind-formatted output. ''' import kuroko import fileio def processFile(sourcePath: str, pid: int , cmd: str): '''@brief Process @p sourcePath from process @p pid with command @p cmd as a VM trace file.''' let funcs = {} with fileio.open(sourcePath,'r') as f: for line in f.readlines(): let callerFile, callerFunc, callerLine, calleeFile, calleeFunc, calleeLine, nsecs = line.split(' ') nsecs = float(nsecs) let data = funcs.get((callerFile,callerFunc),{}) let call = data.get((callerLine,calleeFile,calleeFunc,calleeLine),(0,0)) let out = (call[0] + 1, call[1] + nsecs) data[callerLine,calleeFile,calleeFunc,calleeLine] = out funcs[callerFile,callerFunc] = data let called = funcs.get((calleeFile,calleeFunc),{}) let times = called.get(None,(1,0)) called[None] = (calleeLine, times[1] + nsecs) funcs[calleeFile,calleeFunc] = called with fileio.open(f'callgrind.out.{pid}','w') as out: out.write('# callgrind format\n') out.write('creator: Kuroko\n') out.write('positions: line\n') out.write('events: nanoseconds\n') out.write(f'cmd: {cmd}\n\n') def defloat(f): let s = int(f) let n = str(int(f * 1000000000)) if len(n) > 9: n = n[-9:] let o = (str(s) + '0' * (9 - len(n)) + n).lstrip('0') return o if o else '0' def cleanfunc(func): for s in ['','','','','']: func = func.replace(s,'['+s[1:-1]+']') return func.replace('@','<') + '>' for key, value in funcs.items(): let sFile, sFunc = key out.write(f'fl={sFile}\n') out.write(f'fn={cleanfunc(sFunc)}\n') if not sFunc.startswith('(root)'): let startLine, totalNsecs = value[None] for k, v in value.items(): if not k: continue let sourceLine, file, func, destLine = k let count, nsecs = v totalNsecs -= nsecs out.write(f'{startLine} {defloat(totalNsecs)}\n') for k, v in value.items(): if not k: continue let sourceLine, file, func, destLine = k let count, totalNsecs = v if file != sFile: out.write(f'cfi={file}\n') out.write(f'cfn={cleanfunc(func)}\n') out.write(f'calls={count} {destLine}\n') out.write(f'{sourceLine} {defloat(totalNsecs)}\n') out.write('\n')