private void ClearDebugItem(GXDebugItem dbgItem) { dbgItem.MsgType = GXDebugMsgType.INVALID; dbgItem.Arg1 = 0; dbgItem.Arg2 = 0; dbgItem.ArgObj = null; }
private GXDebugItem NewInvalidItem() { GXDebugItem invalidItem = new GXDebugItem(); invalidItem.MsgType = GXDebugMsgType.INVALID; return(invalidItem); }
public GXDebugInfo(int SId, IGxContext context, KeyValuePair <int, int> dbgKey) { this.SId = SId; this.context = context; Key = dbgKey; LastItem = null; stopwatch = new Stopwatch(); }
public GXDebugItem ReadPgmTrace(GXDebugItem dbgItem, byte cmd) { dbgItem = dbgItem ?? new GXDebugItem(); dbgItem.MsgType = GXDebugMsgType.PGM_TRACE; dbgItem.DbgInfo = dbgItem.DbgInfo ?? new GXDebugInfoLocal(); dbgItem.ArgObj = null; GXDebugMsgType cmdMsgType = (GXDebugMsgType)cmd; bool hasSId = (cmd & 0x30) == GXDebugMsgType.TRACE_HAS_SID.ToByte(); bool hasLine1 = (cmd & 0x0F) == GXDebugMsgType.TRACE_HAS_LINE1.ToByte(); bool hasCol = cmdMsgType.HasFlag(GXDebugMsgType.TRACE_HAS_COL); dbgItem.Ticks = ReadScaledLong(); if (hasSId) { dbgItem.DbgInfo.SId = ReadVLUInt(); } else { switch ((cmd >> 4) & 0x3) { case 0: dbgItem.DbgInfo.SId = LastSId; break; case 1: dbgItem.DbgInfo.SId = LastSId + 1; break; case 2: dbgItem.DbgInfo.SId = LastSId - 1; break; } } if (hasLine1) { dbgItem.Arg1 = ReadVLUInt(); } else { byte difLine1 = (byte)(cmd & 0xF); if ((difLine1 & 0x08) == 0x08) { difLine1 |= 0xF0; } dbgItem.Arg1 = LastLine1 + (sbyte)difLine1; } if (hasCol) { dbgItem.Arg2 = ReadVLUInt(); } else { dbgItem.Arg2 = 0; } LastSId = dbgItem.DbgInfo.SId; LastLine1 = dbgItem.Arg1; return(dbgItem); }
private GXDebugManager() { Current = new GXDebugItem[BUFFER_INITIAL_SIZE]; Next = new GXDebugItem[BUFFER_INITIAL_SIZE]; for (int i = 0; i < BUFFER_INITIAL_SIZE; i++) { Current[i] = new GXDebugItem(); Next[i] = new GXDebugItem(); } SessionGuid = Guid.NewGuid(); waitSaveEvent = new AutoResetEvent(false); PushSystem((int)GXDebugMsgCode.INITIALIZE, DateTime.UtcNow); }
private GXDebugItem[] ReadItems(GXDebugStream stream, out Guid sessionGuid, out GXDebugGenId genId, IList <GXDebugError> errors) { sessionGuid = Guid.Empty; genId = GXDebugGenId.INVALID; stream.InitializeNewBlock(); if (!FindEscape(stream, GXDebugStream.ESCAPE.PROLOG, errors)) { return(null); } short versionAndGenId = stream.ReadVLUShort(); genId = (GXDebugGenId)(versionAndGenId & 0xF); short version = (short)(versionAndGenId >> 4); if (version != GXDebugManager.GXDEBUG_VERSION) { errors.Add(new GXDebugError(stream.Position, $"Cannot parse version { version } blocks")); FindEscape(stream, GXDebugStream.ESCAPE.EPILOG, errors); return(new GXDebugItem[0]); } int itemCount = stream.ReadVLUInt(); if (itemCount == 0) { errors.Add(new GXDebugError(stream.Position, $"Invalid block. Item count = 0")); FindEscape(stream, GXDebugStream.ESCAPE.EPILOG, errors); return(new GXDebugItem[0]); } byte[] guid = new byte[16]; sessionGuid = new Guid(stream.ReadFully(guid)); GXDebugItem[] items = new GXDebugItem[itemCount]; for (int idx = 0; idx < itemCount; idx++) { items[idx] = ReadItem(stream, errors); if (items[idx].MsgType == GXDebugMsgType.INVALID) { while (++idx < itemCount) { items[idx] = NewInvalidItem(); } break; } } FindEscape(stream, GXDebugStream.ESCAPE.EPILOG, errors); return(items); }
internal void TrkRng(int lineNro, int colNro, int lineNro2, int colNro2) { UpdateTicks(); LastItem = GXDebugManager.Instance.PushRange(this, lineNro, colNro, lineNro2, colNro2); stopwatch.Restart(); }
internal void Trk(int lineNro, int colNro = 0) { UpdateTicks(); LastItem = GXDebugManager.Instance.Push(this, lineNro, colNro); stopwatch.Restart(); }
private void mSave(object state1) { object[] state = state1 as object[]; GXDebugItem[] Data = state[0] as GXDebugItem[]; int saveTop = (int)state[1]; int saveCount = (int)state[2]; lock (mSaveLock) { int idx = 0; try { string FQFileName = Path.IsPathRooted(FileName) ? FileName : Path.Combine(GxContext.Current.GetPhysicalPath(), FileName); #pragma warning disable SCS0018 // Path traversal: injection possible in {1} argument passed to '{0}' using (GXDebugStream stream = new GXDebugStream(FQFileName, FileMode.Append)) #pragma warning restore SCS0018 // Path traversal: injection possible in {1} argument passed to '{0}' { stream.WriteHeader(SessionGuid, (short)(GXDEBUG_VERSION << 4 | GENERATOR_ID.ToByte()), saveCount); #if _DEBUG_DEBUGGER Console.WriteLine("mSave-" + saveTop); #endif for (; idx < saveTop; idx++) { GXDebugItem dbgItem = Data[idx]; #if _DEBUG_DEBUGGER Console.WriteLine($"item({idx}): { dbgItem }"); #endif switch (dbgItem.MsgType) { case GXDebugMsgType.SYSTEM: { stream.WriteByte((byte)(dbgItem.MsgType.ToByte() | ((GXDebugMsgCode)dbgItem.Arg1).ToByte())); switch ((GXDebugMsgCode)dbgItem.Arg1) { case GXDebugMsgCode.INITIALIZE: stream.WriteLong(((DateTime)dbgItem.ArgObj).ToUniversalTime().Ticks); break; case GXDebugMsgCode.OBJ_CLEANUP: stream.WriteVLUInt((int)dbgItem.ArgObj); break; case GXDebugMsgCode.EXIT: break; case GXDebugMsgCode.PGM_INFO: KeyValuePair <object, object> info = (KeyValuePair <object, object>)dbgItem.ArgObj; stream.WriteVLUInt(((KeyValuePair <int, int>)info.Key).Key); stream.WriteVLUInt(((KeyValuePair <int, int>)info.Key).Value); stream.WriteVLUInt(((KeyValuePair <int, long>)info.Value).Key); stream.WriteInt(((KeyValuePair <int, long>)info.Value).Value); break; default: throw new ArgumentException($"Invalid DbgItem: { dbgItem }"); } } break; case GXDebugMsgType.PGM_TRACE: { stream.WritePgmTrace(dbgItem.DbgInfo.SId, dbgItem.Arg1, dbgItem.Arg2, dbgItem.Ticks); } break; case GXDebugMsgType.PGM_TRACE_RANGE: case GXDebugMsgType.PGM_TRACE_RANGE_WITH_COLS: { stream.WriteByte(dbgItem.MsgType.ToByte()); stream.WriteVLUInt(dbgItem.DbgInfo.SId); stream.WriteVLUInt(dbgItem.Arg1); stream.WriteVLUInt(dbgItem.Arg2); if (dbgItem.MsgType == GXDebugMsgType.PGM_TRACE_RANGE_WITH_COLS) { stream.WriteVLUInt(((KeyValuePair <int, int>)dbgItem.ArgObj).Key); stream.WriteVLUInt(((KeyValuePair <int, int>)dbgItem.ArgObj).Value); } } break; case GXDebugMsgType.REGISTER_PGM: { stream.WriteByte(dbgItem.MsgType.ToByte()); stream.WriteVLUInt(dbgItem.DbgInfo.SId); stream.WriteVLUInt(dbgItem.Arg1); stream.WriteVLUInt(((KeyValuePair <int, int>)dbgItem.ArgObj).Key); stream.WriteVLUInt(((KeyValuePair <int, int>)dbgItem.ArgObj).Value); } break; case GXDebugMsgType.SKIP: continue; } ClearDebugItem(dbgItem); } } } catch (Exception ex) { GXLogging.Warn(log, $"GXDebugManager: Cannot write debug file", ex); } saving = false; waitSaveEvent.Set(); } }
private void Save(GXDebugItem[] ToSave, int saveTop = -1, bool saveInThread = true) { int saveCount = 0; if (saveTop == -1) { ToSave = Next; saveTop = ToSave.Length; for (int idx = 0; idx < saveTop; idx++) { if (ToSave[idx].Ticks == TICKS_NOT_SET) { GXDebugItem swap = ToSave[idx]; ToSave[idx] = Current[dbgIndex]; Current[dbgIndex] = swap; ClearDebugItem(ToSave[idx]); ToSave[idx].MsgType = GXDebugMsgType.SKIP; ToSave[idx].ArgObj = swap; dbgIndex++; if (dbgIndex == Current.Length) { int lastTop = Current.Length; GXDebugItem[] tempL = new GXDebugItem[lastTop + BUFFER_INITIAL_SIZE]; Array.Copy(Current, tempL, lastTop); Current = tempL; tempL = new GXDebugItem[lastTop + BUFFER_INITIAL_SIZE]; Array.Copy(Next, tempL, lastTop); Next = tempL; for (int i = lastTop; i < Current.Length; i++) { Current[i] = new GXDebugItem(); Next[i] = new GXDebugItem(); } } } else { saveCount++; } } } else if (saveTop == 0) { return; } else { saveCount = saveTop; } lock (mSaveLock) { Debug.Assert(!saving, "Already saving"); saving = true; } if (saveInThread) { ThreadPool.QueueUserWorkItem(mSave, new object[] { ToSave, saveTop, saveCount }); } else { mSave(new object[] { ToSave, saveTop, saveCount }); } }
private GXDebugItem mPush(GXDebugInfo dbgInfo, GXDebugMsgType msgType, int arg1, int arg2, object argObj = null) { lock (saveLock) { if (ToSave != null) { Save(ToSave); ToSave = null; } GXDebugItem currentItem = Current[dbgIndex]; currentItem.DbgInfo = dbgInfo; currentItem.MsgType = msgType; currentItem.Arg1 = arg1; currentItem.Arg2 = arg2; currentItem.ArgObj = argObj; switch (msgType) { case GXDebugMsgType.SYSTEM: { switch ((GXDebugMsgCode)arg1) { case GXDebugMsgCode.INITIALIZE: case GXDebugMsgCode.EXIT: case GXDebugMsgCode.OBJ_CLEANUP: case GXDebugMsgCode.PGM_INFO: currentItem.Ticks = TICKS_NOT_NEEDED; break; default: currentItem.Ticks = TICKS_NOT_SET; break; } } break; case GXDebugMsgType.REGISTER_PGM: { currentItem.Ticks = TICKS_NOT_NEEDED; } break; default: currentItem.Ticks = TICKS_NOT_SET; break; } dbgIndex++; if (dbgIndex == Current.Length) { bool mSaving = false; lock (mSaveLock) { mSaving = saving; } if (mSaving) { waitSaveEvent.WaitOne(); } ToSave = Current; GXDebugItem[] swap = Current; Current = Next; Next = swap; pgmInfoTable.Clear(); dbgIndex = 0; } return(currentItem); } }
private GXDebugItem ReadItem(GXDebugStream stream, IList <GXDebugError> errors) { int value; if ((value = stream.ReadByte()) == -1) { throw new EndOfStreamException(); } GXDebugItem dbgItem = new GXDebugItem(); if ((value & GXDebugMsgType.SYSTEM.ToByte()) == GXDebugMsgType.SYSTEM.ToByte()) { switch (value & 0xFC) { case 0xC0: { dbgItem.MsgType = GXDebugMsgType.REGISTER_PGM; dbgItem.DbgInfo = new GXDebugInfoLocal(); dbgItem.DbgInfo.SId = stream.ReadVLUInt(); dbgItem.Arg1 = stream.ReadVLUInt(); dbgItem.ArgObj = new KeyValuePair <int, int>(stream.ReadVLUInt(), stream.ReadVLUInt()); } break; case 0xA0: { dbgItem.MsgType = GXDebugMsgType.PGM_TRACE_RANGE; dbgItem.DbgInfo = new GXDebugInfoLocal(); dbgItem.DbgInfo.SId = stream.ReadVLUInt(); dbgItem.Arg1 = stream.ReadVLUInt(); dbgItem.Arg2 = stream.ReadVLUInt(); if ((value & GXDebugMsgType.PGM_TRACE_RANGE_WITH_COLS.ToByte()) == GXDebugMsgType.PGM_TRACE_RANGE_WITH_COLS.ToByte()) { dbgItem.ArgObj = new KeyValuePair <int, int>(stream.ReadVLUInt(), stream.ReadVLUInt()); } else { dbgItem.ArgObj = new KeyValuePair <int, int>(0, 0); } } break; case 0x80: { dbgItem.MsgType = GXDebugMsgType.SYSTEM; dbgItem.Arg1 = value & GXDebugMsgCode.MASK_BITS.ToByte(); switch ((GXDebugMsgCode)(dbgItem.Arg1)) { case GXDebugMsgCode.INITIALIZE: dbgItem.ArgObj = new DateTime(stream.ReadLong(), DateTimeKind.Utc); break; case GXDebugMsgCode.OBJ_CLEANUP: dbgItem.ArgObj = stream.ReadVLUInt(); break; case GXDebugMsgCode.PGM_INFO: { KeyValuePair <int, int> pgmKey = new KeyValuePair <int, int>(stream.ReadVLUInt(), stream.ReadVLUInt()); KeyValuePair <int, long> pgmInfo = new KeyValuePair <int, long>(stream.ReadVLUInt(), stream.ReadIntAsLong()); dbgItem.ArgObj = new KeyValuePair <object, object>(pgmKey, pgmInfo); } break; case GXDebugMsgCode.EXIT: break; default: dbgItem.MsgType = GXDebugMsgType.INVALID; errors.Add(new GXDebugError(stream.Position, $"Invalid Debug Item (type={ dbgItem.MsgType } - { value })")); break; } } break; default: dbgItem.MsgType = GXDebugMsgType.INVALID; errors.Add(new GXDebugError(stream.Position, $"Invalid Debug Item (type={ value })")); break; } } else { stream.ReadPgmTrace(dbgItem, (byte)value); } return(dbgItem); }