Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
debug_debug.h
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
20// $File: //depot/GeneralsMD/Staging/code/Libraries/Source/debug/debug_debug.h $
21// $Author: mhoffe $
22// $Revision: #1 $
23// $DateTime: 2003/07/03 11:55:26 $
24//
25// ©2003 Electronic Arts
26//
27// main Debug object (singleton)
29#ifdef _MSC_VER
30# pragma once
31#endif
32#ifndef DEBUG_DEBUG_H // Include guard
33#define DEBUG_DEBUG_H
34
35// this makes sure that whenever this header is included
36// the accompanying OBJ file is linked in as well
37#pragma comment(linker,"/include:___DebugIncludeInLink1")
38
44class Debug
45{
46 // necessary because all debug commands operate directly on this class
48
49 // necessary because exception handler needs direct access
51
52public:
53 enum
54 {
57 };
58
70 typedef bool (*HResultTranslator)(Debug &debug, long hresult, void *user);
71
82 class MemDump
83 {
84 // necessary because Debug needs access to the following private members
85 friend Debug;
86
87 const unsigned char *m_startPtr;
88 unsigned m_numItems;
89 unsigned m_bytePerItem;
90 bool m_absAddr;
91 bool m_withChars;
92
93 // constructor is private on purpose so that nobody can
94 // create instances of this class except the static functions
95 // provided herein
96 MemDump(const void *ptr, unsigned num, unsigned bpi, bool absAddr, bool withChars):
97 m_startPtr((const unsigned char *)ptr), m_numItems(num),
98 m_bytePerItem(bpi), m_absAddr(absAddr), m_withChars(withChars) {}
99 public:
100
108 static MemDump Raw(const void *startPtr, unsigned numItems, unsigned bytePerItem=1)
109 {
110 return MemDump(startPtr,numItems,bytePerItem,true,false);
111 }
112
120 static MemDump RawRel(const void *startPtr, unsigned numItems, unsigned bytePerItem=1)
121 {
122 return MemDump(startPtr,numItems,bytePerItem,false,false);
123 }
124
132 static MemDump Char(const void *startPtr, unsigned numItems, unsigned bytePerItem=1)
133 {
134 return MemDump(startPtr,numItems,bytePerItem,true,true);
135 }
136
144 static MemDump CharRel(const void *startPtr, unsigned numItems, unsigned bytePerItem=1)
145 {
146 return MemDump(startPtr,numItems,bytePerItem,false,true);
147 }
148 };
149
165 {
166 // necessary because Debug needs access to the following private members
167 friend Debug;
168
169 long m_hresult;
170
171 public:
172
178 explicit HResult(long hresult): m_hresult(hresult) {}
179 };
180
186 class LogDescription
187 {
188 // sorry, no copies or assignments
189 LogDescription(const LogDescription&);
190 LogDescription& operator=(const LogDescription&);
191
192 public:
193
201 LogDescription(const char *fileOrGroup, const char *description);
202 };
203
207 class Hex {};
208
210 Debug& operator<<(Hex &)
211 {
212 SetPrefixAndRadix("0x",16);
213 return *this;
214 }
215
219 class Dec {};
220
222 Debug& operator<<(Dec &)
223 {
224 SetPrefixAndRadix("",10);
225 return *this;
226 }
227
231 class Bin {};
232
234 Debug& operator<<(Bin &)
235 {
236 SetPrefixAndRadix("%",2);
237 return *this;
238 }
239
243 class Width
244 {
245 // necessary because Debug needs access to the following private members
246 friend Debug;
247
248 int m_width;
249
250 public:
252 explicit Width(int width): m_width(width) {}
253 };
254
256 Debug& operator<<(Width &w)
257 {
258 m_width=w.m_width;
259 return *this;
260 }
261
266 {
267 // necessary because Debug needs access to the following private members
268 friend Debug;
269
270 char m_fill;
271
272 public:
274 explicit FillChar(char ch=' '): m_fill(ch) {}
275 };
276
279 {
280 m_fillChar=c.m_fill;
281 return *this;
282 }
283
288 {
289 // necessary because Debug needs access to the following private members
290 friend Debug;
291
292 char m_char;
293 int m_count;
294
295 public:
297 explicit RepeatChar(char ch, int count): m_char(ch), m_count(count) {}
298 };
299
301 Debug& operator<<(RepeatChar &c);
302
309 class Format
310 {
311 // necessary because Debug needs access to the following private members
312 friend Debug;
313
314 // no CC, AOp
315 Format(const Format &);
316 Format& operator=(const Format&);
317
318 char m_buffer[512];
319
320 public:
322 explicit Format(const char *format, ...);
323 };
324
326 Debug& operator<<(const Format &f)
327 {
328 operator<<(f.m_buffer);
329 return *this;
330 }
331
332 // this is necessary because LogDescription needs to call AddLogGroup
333 friend class LogDescription;
334
339 ~Debug();
340
347 static void InstallExceptionHandler(void);
348
362 static bool SkipNext(void);
363
378 static Debug &AssertBegin(const char *file, int line, const char *expr);
379
390 bool AssertDone(void);
391
406 static Debug &CheckBegin(const char *file, int line, const char *expr);
407
416 bool CheckDone(void);
417
430 static Debug &LogBegin(const char *fileOrGroup);
431
440 bool LogDone(void);
441
456 static Debug &CrashBegin(const char *file, int line);
457
468 bool CrashDone(bool die);
469
477 Debug& operator<<(const char *str);
478
486 void SetPrefixAndRadix(const char *prefix, int radix);
487
495 Debug& operator<<(int val);
496
504 Debug& operator<<(unsigned val);
505
513 Debug& operator<<(long val);
514
522 Debug& operator<<(unsigned long val);
523
531 Debug& operator<<(bool val);
532
540 Debug& operator<<(float val);
541
549 Debug& operator<<(double val);
550
558 Debug& operator<<(short val);
559
567 Debug& operator<<(unsigned short val);
568
576 Debug& operator<<(__int64 val);
577
585 Debug& operator<<(unsigned __int64 val);
586
594 Debug& operator<<(const void *ptr);
595
603 Debug& operator<<(const MemDump &dump);
604
612 Debug& operator<<(HResult hres);
613
624 static bool IsLogEnabled(const char *fileOrGroup);
625
641 static void AddHResultTranslator(unsigned prio, HResultTranslator func, void *user=0);
642
652 static void RemoveHResultTranslator(HResultTranslator func, void *user=0);
653
666 static bool AddIOFactory(const char *io_id, const char *descr,
667 DebugIOInterface* (*func)(void));
668
689 static bool AddCommands(const char *cmdgroup, DebugCmdInterface *cmdif);
690
696 static void RemoveCommands(DebugCmdInterface *cmdif);
697
703 static void Command(const char *cmd);
704
710 static void Update(void);
711
720 static bool SimpleMatch(const char *str, const char *pattern);
721
731 static void SetBuildInfo(const char *version,
732 const char *internalVersion,
733 const char *buildDate);
734
738 void WriteBuildInfo(void);
739
740private:
741 // no assignment, no copy constructor
742 Debug(const Debug&);
743 Debug& operator=(const Debug&);
744
753 Debug(void);
754
761 static void PreStaticInit(void);
762
768 static void PostStaticInit(void);
769
776 static void StaticExit(void);
777
783 static Debug Instance;
784
790 static void *PreStatic;
791
797 static void *PostStatic;
798
800 struct HResultTranslatorEntry
801 {
803 unsigned prio;
804
807
809 void *user;
810 };
811
813 HResultTranslatorEntry *hrTranslators;
814
816 unsigned numHrTranslators;
817
819 struct IOFactoryListEntry
820 {
822 IOFactoryListEntry *next;
823
825 const char *ioID;
826
828 const char *descr;
829
831 DebugIOInterface* (*factory)(void);
832
835
837 char *input;
838
840 unsigned inputUsed;
841
843 unsigned inputAlloc;
844 };
845
852 IOFactoryListEntry *firstIOFactory;
853
855 struct CmdInterfaceListEntry
856 {
858 CmdInterfaceListEntry *next;
859
861 const char *group;
862
864 DebugCmdInterface *cmdif;
865 };
866
873 CmdInterfaceListEntry *firstCmdGroup;
874
876 static unsigned curStackFrame;
877
885 enum
886 {
888 FrameTypeAssert = 0x00000001,
889
891 FrameTypeCheck = 0x00000002,
892
894 FrameTypeLog = 0x00000004
895 };
896
901 enum FrameStatus
902 {
904 Unknown = 0,
905
907 Skip,
908
910 NoSkip
911 };
912
918 struct FrameHashEntry
919 {
921 FrameHashEntry *next;
922
924 unsigned frameAddr;
925
927 unsigned frameType;
928
930 const char *fileOrGroup;
931
933 int line;
934
936 int hits;
937
939 FrameStatus status;
940 };
941
943 enum { FRAME_HASH_SIZE = 10007 };
944
946 FrameHashEntry *frameHash[FRAME_HASH_SIZE];
947
949 enum { FRAME_HASH_ALLOC_COUNT = 100 };
950
952 FrameHashEntry *nextUnusedFrameHash;
953
955 unsigned numAvailableFrameHash;
956
964 __forceinline FrameHashEntry *LookupFrame(unsigned addr)
965 {
966 for (FrameHashEntry *e=frameHash[addr%FRAME_HASH_SIZE];e;e=e->next)
967 if (e->frameAddr==addr)
968 return e;
969 return 0;
970 }
971
984 FrameHashEntry *AddFrameEntry(unsigned addr, unsigned type,
985 const char *fileOrGroup, int line);
986
994 void UpdateFrameStatus(FrameHashEntry &entry);
995
1006 FrameHashEntry *GetFrameEntry(unsigned addr, unsigned type,
1007 const char *fileOrGroup, int line)
1008 {
1009 FrameHashEntry *e=LookupFrame(addr);
1010 if (!e)
1011 e=AddFrameEntry(addr,type,fileOrGroup,line);
1012 if (e->status==Unknown)
1013 UpdateFrameStatus(*e);
1014 return e;
1015 }
1016
1026 struct KnownLogGroupList
1027 {
1029 KnownLogGroupList *next;
1030
1032 char *nameGroup;
1033
1035 const char *descr;
1036 };
1037
1039 KnownLogGroupList *firstLogGroup;
1040
1053 const char *AddLogGroup(const char *fileOrGroup, const char *descr);
1054
1056 struct
1057 {
1059 char *buffer;
1060
1062 unsigned used;
1063
1065 unsigned alloc;
1066
1070
1073
1075 char curSource[256];
1076
1078 int disableAssertsEtc;
1079
1087 void StartOutput(DebugIOInterface::StringType type, const char *fmt, ...);
1088
1096 void AddOutput(const char *str, unsigned len);
1097
1105 void FlushOutput(bool defaultLog=true);
1106
1108 FrameHashEntry *curFrameEntry;
1109
1111 struct PatternListEntry
1112 {
1114 PatternListEntry *next;
1115
1117 unsigned frameTypes;
1118
1120 bool isActive;
1121
1123 char *pattern;
1124 };
1125
1132 PatternListEntry *firstPatternEntry;
1133
1135 PatternListEntry *lastPatternEntry;
1136
1146 void AddPatternEntry(unsigned types, bool isActive, const char *pattern);
1147
1155 void ExecCommand(const char *cmdstart, const char *cmdend);
1156
1165 bool IsWindowed(void);
1166
1168 char curCommandGroup[100];
1169
1171 bool alwaysFlush;
1172
1174 bool timeStamp;
1175
1177 DebugStackwalk m_stackWalk;
1178
1180 char m_prefix[16];
1181
1183 int m_radix;
1184
1186 char m_version[64];
1187
1189 char m_intVersion[64];
1190
1192 char m_buildDate[64];
1193
1195 int m_width;
1196
1198 char m_fillChar;
1199
1201 char m_isWindowed;
1202};
1203
1206
1232const char *DebugGetDefaultCommands(void);
1233
1235
1236#endif // DEBUG_DEBUG_H
#define bool
Definition gimex.h:284
Switches integer output to binary format.
Switches integer output to decimal format.
Sets new fill character.
FillChar(char ch=' ')
Sets new fill character.
Old printf style formatting.
Helper class for writing HRESULTs to the debug stream.
HResult(long hresult)
Switches integer output to hexadecimal format.
Helper class for performing a raw memory dump.
Definition debug_debug.h:83
static MemDump CharRel(const void *startPtr, unsigned numItems, unsigned bytePerItem=1)
static MemDump Raw(const void *startPtr, unsigned numItems, unsigned bytePerItem=1)
static MemDump Char(const void *startPtr, unsigned numItems, unsigned bytePerItem=1)
static MemDump RawRel(const void *startPtr, unsigned numItems, unsigned bytePerItem=1)
RepeatChar(char ch, int count)
Repeats a given character N times.
Sets output width for the next insertion.
Width(int width)
Sets new output width (next insertion only).
Debug command group interface.
Definition debug_cmd.h:52
Debug module main class (singleton).
Definition debug_debug.h:45
void WriteBuildInfo(void)
Write build information into log.
static void Command(const char *cmd)
Issues a debug command.
unsigned used
used buffer size
Debug & operator<<(const Format &f)
static void RemoveCommands(DebugCmdInterface *cmdif)
Removes a command group.
Debug & operator<<(Hex &)
static void Update(void)
Update method, must be called on a regular basis.
static Debug & AssertBegin(const char *file, int line, const char *expr)
Debug & operator<<(Width &w)
static bool IsLogEnabled(const char *fileOrGroup)
Debug & operator<<(Dec &)
bool CrashDone(bool die)
bool AssertDone(void)
static void AddHResultTranslator(unsigned prio, HResultTranslator func, void *user=0)
Adds a HRESULT translator.
static bool AddCommands(const char *cmdgroup, DebugCmdInterface *cmdif)
Adds a new command group.
static bool AddIOFactory(const char *io_id, const char *descr, DebugIOInterface *(*func)(void))
Registers a new I/O class factory function.
bool(* HResultTranslator)(Debug &debug, long hresult, void *user)
HRESULT translator callback function type.
Definition debug_debug.h:70
friend class LogDescription
static void RemoveHResultTranslator(HResultTranslator func, void *user=0)
Removes a HRESULT translator.
Debug & operator<<(FillChar &c)
static void InstallExceptionHandler(void)
Installs exception handler for current thread.
Debug & operator<<(Bin &)
static Debug & CheckBegin(const char *file, int line, const char *expr)
void SetPrefixAndRadix(const char *prefix, int radix)
static Debug & LogBegin(const char *fileOrGroup)
friend class DebugExceptionhandler
Definition debug_debug.h:50
friend class DebugCmdInterfaceDebug
Definition debug_debug.h:47
bool LogDone(void)
unsigned alloc
allocated buffer size
char * buffer
buffer
static bool SimpleMatch(const char *str, const char *pattern)
@ MAX_CHECK_HITS
maximum number of times a check can be hit before it is turned off
Definition debug_debug.h:56
static Debug & CrashBegin(const char *file, int line)
bool CheckDone(void)
static bool SkipNext(void)
bool lastWasCR
has last character been CR?
static void SetBuildInfo(const char *version, const char *internalVersion, const char *buildDate)
Tell debug module about build info.
Debug I/O interface.
Definition debug_io.h:47
StringType
List of possible log string types.
Definition debug_io.h:67
const char * DebugGetDefaultCommands(void)
Determines default commands to be executed at startup.