From ad199aad5c91667f404283d2a444301a0b607314 Mon Sep 17 00:00:00 2001 From: Gustavo Brown Date: Sat, 14 Oct 2023 00:18:58 -0300 Subject: [PATCH 1/2] GXDebugStream was being closed too instantly after creating it --- .../genexus/diagnostics/GXDebugManager.java | 132 +++++++++--------- 1 file changed, 68 insertions(+), 64 deletions(-) diff --git a/common/src/main/java/com/genexus/diagnostics/GXDebugManager.java b/common/src/main/java/com/genexus/diagnostics/GXDebugManager.java index 9dfd0a6b8..fb35d6498 100644 --- a/common/src/main/java/com/genexus/diagnostics/GXDebugManager.java +++ b/common/src/main/java/com/genexus/diagnostics/GXDebugManager.java @@ -54,7 +54,7 @@ private GXDebugManager() } sessionGuid = UUID.randomUUID(); lastSId = new AtomicInteger(); - executorService = new ThreadPoolExecutor(0, 1, 5, TimeUnit.MINUTES, new SynchronousQueue()); + executorService = new ThreadPoolExecutor(0, 1, 5, TimeUnit.MINUTES, new SynchronousQueue(), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy()); pushSystem(GXDebugMsgCode.INITIALIZE.toByteInt(), new Date()); } @@ -88,7 +88,7 @@ private int newSId() private GXDebugItem [] current, next, toSave; private boolean saving = false; - private int dbgIndex = 0; + private volatile int dbgIndex = 0; private final Object saveLock = new Object(); private final Object mSaveLock = new Object(); private final ConcurrentHashMap parentTable = new ConcurrentHashMap(); @@ -119,7 +119,7 @@ protected GXDebugItem pushRange(GXDebugInfo dbgInfo, int lineNro, int colNro, in else return mPush(dbgInfo, GXDebugMsgType.PGM_TRACE_RANGE, lineNro, lineNro2, null); } - private GXDebugItem mPush(GXDebugInfo dbgInfo, GXDebugMsgType msgType, int arg1, int arg2, Object argObj) + private GXDebugItem mPush(GXDebugInfo dbgInfo, GXDebugMsgType msgType, int arg1, int arg2, Object argObj) { synchronized (saveLock) { @@ -240,12 +240,13 @@ else if(saveTop == 0) executorService.execute(new Runnable(){public void run(){mSave(mToSave, mSaveTop, mSaveCount);}}); } else mSave(toSave, saveTop, saveCount ); - } + } protected void onExit(GXDebugInfo dbgInfo) { pushSystem(GXDebugMsgCode.EXIT.toByteInt()); save(); + executorService.shutdown(); } protected void onCleanup(GXDebugInfo dbgInfo) @@ -288,7 +289,7 @@ private void clearDebugItem(GXDebugItem dbgItem) private void mSave(GXDebugItem [] data, int saveTop, int saveCount) { - synchronized(mSaveLock) + synchronized(mSaveLock) { // Obtengo chunk a grabar int idx = 0; @@ -302,37 +303,38 @@ private void mSave(GXDebugItem [] data, int saveTop, int saveCount) for (; idx < saveTop; idx++) { GXDebugItem dbgItem = data[idx]; - switch (dbgItem.msgType) - { - case SYSTEM: - { - stream.writeByte((dbgItem.msgType.toByteInt() | (GXDebugMsgCode.valueOf(dbgItem.arg1).toByteInt()))); - switch (GXDebugMsgCode.valueOf(dbgItem.arg1)) - { - case INITIALIZE: - stream.writeLong(ToTicks((Date) dbgItem.argObj)); - break; - case OBJ_CLEANUP: - stream.writeVLUInt((Integer) dbgItem.argObj); - break; - case EXIT: + switch (dbgItem.msgType) + { + case SYSTEM: + { + stream.writeByte((dbgItem.msgType.toByteInt() | (GXDebugMsgCode.valueOf(dbgItem.arg1).toByteInt()))); + switch (GXDebugMsgCode.valueOf(dbgItem.arg1)) + { + case INITIALIZE: + stream.writeLong(ToTicks((Date) dbgItem.argObj)); + break; + case OBJ_CLEANUP: + stream.writeVLUInt((Integer) dbgItem.argObj); + break; + case EXIT: + break; case PGM_INFO: - Object [] info = (Object[])dbgItem.argObj; - stream.writeVLUInt(((IntPair)info[0]).left); - stream.writeVLUInt(((IntPair)info[0]).right); - stream.writeVLUInt(((PgmInfo)info[1]).dbgLines); - stream.writeInt(((PgmInfo)info[1]).hash); - break; - default: - throw new IllegalArgumentException(String.format("Invalid DbgItem: %s", dbgItem)); - } - } - break; - case PGM_TRACE: - { - stream.writePgmTrace(dbgItem.dbgInfo.sId, dbgItem.arg1, dbgItem.arg2, dbgItem.ticks); - } - break; + Object[] info = (Object[]) dbgItem.argObj; + stream.writeVLUInt(((IntPair) info[0]).left); + stream.writeVLUInt(((IntPair) info[0]).right); + stream.writeVLUInt(((PgmInfo) info[1]).dbgLines); + stream.writeInt(((PgmInfo) info[1]).hash); + break; + default: + throw new IllegalArgumentException(String.format("Invalid DbgItem: %s", dbgItem)); + } + } + break; + case PGM_TRACE: + { + stream.writePgmTrace(dbgItem.dbgInfo.sId, dbgItem.arg1, dbgItem.arg2, dbgItem.ticks); + } + break; case PGM_TRACE_RANGE: case PGM_TRACE_RANGE_WITH_COLS: { @@ -340,27 +342,27 @@ private void mSave(GXDebugItem [] data, int saveTop, int saveCount) stream.writeVLUInt(dbgItem.dbgInfo.sId); stream.writeVLUInt(dbgItem.arg1); stream.writeVLUInt(dbgItem.arg2); - if(dbgItem.msgType == GXDebugMsgType.PGM_TRACE_RANGE_WITH_COLS) + if (dbgItem.msgType == GXDebugMsgType.PGM_TRACE_RANGE_WITH_COLS) { - stream.writeVLUInt(((IntPair)dbgItem.argObj).left); - stream.writeVLUInt(((IntPair)dbgItem.argObj).right); + stream.writeVLUInt(((IntPair) dbgItem.argObj).left); + stream.writeVLUInt(((IntPair) dbgItem.argObj).right); } } break; - case REGISTER_PGM: - { - stream.writeByte(dbgItem.msgType.toByteInt()); - stream.writeVLUInt(dbgItem.dbgInfo.sId); - stream.writeVLUInt(dbgItem.arg1); - stream.writeVLUInt(((IntPair) dbgItem.argObj).left); - stream.writeVLUInt(((IntPair) dbgItem.argObj).right); - } - break; - case SKIP: - continue; - } - clearDebugItem(dbgItem); - } + case REGISTER_PGM: + { + stream.writeByte(dbgItem.msgType.toByteInt()); + stream.writeVLUInt(dbgItem.dbgInfo.sId); + stream.writeVLUInt(dbgItem.arg1); + stream.writeVLUInt(((IntPair) dbgItem.argObj).left); + stream.writeVLUInt(((IntPair) dbgItem.argObj).right); + } + break; + case SKIP: + continue; + } + clearDebugItem(dbgItem); + } } finally { if (stream != null) @@ -565,15 +567,12 @@ class ESCAPE static GXDebugStream getStream(String fileName) throws IOException { - try (FileOutputStream stream = new FileOutputStream(fileName, true)){ - return new GXDebugStream(new BufferedOutputStream(stream), stream.getChannel()); - } + return new GXDebugStream(fileName); } - private GXDebugStream(OutputStream stream, FileChannel channel) throws IOException + private GXDebugStream(String fileName) throws IOException { - this(stream); - channel.lock(); + this(new BufferedOutputStream(new FileOutputStream(fileName, true))); } GXDebugStream(OutputStream stream) @@ -588,8 +587,8 @@ private GXDebugStream(OutputStream stream, FileChannel channel) throws IOExcepti public void close() throws IOException { writeEpilog(); - super.close(); - } + super.close(); + } private void writeProlog(short version) throws IOException { @@ -610,7 +609,11 @@ public void write(byte[] data) throws IOException void writeRaw(byte[] data, int from, int length) throws IOException { - super.write(data, from, length); + if ((from | length | (data.length - (length + from)) | (from + length)) < 0) + throw new IndexOutOfBoundsException(); + + while (length-- > 0) + writeRaw(data[from++]); } void writeRaw(byte value) throws IOException @@ -625,16 +628,17 @@ public void write(byte[] data, int offset, int count) throws IOException writeByte(data[offset++]); } - private int last, lastLast; + private volatile int last, lastLast; @Override - public void write(int value)throws IOException + public void write(int value) throws IOException { writeByte(value); } void writeByte(int value) throws IOException { + value &= 0xFF; super.write(value); if (value == 0xFF && value == last && @@ -703,7 +707,7 @@ void writeInt(long value) throws IOException } } - private int LastSId, LastLine1; + private volatile int LastSId, LastLine1; void writePgmTrace(int SId, int line1, int col, long ticks) throws IOException { From 464a78993448fb70685b7f8d92de53de242a1382 Mon Sep 17 00:00:00 2001 From: Gustavo Brown Date: Sat, 14 Oct 2023 01:00:18 -0300 Subject: [PATCH 2/2] fix lint warnings --- .../genexus/diagnostics/GXDebugManager.java | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/common/src/main/java/com/genexus/diagnostics/GXDebugManager.java b/common/src/main/java/com/genexus/diagnostics/GXDebugManager.java index fb35d6498..a62a7f4ac 100644 --- a/common/src/main/java/com/genexus/diagnostics/GXDebugManager.java +++ b/common/src/main/java/com/genexus/diagnostics/GXDebugManager.java @@ -3,10 +3,9 @@ import com.genexus.ModelContext; import java.io.*; -import java.nio.channels.FileChannel; +import java.util.Date; import java.util.HashSet; import java.util.UUID; -import java.util.Date; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; @@ -37,7 +36,7 @@ public static GXDebugManager getInstance() return instance; } - private static int BUFFER_INITIAL_SIZE = 16383; + private static final int BUFFER_INITIAL_SIZE = 16383; private static final long TICKS_NOT_SET = Long.MAX_VALUE; private static final long TICKS_NOT_NEEDED = 0; private static String fileName = "gxperf.gxd"; @@ -54,7 +53,7 @@ private GXDebugManager() } sessionGuid = UUID.randomUUID(); lastSId = new AtomicInteger(); - executorService = new ThreadPoolExecutor(0, 1, 5, TimeUnit.MINUTES, new SynchronousQueue(), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy()); + executorService = new ThreadPoolExecutor(0, 1, 5, TimeUnit.MINUTES, new SynchronousQueue<>(), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy()); pushSystem(GXDebugMsgCode.INITIALIZE.toByteInt(), new Date()); } @@ -91,8 +90,8 @@ private int newSId() private volatile int dbgIndex = 0; private final Object saveLock = new Object(); private final Object mSaveLock = new Object(); - private final ConcurrentHashMap parentTable = new ConcurrentHashMap(); - private final HashSet pgmInfoTable = new HashSet(); + private final ConcurrentHashMap parentTable = new ConcurrentHashMap<>(); + private final HashSet pgmInfoTable = new HashSet<>(); private static ExecutorService executorService; @@ -125,7 +124,7 @@ private GXDebugItem mPush(GXDebugInfo dbgInfo, GXDebugMsgType msgType, int arg1, { if (toSave != null) { - save(toSave); + save(toSave, -1, true); toSave = null; } GXDebugItem currentItem = current[dbgIndex]; @@ -183,13 +182,9 @@ private GXDebugItem mPush(GXDebugInfo dbgInfo, GXDebugMsgType msgType, int arg1, } - private void save(GXDebugItem[] toSave) - { - save(toSave, -1, true); - } - private void save(GXDebugItem[] toSave, int saveTop, boolean saveInThread) { + // This method always runs inside the critical section defined by saveLock int saveCount = 0; if (saveTop == -1) { @@ -237,7 +232,7 @@ else if(saveTop == 0) final GXDebugItem[] mToSave = toSave; final int mSaveTop = saveTop; final int mSaveCount = saveCount; - executorService.execute(new Runnable(){public void run(){mSave(mToSave, mSaveTop, mSaveCount);}}); + executorService.execute(() -> mSave(mToSave, mSaveTop, mSaveCount)); } else mSave(toSave, saveTop, saveCount ); } @@ -271,7 +266,7 @@ private void save() { if (toSave != null) { - save(toSave); + save(toSave, -1, true); toSave = null; } save(current, dbgIndex, false); @@ -462,7 +457,7 @@ private int toByteInt() } - class GXDebugItem + static class GXDebugItem { GXDebugInfo dbgInfo; int arg1; @@ -480,7 +475,7 @@ public String toString() private String toStringTicks(){ return (msgType == GXDebugMsgType.PGM_TRACE ? String.format(" elapsed:%d", ticks) : ""); } } - class IntPair + static class IntPair { final int left; final int right; @@ -507,7 +502,7 @@ public boolean equals(Object o) } - class PgmInfo + static class PgmInfo { final int dbgLines; final long hash; @@ -554,7 +549,7 @@ public final void restart() static class GXDebugStream extends FilterOutputStream { - class ESCAPE + static class ESCAPE { static final byte PROLOG = 0; static final byte EPILOG = 1;