Skip to content

Commit 4cb4dc8

Browse files
committed
Opcode granularity in the execution of the graph. Also fixed executed graph edges
1 parent f4b5576 commit 4cb4dc8

File tree

2 files changed

+60
-15
lines changed

2 files changed

+60
-15
lines changed

src/main/java/net/nandgr/debugger/cfg/CFGCreatorDefault.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ private void checkChunksWithTrace(Map<Integer, BytecodeChunk> functionsChunks, M
6565
BytecodeChunk chunk = entry.getValue();
6666
OpcodeSource lastOpcode = chunk.getOpcodes().get(chunk.getOpcodes().size() - 1);
6767

68-
if (trace.containsKey(lastOpcode.getOffset()) && chunk.hasEmptyRelations() && isJumpOpcode(lastOpcode)) {
68+
if (trace.containsKey(lastOpcode.getOffset()) && hasAnyEmptyRelation(chunk) && isJumpOpcode(lastOpcode)) {
6969
DebugTraceTransactionLog jumpTrace = trace.get(lastOpcode.getOffset());
7070
Integer jumpDestination = Integer.valueOf(jumpTrace.getStack().get(jumpTrace.getStack().size() - 1), 16);
7171
BytecodeChunk destChunk;
@@ -74,11 +74,30 @@ private void checkChunksWithTrace(Map<Integer, BytecodeChunk> functionsChunks, M
7474
} else {
7575
destChunk = searchDestinationChunk(functionsChunks, jumpDestination);
7676
}
77-
chunk.setBranchA(destChunk);
77+
setBranch(chunk, destChunk);
7878
}
7979
}
8080
}
8181

82+
private static void setBranch(BytecodeChunk parent, BytecodeChunk child) {
83+
if (parent.getBranchA() == null && parent.getBranchB() == null) {
84+
parent.setBranchA(child);
85+
return;
86+
}
87+
if (parent.getBranchA() == null && parent.getBranchB().getId() != child.getId()) {
88+
parent.setBranchA(child);
89+
return;
90+
}
91+
if (parent.getBranchB() == null && parent.getBranchA().getId() != child.getId()) {
92+
parent.setBranchB(child);
93+
return;
94+
}
95+
}
96+
97+
private static boolean hasAnyEmptyRelation(BytecodeChunk chunk) {
98+
return chunk.getBranchA() == null || chunk.getBranchB() == null;
99+
}
100+
82101
private boolean isJumpOpcode(OpcodeSource lastOpcode) {
83102
return isJump(lastOpcode) || lastOpcode.getOpcode().equals(Opcodes.JUMPI);
84103
}

src/main/java/net/nandgr/debugger/cfg/graphviz/GraphVizCreator.java

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,9 @@ public String buildStringGraph() {
2626
.append("node [shape=plain fillcolor=\"#2A2A2A\" style=filled fontcolor=\"#12cc12\" fontname=\"Courier\"]").append(System.lineSeparator());
2727
for (BytecodeChunk bytecodeChunk : chunks.values()) {
2828
String coloredNode = "";
29-
OpcodeSource firstOpcode = bytecodeChunk.getOpcodes().get(0);
30-
if (Main.arguments.onlyTraceOpcodes && !trace.containsKey(firstOpcode.getOffset())) {
29+
if (Main.arguments.onlyTraceOpcodes && !chunkIsInTrace(bytecodeChunk)) {
3130
continue;
3231
}
33-
if (trace.containsKey(firstOpcode.getOffset())) {
34-
coloredNode = " fontcolor=\"red\" ";
35-
}
3632
sb.append(bytecodeChunk.getId()).append("[").append(coloredNode).append("label=").append(buildLabel(bytecodeChunk)).append("]").append(System.lineSeparator());
3733

3834
if (checkIfAppendBranch(bytecodeChunk.getBranchA())) {
@@ -46,28 +42,58 @@ public String buildStringGraph() {
4642
return sb.toString();
4743
}
4844

45+
private boolean chunkIsInTrace(BytecodeChunk chunk) {
46+
for (OpcodeSource opcodeSource : chunk.getOpcodes()) {
47+
if (trace.containsKey(opcodeSource.getOffset())) {
48+
return true;
49+
}
50+
}
51+
return false;
52+
}
53+
4954
private boolean checkIfAppendBranch(BytecodeChunk branch) {
5055
if (branch == null) {
5156
return false;
5257
}
5358
if (!Main.arguments.onlyTraceOpcodes) {
5459
return true;
5560
}
56-
OpcodeSource firstOpcode = branch.getOpcodes().get(0);
57-
return trace.containsKey(firstOpcode.getOffset());
61+
return chunkIsInTrace(branch);
5862
}
5963

6064
private String buildLabel(BytecodeChunk bytecodeChunk) {
6165
StringBuilder sb= new StringBuilder("< <TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">").append(System.lineSeparator());
6266
for (OpcodeSource opcodeSource : bytecodeChunk.getOpcodes()) {
67+
boolean isInTrace = trace.containsKey(opcodeSource.getOffset());
68+
6369
String id = opcodeSource.getOffset() + "#" + opcodeSource.getBegin() + "#" + opcodeSource.getEnd();
64-
sb.append("<TR><TD ID=\"").append(id).append("#offset#").append(contractName).append("\" HREF=\" \">0x")
65-
.append(String.format("%04X", opcodeSource.getOffset()))
66-
.append("</TD><TD ID=\"").append(id).append("#instr#").append(contractName).append("\" HREF=\" \">")
67-
.append(opcodeSource.getOpcode())
68-
.append("</TD>");
70+
sb.append("<TR><TD ID=\"").append(id).append("#offset#").append(contractName).append("\" HREF=\" \">");
71+
if (isInTrace) {
72+
sb.append("<font color=\"#ff1020\">");
73+
}
74+
sb.append("0x").append(String.format("%04X", opcodeSource.getOffset()));
75+
if (isInTrace) {
76+
sb.append("</font>");
77+
}
78+
sb.append("</TD><TD ID=\"").append(id).append("#instr#").append(contractName).append("\" HREF=\" \">");
79+
if (isInTrace) {
80+
sb.append("<font color=\"#ff1020\">");
81+
}
82+
sb.append(opcodeSource.getOpcode());
83+
if (isInTrace) {
84+
sb.append("</font>");
85+
}
86+
sb.append("</TD>");
6987
if (opcodeSource.getParameter() != null) {
70-
sb.append("<TD>0x").append(opcodeSource.getParameter().toString(16)).append("</TD>");
88+
sb.append("<TD>");
89+
if (isInTrace) {
90+
sb.append("<font color=\"#ff1020\">");
91+
}
92+
sb.append("0x").append(opcodeSource.getParameter().toString(16));
93+
if (isInTrace) {
94+
sb.append("</font>");
95+
}
96+
sb.append("</TD>");
7197
}
7298
sb.append("</TR>").append(System.lineSeparator());
7399
}

0 commit comments

Comments
 (0)