/src/python/datatraces.py

https://gitlab.com/admin-github-cloud/jalangi2 · Python · 177 lines · 136 code · 38 blank · 3 comment · 27 complexity · e3416909c10be983e6732deedb536bd8 MD5 · raw file

  1. import collections
  2. import csv, json
  3. from collections import namedtuple
  4. strings = [] # IDX -> STRING
  5. source_map = {} # SSID -> IID -> [LINE_START, COL_START, LINE_END, COL_END]
  6. def main(trace_csv_file = "trace.log", strings_json_file = "strings.json", source_map_json_file = "smap.json") :
  7. global strings, source_map
  8. with open(source_map_json_file) as source_map_json:
  9. source_map = json.load(source_map_json)
  10. with open(strings_json_file) as strings_json:
  11. strings = json.load(strings_json)
  12. with open(trace_csv_file) as trace_csv:
  13. trace_reader = csv.reader(trace_csv)
  14. for row in trace_reader:
  15. handle_row(row)
  16. Mem = namedtuple('Mem', ['oid', 'offset'])
  17. Loc = namedtuple('Loc', ['sid', 'iid'])
  18. Val = namedtuple('Val', ['type', 'value'])
  19. def string(idx):
  20. return strings[int(idx)-1]
  21. def make_loc(sid, iid):
  22. return Loc(sid, iid)
  23. def make_val(type, value):
  24. return Val(type, value)
  25. def make_mem(ofid, offset):
  26. return None if ofid == "0" else Mem(ofid, offset)
  27. def str_loc(loc):
  28. (sid, iid) = loc
  29. if len(source_map) == 1:
  30. return "Line " + str(source_map[sid][iid][0]) if iid in source_map[sid] else "IID " + iid
  31. else:
  32. return source_map[sid][originalSourceFile] + ":" + str(source_map[sid][iid][0])
  33. def str_mem(mem) :
  34. if mem == None :
  35. return "undefined"
  36. else :
  37. (oid, offset) = mem
  38. return oid + "." + string(offset)
  39. def str_val(val) :
  40. (type, value) = val
  41. return type + ":" + value
  42. def handle_row(row) :
  43. if row[0] == "R" :
  44. handle_read(sid=row[1], iid=row[2], fid=row[3], offset=row[4], value=row[5], type=row[6])
  45. elif row[0] == "W" :
  46. handle_write(sid=row[1], iid=row[2], fid=row[3], offset=row[4], value=row[5], type=row[6])
  47. elif row[0] == "G":
  48. handle_getfield(sid=row[1], iid=row[2], rid=row[3], oid=row[4], offset=row[5], value=row[6], type=row[7])
  49. elif row[0] == "P":
  50. handle_putfield(sid=row[1], iid=row[2], rid=row[3], oid=row[4], offset=row[5], value=row[6], type=row[7])
  51. elif row[0] == "C":
  52. handle_call(sid=row[1], iid=row[2], oid=row[3], fid=row[4])
  53. elif row[0] == "E":
  54. handle_return(sid=row[1], iid=row[2], value=row[3], type=row[4])
  55. def handle_read(sid, iid, fid, offset, type, value):
  56. loc = make_loc(sid, iid)
  57. mem = make_mem(fid, offset)
  58. val = make_val(type, value)
  59. read_mem(mem, loc, val)
  60. pass
  61. def handle_write(sid, iid, fid, offset, type, value):
  62. loc = make_loc(sid, iid)
  63. mem = make_mem(fid, offset)
  64. val = make_val(type, value)
  65. write_mem(mem, loc, val)
  66. pass
  67. def handle_getfield(sid, iid, rid, oid, offset, type, value):
  68. loc = make_loc(sid, iid)
  69. mem = make_mem(oid, offset)
  70. val = make_val(type, value)
  71. read_mem(mem, loc, val)
  72. pass
  73. def handle_putfield(sid, iid, rid, oid, offset, type, value):
  74. loc = make_loc(sid, iid)
  75. mem = make_mem(oid, offset)
  76. val = make_val(type, value)
  77. write_mem(mem, loc, val)
  78. pass
  79. def handle_call(sid, iid, oid, fid):
  80. loc = make_loc(sid, iid)
  81. push_sets()
  82. pass
  83. def handle_return(sid, iid, type, value):
  84. loc = make_loc(sid, iid)
  85. val = make_val(type, value)
  86. pop_sets()
  87. pass
  88. read_sets_stack = [] # MEM -> [LOC X VAL] // List of reads-before-writes to a memory address
  89. write_sets_stack = [] # MEM -> LOC X VAL // The last write to a memory address
  90. def read_set() :
  91. return read_sets_stack[-1]
  92. def write_set():
  93. return write_sets_stack[-1]
  94. def push_sets():
  95. read_sets_stack.append({})
  96. write_sets_stack.append({})
  97. def pop_sets():
  98. callee_read_set = read_sets_stack.pop()
  99. caller_read_set = read_sets_stack[-1]
  100. callee_write_set = write_sets_stack.pop()
  101. caller_write_set = write_sets_stack[-1]
  102. # print callee_read_set, caller_write_set
  103. # Collect all callee's reads into caller's reads, if not written in caller
  104. for mem in callee_read_set:
  105. if not mem in caller_write_set:
  106. if not mem in caller_read_set:
  107. caller_read_set[mem] = []
  108. caller_read_set[mem].extend(callee_read_set[mem])
  109. # Overwrite all of callee's last-writes into caller's last-writes
  110. for mem in callee_write_set:
  111. caller_write_set[mem] = callee_write_set[mem]
  112. def read_mem(mem, loc, val) :
  113. rs = read_set()
  114. ws = write_set()
  115. if not mem in ws :
  116. if not mem in rs :
  117. rs[mem] = []
  118. rs[mem].append((loc, val))
  119. def write_mem(mem, loc, val) :
  120. ws = write_set()
  121. ws[mem] = (loc, val)
  122. def print_read_set(rs, tabs=0) :
  123. for mem in rs:
  124. print " "*tabs + "Reads of " + str_mem(mem)
  125. tabs += 1
  126. for (loc, val) in rs[mem]:
  127. print " "*tabs + str_loc(loc) + " = " + str_val(val)
  128. tabs -= 1
  129. def print_write_set(ws, tabs=0) :
  130. for mem in ws:
  131. print " "*tabs + "Last Write of " + str_mem(mem)
  132. tabs += 1
  133. (loc, val) = ws[mem]
  134. print " "*tabs + str_loc(loc) + " = " + str_val(val)
  135. tabs -= 1
  136. push_sets()
  137. main()
  138. print_read_set(read_set())
  139. print_write_set(write_set())