Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/java/erlyberly/CrashReport.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class CrashReport {

private static final OtpErlangAtom ATOM_LINE = OtpUtil.atom("line");

private final Map<Object, Object> crashProps;
private final Map<OtpErlangObject, OtpErlangObject> crashProps;

private final String registeredName;

Expand Down Expand Up @@ -89,7 +89,7 @@ <T> List<T> mapStackTraces(StackTraceFn<T> fn) {
OtpErlangList list = (OtpErlangList) argsOrArity;
arity = new OtpErlangLong(list.arity());
}
Map<Object, Object> fileLineProps = OtpUtil.propsToMap((OtpErlangList) tuple.elementAt(3));
Map<OtpErlangObject, OtpErlangObject> fileLineProps = OtpUtil.propsToMap((OtpErlangList) tuple.elementAt(3));
OtpErlangString file = (OtpErlangString) fileLineProps.get(ATOM_FILE);
OtpErlangLong line = (OtpErlangLong) fileLineProps.get(ATOM_LINE);

Expand Down
37 changes: 9 additions & 28 deletions src/main/java/erlyberly/DbgController.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

import com.ericsson.otp.erlang.OtpErlangException;
import com.ericsson.otp.erlang.OtpErlangList;
import com.ericsson.otp.erlang.OtpErlangTuple;

import erlyberly.node.OtpUtil;
import erlyberly.node.RpcCallback;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
Expand Down Expand Up @@ -55,8 +53,6 @@ public class DbgController implements Initializable {

private final ObservableList<TraceLog> traceLogs = FXCollections.observableArrayList();

private final ObservableList<ModFunc> traces = FXCollections.observableArrayList();

private final ObservableList<SeqTraceLog> seqTraces = FXCollections.observableArrayList();

private volatile boolean collectingSeqTraces;
Expand Down Expand Up @@ -102,16 +98,12 @@ public ObservableList<SeqTraceLog> getSeqTraceLogs() {
return seqTraces;
}

public boolean isTraced(ModFunc function) {
return traces.contains(function);
}

public void toggleTraceModFunc(ModFunc function) {
// if tracing is suspended, we can't apply a new trace because that will
// leave us in a state where some traces are active and others are not
if(ErlyBerly.nodeAPI().isSuspended())
return;
if(traces.contains(function))
if(ErlyBerly.nodeAPI().isTraced(function))
onRemoveTracer(null, function);
else
traceModFunc(function);
Expand All @@ -121,10 +113,6 @@ private void traceModFunc(ModFunc function) {
ErlyBerly.runIO(() -> {
try {
ErlyBerly.nodeAPI().startTrace(function, PrefBind.getMaxTraceQueueLengthConfig());

Platform.runLater(() -> { traces.add(function); });

ErlyBerly.nodeAPI().loadModuleRecords(OtpUtil.atom(function.getModuleName()));
}
catch (Exception ex) {
ex.printStackTrace();
Expand All @@ -136,8 +124,6 @@ private void onRemoveTracer(ActionEvent e, ModFunc function) {
ErlyBerly.runIO(() -> {
try {
ErlyBerly.nodeAPI().stopTrace(function);

Platform.runLater(() -> { traces.remove(function); });
}
catch (Exception ex) {
ex.printStackTrace();
Expand All @@ -146,23 +132,13 @@ private void onRemoveTracer(ActionEvent e, ModFunc function) {
}

public void reapplyTraces() {
final int maxTraceQueueLengthConfig = PrefBind.getMaxTraceQueueLengthConfig();
final ArrayList<ModFunc> tracesCopy = new ArrayList<ModFunc>(traces);
ErlyBerly.runIO(() -> {
for (ModFunc function : tracesCopy) {
try {
ErlyBerly.nodeAPI().startTrace(function, maxTraceQueueLengthConfig);
}
catch (Exception e) {
e.printStackTrace();
Platform.runLater(() -> { traces.remove(function); });
}
}
erlyberly.ErlyBerly.nodeAPI().reapplyTraces();
});
}

public void addTraceListener(InvalidationListener listener) {
traces.addListener(listener);
ErlyBerly.nodeAPI().addTraceListener(listener);
}

public void requestModFuncs(RpcCallback<OtpErlangList> rpcCallback) {
Expand Down Expand Up @@ -226,7 +202,7 @@ public GetModulesThread(RpcCallback<OtpErlangList> anRpcCallback) {
@Override
public void run() {
try {
OtpErlangList functions = ErlyBerly.nodeAPI().requestFunctions();
OtpErlangList functions = ErlyBerly.nodeAPI().allModuleFunctions();
Platform.runLater(() -> { rpcCallback.callback(functions); });
}
catch (Exception e) {
Expand All @@ -238,6 +214,7 @@ public void run() {
public String moduleFunctionSourceCode(String module, String function, Integer arity) throws IOException, OtpErlangException {
return ErlyBerly.nodeAPI().moduleFunctionSourceCode(module, function, arity);
}

public String moduleFunctionSourceCode(String module) throws IOException, OtpErlangException {
return ErlyBerly.nodeAPI().moduleFunctionSourceCode(module);
}
Expand All @@ -246,6 +223,7 @@ public String moduleFunctionAbstCode(String module) throws IOException, OtpErlan
String moduleCode = ErlyBerly.nodeAPI().moduleFunctionAbstractCode(module);
return moduleCode;
}

public String moduleFunctionAbstCode(String module, String function, Integer arity) throws IOException, OtpErlangException {
String moduleCode = ErlyBerly.nodeAPI().moduleFunctionAbstractCode(module, function, arity);
return moduleCode;
Expand All @@ -255,4 +233,7 @@ public void setModuleLoadedCallback(RpcCallback<OtpErlangTuple> moduleLoadedCall
ErlyBerly.nodeAPI().setModuleLoadedCallback(moduleLoadedCallback);
}

public boolean isTraced(ModFunc function) {
return ErlyBerly.nodeAPI().isTraced(function);
}
}
44 changes: 37 additions & 7 deletions src/main/java/erlyberly/DbgTraceView.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,9 @@ private void putTraceContextMenu() {
private void onTraceClicked(MouseEvent me) {
if(me.getButton().equals(MouseButton.PRIMARY) && me.getClickCount() == 2) {
TraceLog selectedItem = tracesBox.getSelectionModel().getSelectedItem();

if(selectedItem != null && selectedItem != null) {
// some items may not traces, they might be node down messages for example
boolean isActualTrace = !"".equals(selectedItem.getArgs());
if(selectedItem != null && selectedItem != null && isActualTrace) {
showTraceTermView(selectedItem);
}
}
Expand Down Expand Up @@ -221,14 +222,15 @@ private void showTraceTermView(final TraceLog traceLog) {
OtpErlangAtom moduleName = OtpUtil.atom(traceLog.getModFunc().getModuleName());

if(result != null) {
resultTermsTreeView.populateFromTerm(moduleName, traceLog.getResultFromMap());
resultTermsTreeView.populateFromTerm(moduleName, result);
}
else {
// the result may be receievd while the term view is open so put a listen
// on the result property and show it if is set
WeakChangeListener<Boolean> listener = new WeakChangeListener<Boolean>((o, oldV, newV) -> {
if(newV)
resultTermsTreeView.populateFromTerm(traceLog.getResultFromMap());
});

traceLog.isCompleteProperty().addListener(listener);
}

Expand All @@ -246,9 +248,32 @@ private void showTraceTermView(final TraceLog traceLog) {

StackTraceView stackTraceView;
stackTraceView = new StackTraceView();
stackTraceView.populateFromMfaList(traceLog.getStackTrace());
String stackTraceTitle = "Stack Trace (" + traceLog.getStackTrace().arity() + ")";
TitledPane titledPane = new TitledPane(stackTraceTitle, stackTraceView);

TitledPane titledPane;
titledPane = new TitledPane("No Stack Trace", stackTraceView);
if(traceLog.getStackTrace() != null) {
applyStackTraceOnView(traceLog, stackTraceView, titledPane);
}
else {
ErlyBerly.runIO(() -> {
OtpErlangList stackTrace;
try {
// if the stack trace is null then send the stack trace binary that we
// receive in the trace tuple to the remote node so that it can be decoded
// since we don't want to rewrite that logic in java. Once we receive the
// stack trace as a list we can set the binary to null so it can be gc'ed
stackTrace = ErlyBerly.nodeAPI().stak(traceLog.getStackTraceBinary());
Platform.runLater(() -> {
traceLog.setStackTrace(stackTrace);
traceLog.setStackTraceBinary(null);
applyStackTraceOnView(traceLog, stackTraceView, titledPane);
});
}
catch (Exception e) {
e.printStackTrace();
}
});
}
titledPane.setExpanded(!stackTraceView.isStackTracesEmpty());
splitPaneH = new SplitPane();
splitPaneH.setOrientation(Orientation.VERTICAL);
Expand All @@ -261,6 +286,11 @@ private void showTraceTermView(final TraceLog traceLog) {
ErlyBerly.showPane(sb.toString(), ErlyBerly.wrapInPane(splitPaneH));
}

private void applyStackTraceOnView(final TraceLog traceLog, StackTraceView stackTraceView, TitledPane titledPane) {
stackTraceView.populateFromMfaList(traceLog.getStackTrace());
titledPane.setText("Stack Trace (" + traceLog.getStackTrace().arity() + ")");
}

private Node labelledTreeView(String label, TermTreeView node) {
return new VBox(new Label(label), node);
}
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/erlyberly/ErlyBerly.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,16 @@ public static void main(String[] args) throws Exception {
}

public static void runIO(Runnable runnable) {
IO_EXECUTOR.execute(runnable);
IO_EXECUTOR.execute(() -> {
try {
runnable.run();
}
catch(Exception e) {
// print here or no console output is written at all
e.printStackTrace();
throw e;
}
});
}

public static void runIOAndWait(Runnable runnable) {
Expand All @@ -93,6 +102,7 @@ public static void runIOAndWait(Runnable runnable) {
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/main/java/erlyberly/ProcInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.ericsson.otp.erlang.OtpErlangAtom;
import com.ericsson.otp.erlang.OtpErlangList;
import com.ericsson.otp.erlang.OtpErlangLong;
import com.ericsson.otp.erlang.OtpErlangObject;
import com.ericsson.otp.erlang.OtpErlangString;

import javafx.beans.property.LongProperty;
Expand Down Expand Up @@ -165,7 +166,7 @@ public LongProperty reductionsProperty() {
return reductions;
}

public static ProcInfo toProcessInfo(Map<Object, Object> propList) {
public static ProcInfo toProcessInfo(Map<OtpErlangObject, OtpErlangObject> propList) {
Object processName = propList.get(REGISTERED_NAME_ATOM);
Object pid = ((OtpErlangString) propList.get(PID_ATOM)).stringValue();

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/erlyberly/SeqTraceLog.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public SeqTraceLog(Object msgType, Object serial, Object from, Object to, Object
this.timestamp = timestamp;
}

public static SeqTraceLog build(Map<Object, Object> props) {
public static SeqTraceLog build(Map<OtpErlangObject, OtpErlangObject> props) {
Object msgType = props.get(OtpUtil.atom("msg_type"));
Object serial = props.get(OtpUtil.atom("serial"));
Object from = props.get(OtpUtil.atom("from"));
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/erlyberly/StackTraceView.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ private ModFunc mfaToModFunc(OtpErlangAtom module, OtpErlangAtom function, OtpEr
}

public void populateFromMfaList(OtpErlangList stackTrace) {
if(stackTrace == null)
return;
try {
for (OtpErlangObject obj : stackTrace) {
if(obj instanceof OtpErlangString) {
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/erlyberly/TopBarView.java
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ public ErlangMemoryThread(ObservableList<PieChart.Data> thePieData) {
@Override
public void run() {
try {
final Map<Object, Object> erlangMemory = ErlyBerly.nodeAPI().erlangMemory();
final Map<OtpErlangObject, OtpErlangObject> erlangMemory = ErlyBerly.nodeAPI().erlangMemory();

// remove stats which are combinations of other stats
erlangMemory.remove(OtpUtil.atom("maximum"));
Expand All @@ -500,8 +500,8 @@ public void run() {
}
}

private void populatePieData(final Map<Object, Object> erlangMemory) {
for (Entry<Object, Object> entry : erlangMemory.entrySet()) {
private void populatePieData(final Map<OtpErlangObject, OtpErlangObject> erlangMemory) {
for (Entry<OtpErlangObject, OtpErlangObject> entry : erlangMemory.entrySet()) {
long kb = (long) (Double.parseDouble(entry.getValue().toString()) / 1024);
String label = entry.getKey().toString() + " (" + kb + " KB)";
pieData.add(new Data(label, kb));
Expand Down
35 changes: 35 additions & 0 deletions src/main/java/erlyberly/TraceList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package erlyberly;

import java.util.ArrayList;
import java.util.List;

import javafx.beans.InvalidationListener;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

/**
* A list of erlang traces.
*/
public class TraceList {
private final ObservableList<ModFunc> traces = FXCollections.observableArrayList();

public boolean isTraces(ModFunc function) {
return traces.contains(function);
}

public void remove(ModFunc mf) {
traces.remove(mf);
}

public void add(ModFunc mf) {
traces.add(mf);
}

public List<ModFunc> coptToList() {
return new ArrayList<ModFunc>(traces);
}

public void addListener(InvalidationListener listener) {
traces.addListener(listener);
}
}
Loading