add remote debug

This commit is contained in:
CaiHQ 2022-09-02 21:29:19 +08:00
parent ca9c51e1bc
commit 8ce956a5c7
7 changed files with 92 additions and 97 deletions

View File

@ -24,6 +24,7 @@ import org.bdware.sc.util.JsonUtil;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.*; import java.util.*;
@ -31,7 +32,6 @@ public class ContractClient {
private static final Logger LOGGER = LogManager.getLogger(ContractClient.class); private static final Logger LOGGER = LogManager.getLogger(ContractClient.class);
public static String cmi = ""; public static String cmi = "";
public ContractMeta contractMeta; public ContractMeta contractMeta;
public boolean isDebug;
transient SocketGet get; transient SocketGet get;
int port; int port;
String pid; String pid;
@ -196,7 +196,6 @@ public class ContractClient {
contractMeta.thisPermission = get.syncGet("", "showPermission", ""); contractMeta.thisPermission = get.syncGet("", "showPermission", "");
// LOGGER.info("initProps ---- position-----8"); // LOGGER.info("initProps ---- position-----8");
isRunning = true; isRunning = true;
contractMeta.isDebug = Boolean.parseBoolean(get.syncGet("", "getDebug", ""));
// LOGGER.info("initProps ---- position-----9"); // LOGGER.info("initProps ---- position-----9");
get.syncGet("", "registerMangerPort", ContractManager.cPort.getCMPort() + ""); get.syncGet("", "registerMangerPort", ContractManager.cPort.getCMPort() + "");
contractMeta.contract = contractMeta.contract =
@ -221,11 +220,9 @@ public class ContractClient {
public String startProcess(PrintStream ps) throws Exception { public String startProcess(PrintStream ps) throws Exception {
isRunning = false; isRunning = false;
port = -1; port = -1;
String darg = "-Djava.library.path="; String darg = "-Djava.library.path=";
String classpath; String classpath;
File jniPath; File jniPath;
if (ContractManager.yjsPath == null) { if (ContractManager.yjsPath == null) {
jniPath = new File("./jni/"); jniPath = new File("./jni/");
classpath = System.getProperty("java.class.path"); classpath = System.getProperty("java.class.path");
@ -233,7 +230,6 @@ public class ContractClient {
classpath = ContractManager.yjsPath; classpath = ContractManager.yjsPath;
jniPath = new File(classpath).getParentFile(); jniPath = new File(classpath).getParentFile();
} }
String osJni = ((HardwareInfo.type == OSType.linux) ? "/jni/linux" : "/jni/mac"); String osJni = ((HardwareInfo.type == OSType.linux) ? "/jni/linux" : "/jni/mac");
darg += jniPath.getAbsolutePath() + osJni; darg += jniPath.getAbsolutePath() + osJni;
if (!new File(classpath).exists()) { if (!new File(classpath).exists()) {
@ -249,39 +245,63 @@ public class ContractClient {
new JsonPrimitive("incorrect path: yjs.jar, missing libs")); new JsonPrimitive("incorrect path: yjs.jar, missing libs"));
return JsonUtil.toJson(r); return JsonUtil.toJson(r);
} }
// ProcessBuilder builder =
// new ProcessBuilder(
// "java",
// "-Dfile.encoding=UTF-8",
// darg,
// "-cp",
// jniPath.getAbsolutePath() + "/libs/*:" + classpath,
// "org.bdware.sc.ContractProcess",
// "-port=" + cPort.getPort());
int startPort = ContractManager.cPort.getPortAndInc(); int startPort = ContractManager.cPort.getPortAndInc();
//(isDebug ? "-Dlog4j.configurationFile=./log4j2.debug.properties" : ""), List<String> pbParameters = new ArrayList<>();
ProcessBuilder builder = pbParameters.add("java");
new ProcessBuilder( pbParameters.add("-Dfile.encoding=UTF-8");
"java", pbParameters.add(darg);
"-Dfile.encoding=UTF-8", if (contractMeta.contract.getRemoteDebugPort() != 0) {
darg, pbParameters.add(String.format("-agentlib:jdwp=transport=dt_socket,address=%d,server=y,suspend=n", contractMeta.contract.getRemoteDebugPort()));
"-jar", }
classpath, if (contractMeta.contract.isDebug()) {
"-port=" + startPort, pbParameters.add("-Dlog4j.configurationFile=./log4j2.debug.properties");
"-cmi=" + cmi, // cmi 区分不同CM的cp } else {
(isDebug ? "-debug" : "")); pbParameters.add("-Dlog4j.configurationFile=./log4j2.properties");
}
pbParameters.add("-jar");
pbParameters.add(classpath);
pbParameters.add("-port=" + startPort);
pbParameters.add("-cmi=" + cmi);
if (contractMeta.contract.isDebug())
pbParameters.add("-debug");
ProcessBuilder builder;
String[] result = new String[pbParameters.size()];
pbParameters.toArray(result);
Constructor<ProcessBuilder> pbc = ProcessBuilder.class.getDeclaredConstructor(String[].class);
builder = pbc.newInstance(new Object[]{result});
// if (remoteDebug.length() == 0)
// builder =
// new ProcessBuilder(
// "java",
// "-Dfile.encoding=UTF-8",
// darg,
// "-jar",
// classpath,
// "-port=" + startPort,
// "-cmi=" + cmi, // cmi 区分不同CM的cp
// (isDebug ? "-debug" : ""));
// else
// builder =
//
// new ProcessBuilder(
// "java",
// "-Dfile.encoding=UTF-8",
// darg, remoteDebug,
// "-jar",
// classpath,
// "-port=" + startPort,
// "-cmi=" + cmi, // cmi 区分不同CM的cp
// (isDebug ? "-debug" : ""));
File directory = new File("./"); File directory = new File("./");
LOGGER.debug("[CMD] path: " + directory.getAbsolutePath()); LOGGER.debug("[CMD] path: " + directory.getAbsolutePath());
LOGGER.debug(JsonUtil.toPrettyJson(builder.command())); LOGGER.debug(JsonUtil.toPrettyJson(builder.command()));
Map<String, String> map = builder.environment(); Map<String, String> map = builder.environment();
map.put("java.library.path", jniPath.getAbsolutePath() + osJni); map.put("java.library.path", jniPath.getAbsolutePath() + osJni);
builder.directory(directory); builder.directory(directory);
LOGGER.debug("start process:"); LOGGER.debug("start process:");
process = builder.start(); process = builder.start();
this.pid = getPid(process); this.pid = getPid(process);
LOGGER.info("[CP PPID] " + pid); LOGGER.info("[CP PPID] " + pid);
PrintStream printStream = new PrintStream(process.getOutputStream()); PrintStream printStream = new PrintStream(process.getOutputStream());
@ -318,7 +338,7 @@ public class ContractClient {
ContractManager.cPort.updateDb(port, true); ContractManager.cPort.updateDb(port, true);
get = new SocketGet("127.0.0.1", port); get = new SocketGet("127.0.0.1", port);
get.syncGet("", "setDBInfo", ContractManager.dbPath); get.syncGet("", "setDBInfo", ContractManager.dbPath);
if (isDebug || get != null) { if (contractMeta.contract.isDebug() || get != null) {
String tagA = (ps == System.out ? "[Contract_" + port + "_out] " : ""); String tagA = (ps == System.out ? "[Contract_" + port + "_out] " : "");
String tagB = (ps == System.out ? "[Contract_" + port + "_err] " : ""); String tagB = (ps == System.out ? "[Contract_" + port + "_err] " : "");
outputTracer.track(process, sc, tagA, ps); outputTracer.track(process, sc, tagA, ps);
@ -335,9 +355,11 @@ public class ContractClient {
if (multiContractMeta != null && multiContractMeta.getMembers() != null) { if (multiContractMeta != null && multiContractMeta.getMembers() != null) {
String setMemberResult = get.syncGet( String setMemberResult = get.syncGet(
"", "setMembers", JsonUtil.toJson(multiContractMeta.getMembers())); "", "setMembers", JsonUtil.toJson(multiContractMeta.getMembers()));
LOGGER.debug("setMember:" + setMemberResult); LOGGER.info("setMember:" + setMemberResult);
} else {
LOGGER.info("setMember ignore, meta:" + (multiContractMeta == null) + (multiContractMeta == null ? "NULL" : " members:" + multiContractMeta.getMembers()));
} }
if (isBundlePath(contractMeta.contract.getScriptStr())) { if (isBundlePath(contractMeta.contract.getScriptStr())) {
status = status =
get.syncGet( get.syncGet(
@ -450,10 +472,6 @@ public class ContractClient {
return contractMeta.logDetail.get(action); return contractMeta.logDetail.get(action);
} }
public boolean isDebug() {
return contractMeta.isDebug;
}
public long getTimes() { public long getTimes() {
return times; return times;
} }

View File

@ -465,14 +465,6 @@ public class ContractManager {
return statusRecorder.getContractClient(meta.id); return statusRecorder.getContractClient(meta.id);
} }
public String startContractAndRedirectWithDebug(Contract c) {
return startContractAndRedirect(c, System.out, null, true);
}
public String startContractAndRedirect(Contract c, PrintStream ps) {
return startContractAndRedirect(c, ps, null, false);
}
public String getContractStateful(String contractID) { public String getContractStateful(String contractID) {
ContractClient cc = getClient(contractID); ContractClient cc = getClient(contractID);
if (null == cc) { if (null == cc) {
@ -793,7 +785,7 @@ public class ContractManager {
addLocalContractLog(action, meta.contract.getID(), meta.name, meta.contract.getOwner()); addLocalContractLog(action, meta.contract.getID(), meta.name, meta.contract.getOwner());
} }
public String startContractAndRedirect(Contract c, PrintStream ps, String alias, boolean isDebug) { public String startContractAndRedirect(Contract c, PrintStream ps, String alias) {
long freeMemory = getFreeMemory(); long freeMemory = getFreeMemory();
if (statusRecorder.runningProcess.size() > 5 && (freeMemory < memoryLimit)) { if (statusRecorder.runningProcess.size() > 5 && (freeMemory < memoryLimit)) {
statusRecorder.hangLeastUsedContractProcess(); statusRecorder.hangLeastUsedContractProcess();
@ -821,51 +813,12 @@ public class ContractManager {
if (null == c.getOwner()) { if (null == c.getOwner()) {
c.setOwner(c.getPublicKey()); c.setOwner(c.getPublicKey());
} }
LOGGER.debug("contract pubKey: " + c.getPublicKey()); LOGGER.debug("contract pubKey: " + c.getPublicKey());
// 合约启动时读取Manifest文件设置合约DOI // 合约启动时读取Manifest文件设置合约DOI
setContractDOI(c); setContractDOI(c);
setContractStateful(c); setContractStateful(c);
// if (c.getDoipFlag()) {
// // 合约部署时更新合约HandleRecord
// long tmpStart = System.currentTimeMillis();
// try {
// if (c.getDOI() == null || c.getDOI().equals("")) {
// updateContractHandleRecord( // 创建DO
// c,
// new ResultCallback() {
// @Override
// public void onResult(String str) {
// c.setDOI(str);
// // c.setID(str);
// LOGGER.debug("contract DOI: " + c.getDOI());
// }
// });
// } else {
// if (findConflictOfDOI(c.getDOI())) {
// r = new ContractResult(Status.Error, "Duplicate contract
// DOI.");
// return JsonUtil.toJson(r);
// }
// }
// } catch (Exception e) {
// ByteArrayOutputStream bo = new ByteArrayOutputStream();
// e.printStackTrace(new PrintStream(bo));
// c.setDOI("registerFailed");
// }
// LOGGER.info("DOIP executeTime: " + (System.currentTimeMillis() -
// tmpStart));
// } else c.setDOI("registerDisabled");
// if (contracts.containsKey(c.getID())) {
// r = new ContractResult(Status.Error, "contract existed");
// return JsonUtil.toJson(r);
// }
ContractClient client = new ContractClient(c); ContractClient client = new ContractClient(c);
client.isDebug = isDebug;
String ret; String ret;
String conflictCheck; String conflictCheck;
addLocalContractLog("startContract", c.getID(), client.contractMeta.name, c.getOwner()); addLocalContractLog("startContract", c.getID(), client.contractMeta.name, c.getOwner());
@ -1054,7 +1007,7 @@ public class ContractManager {
} }
public String startContract(Contract c) { public String startContract(Contract c) {
return startContractAndRedirect(c, System.out); return startContractAndRedirect(c, System.out, null);
} }
public String queryDEPort(String contractID) { public String queryDEPort(String contractID) {
@ -1309,7 +1262,7 @@ public class ContractManager {
rcb.onResult(JsonUtil.parseObjectAsJsonObject(cr)); rcb.onResult(JsonUtil.parseObjectAsJsonObject(cr));
return; return;
} }
} else if (null != request.getPublicKey() && !request.verifySignature()) { } else if (null != request.getPublicKey() && request.getPublicKey().length() > 30 && !request.verifySignature()) {
request.setPublicKey(null); request.setPublicKey(null);
} }
} }
@ -1673,6 +1626,7 @@ public class ContractManager {
boolean isNodeManager = checkNodeManager(owner); boolean isNodeManager = checkNodeManager(owner);
List<ContractInfo> ret = new ArrayList<>(); List<ContractInfo> ret = new ArrayList<>();
for (ContractMeta client : statusRecorder.getStatus().values()) { for (ContractMeta client : statusRecorder.getStatus().values()) {
if (client.contract == null) continue;
if (!client.contract.getOwner().equals(owner) && !isNodeManager) { if (!client.contract.getOwner().equals(owner) && !isNodeManager) {
continue; continue;
} }
@ -1805,7 +1759,7 @@ public class ContractManager {
public String resetDebugFlag(String contractName, boolean isDebug) { public String resetDebugFlag(String contractName, boolean isDebug) {
ContractClient client = getByName(contractName); ContractClient client = getByName(contractName);
String result = client.get.syncGet("", "changeDebugFlag", String.valueOf(isDebug)); String result = client.get.syncGet("", "changeDebugFlag", String.valueOf(isDebug));
client.contractMeta.isDebug = isDebug; client.contractMeta.contract.setDebug(isDebug);
return result; return result;
} }
/* /*

View File

@ -1,5 +1,7 @@
package org.bdware.sc; package org.bdware.sc;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.sc.bean.Contract; import org.bdware.sc.bean.Contract;
import org.bdware.sc.bean.FunctionDesp; import org.bdware.sc.bean.FunctionDesp;
import org.bdware.sc.bean.IDSerializable; import org.bdware.sc.bean.IDSerializable;
@ -20,7 +22,6 @@ public class ContractMeta implements IDSerializable {
ContractStatusEnum status; ContractStatusEnum status;
String name; String name;
String id; String id;
boolean isDebug;
Map<String, REvent.REventSemantics> declaredEvents; Map<String, REvent.REventSemantics> declaredEvents;
List<FunctionDesp> exportedFunctions; List<FunctionDesp> exportedFunctions;
Map<String, String> logDetail; Map<String, String> logDetail;
@ -96,7 +97,7 @@ public class ContractMeta implements IDSerializable {
// public setMask(){} // public setMask(){}
public boolean getIsDebug() { public boolean getIsDebug() {
return isDebug; return contract.isDebug();
} }
public FunctionDesp getExportedFunction(String action) { public FunctionDesp getExportedFunction(String action) {
@ -124,9 +125,10 @@ public class ContractMeta implements IDSerializable {
contract = c; contract = c;
id = c.getID(); id = c.getID();
status = ContractStatusEnum.HANGED; status = ContractStatusEnum.HANGED;
isDebug = false;
} }
static Logger LOGGER = LogManager.getLogger(ContractMeta.class);
public void setContractExecutor(ContractExecutor executor) { public void setContractExecutor(ContractExecutor executor) {
this.contractExecutor = executor; this.contractExecutor = executor;
} }

View File

@ -95,7 +95,7 @@ public class ContractStatusRecorder extends StatusRecorder<ContractMeta> {
} }
private static String resumeStartContract(Contract contract) { private static String resumeStartContract(Contract contract) {
return ContractManager.instance.startContractAndRedirect(contract, null); return ContractManager.instance.startContractAndRedirect(contract, null, null);
} }
public boolean hasPID(int pid) { public boolean hasPID(int pid) {

View File

@ -31,12 +31,17 @@ public class MultiContractRecorder extends StatusRecorder<MultiContractMeta> {
public MultiContractMeta getMultiContractMeta(String idOrNameOrDOI) { public MultiContractMeta getMultiContractMeta(String idOrNameOrDOI) {
if (idOrNameOrDOI == null) return null; if (idOrNameOrDOI == null) return null;
ContractMeta meta = ContractManager.instance.statusRecorder.getContractMeta(idOrNameOrDOI); ContractMeta meta = ContractManager.instance.statusRecorder.getContractMeta(idOrNameOrDOI);
return getMultiContractMeta(meta);
}
public MultiContractMeta getMultiContractMeta(ContractMeta meta) {
if (meta == null) return null; if (meta == null) return null;
return getStatus().get(meta.id); return getStatus().get(meta.id);
} }
public MultiContractMeta createIfNotExist(String contractID) { public MultiContractMeta createIfNotExist(String contractID) {
MultiContractMeta ret = getMultiContractMeta(contractID); ContractMeta meta = ContractManager.instance.statusRecorder.createIfNotExist(contractID);
MultiContractMeta ret = getMultiContractMeta(meta);
if (null == ret) { if (null == ret) {
LOGGER.info("requests don't contain contract " + contractID); LOGGER.info("requests don't contain contract " + contractID);
ret = new MultiContractMeta(contractID); ret = new MultiContractMeta(contractID);

View File

@ -164,10 +164,6 @@ public class MultiContractMeta implements IDSerializable {
} }
return sb.toString(); return sb.toString();
} }
public void setMembers(String[] m) {
members = m;
}
public void setMembers(JsonArray members) { public void setMembers(JsonArray members) {
String[] copied = new String[members.size()]; String[] copied = new String[members.size()];
for (int i = 0; i < members.size(); i++) { for (int i = 0; i < members.size(); i++) {

View File

@ -0,0 +1,20 @@
package org.bdware.sc.test;
import com.google.gson.Gson;
import java.lang.reflect.Method;
public class ReflectionTest {
public static class Test {
public static void go(String... args) {
System.out.println(new Gson().toJson(args));
}
}
@org.junit.Test
public void go() throws Exception {
Method m = Test.class.getDeclaredMethod("go",String[].class);
String[] abc = new String[]{"ab", "cd"};
m.invoke(null, new Object[]{abc});
}
}