dclib-debug.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  1. /***************************************************************************
  2. * *
  3. * _____ ____ *
  4. * | __ \ / __ \ _ _ _____ *
  5. * | | \ \ / / \_\ | | | | _ \ *
  6. * | | \ \| | | | | | |_| | *
  7. * | | | || | | | | | ___/ *
  8. * | | / /| | __ | | | | _ \ *
  9. * | |__/ / \ \__/ / | |___| | |_| | *
  10. * |_____/ \____/ |_____|_|_____/ *
  11. * *
  12. * Wiimms source code library *
  13. * *
  14. ***************************************************************************
  15. * *
  16. * Copyright (c) 2012-2022 by Dirk Clemens <wiimm@wiimm.de> *
  17. * *
  18. ***************************************************************************
  19. * *
  20. * This library is free software; you can redistribute it and/or modify *
  21. * it under the terms of the GNU General Public License as published by *
  22. * the Free Software Foundation; either version 2 of the License, or *
  23. * (at your option) any later version. *
  24. * *
  25. * This library is distributed in the hope that it will be useful, *
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  28. * GNU General Public License for more details. *
  29. * *
  30. * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt *
  31. * *
  32. ***************************************************************************/
  33. #ifndef DCLIB_DEBUG_H
  34. #define DCLIB_DEBUG_H 1
  35. #include "dclib-types.h"
  36. #include <stdio.h>
  37. #include <stdarg.h>
  38. //
  39. ///////////////////////////////////////////////////////////////////////////////
  40. /////////////// error_level_t ///////////////
  41. ///////////////////////////////////////////////////////////////////////////////
  42. // [[error_level_t]]
  43. typedef enum error_level_t
  44. {
  45. ERRLEV_MINIMAL, // simple error line only
  46. ERRLEV_HEADING, // headline with: tool: ERROR # [ERR_NAME]
  47. ERRLEV_EXTENDED, // extended headline with function and source
  48. ERRLEV_ANNOTATE, // like ERRLEV_EXTENDED; but append 'URL?annotate='
  49. }
  50. error_level_t;
  51. //
  52. ///////////////////////////////////////////////////////////////////////////////
  53. /////////////// program info ///////////////
  54. ///////////////////////////////////////////////////////////////////////////////
  55. // [[ProgInfo_t]]
  56. typedef struct ProgInfo_t
  57. {
  58. ccp progpath; // full path of program, use ProgramPath() to access
  59. ccp progdir; // directory part of progpath, use ProgramDirectory() to access
  60. ccp progname; // program name, based on path or directly set
  61. ccp logdir; // log directory, set by DefineLogDirectory()
  62. // and GetLogDirectory()
  63. ccp toolname; // name of the tool, set by SetupProgname()
  64. ccp toolversion; // version of the tool, set by SetupProgname()
  65. ccp tooltitle; // title of the tool, set by SetupProgname()
  66. error_level_t error_level; // one of ERRLEV_*
  67. bool multi_processing; // TRUE: program uses multiple threads
  68. enumError last_error; // last error, set by PrintErrorArg()
  69. enumError max_error; // max error, set by PrintErrorArg()
  70. u32 error_count; // number of errors, set by PrintErrorArg()
  71. }
  72. ProgInfo_t;
  73. extern ProgInfo_t ProgInfo;
  74. //
  75. ///////////////////////////////////////////////////////////////////////////////
  76. /////////////// error handling ///////////////
  77. ///////////////////////////////////////////////////////////////////////////////
  78. extern ccp (*GetErrorNameHook)( int stat, ccp ret_not_found );
  79. extern ccp (*GetErrorTextHook)( int stat, ccp ret_not_found );
  80. extern ccp GENERIC_ERROR_MESSAGE;
  81. ccp GetErrorName
  82. (
  83. int stat, // error status, err := abs(stat)
  84. ccp ret_not_found // not NULL: return this, if no message is found
  85. // GENERIC_ERROR_MESSAGE: return a generic message
  86. );
  87. ccp GetErrorText
  88. (
  89. int stat, // error status, err := abs(stat)
  90. ccp ret_not_found // not NULL: return this, if no message is found
  91. // GENERIC_ERROR_MESSAGE: return a generic message
  92. );
  93. void ListErrorCodes
  94. (
  95. FILE * f, // valid output stream
  96. int indent, // indent of output
  97. bool all // true: print all user reserved messages too.
  98. );
  99. enumError PrintErrorArg ( ccp func, ccp file, unsigned int line,
  100. int syserr, enumError err_code, ccp format, va_list arg );
  101. enumError PrintError ( ccp func, ccp file, unsigned int line,
  102. int syserr, enumError err_code, ccp format, ... )
  103. __attribute__ ((__format__(__printf__,6,7)));
  104. struct File_t;
  105. enumError PrintErrorFile ( ccp func, ccp file, uint line, struct File_t *F,
  106. int syserr, enumError err_code, ccp format, ... )
  107. __attribute__ ((__format__(__printf__,7,8)));
  108. enumError PrintErrorStat ( enumError err, int verbose, ccp cmdname );
  109. #undef ERROR
  110. #undef ERROR0
  111. #undef ERROR1
  112. #undef FILEERROR
  113. #undef FILEERROR0
  114. #undef FILEERROR1
  115. #define ERROR(se,code,...) PrintError(__FUNCTION__,__FILE__,__LINE__,se,code,__VA_ARGS__)
  116. #define ERROR0(code,...) PrintError(__FUNCTION__,__FILE__,__LINE__,0,code,__VA_ARGS__)
  117. #define ERROR1(code,...) PrintError(__FUNCTION__,__FILE__,__LINE__,errno,code,__VA_ARGS__)
  118. #define FILEERROR(f,se,code,...) \
  119. PrintErrorFile(__FUNCTION__,__FILE__,__LINE__,f,se,code,__VA_ARGS__)
  120. #define FILEERROR0(f,code,...) \
  121. PrintErrorFile(__FUNCTION__,__FILE__,__LINE__,f,0,code,__VA_ARGS__)
  122. #define FILEERROR1(f,code,...) \
  123. PrintErrorFile(__FUNCTION__,__FILE__,__LINE__,f,errno,code,__VA_ARGS__)
  124. //-----------------------------------------------------------------------------
  125. bool mark_used ( ccp name, ... );
  126. #define MARK_USED(...) mark_used(0,__VA_ARGS__)
  127. //
  128. ///////////////////////////////////////////////////////////////////////////////
  129. /////////////// hexdump ///////////////
  130. ///////////////////////////////////////////////////////////////////////////////
  131. extern ccp hexdump_prefix;
  132. extern ccp hexdump_eol;
  133. extern bool hexdump_align;
  134. //-----------------------------------------------------------------------------
  135. // HexDump*() return the number of printed lines
  136. uint HexDump ( FILE * f, int indent, u64 addr, int addr_fw, int row_len,
  137. const void * data, size_t count );
  138. uint HexDump16 ( FILE * f, int indent, u64 addr,
  139. const void * data, size_t count );
  140. uint HexDump20 ( FILE * f, int indent, u64 addr,
  141. const void * data, size_t count );
  142. uint HexDumpBE2 ( FILE * f, int indent, u64 addr, int addr_fw, int row_len,
  143. const void * data, size_t count );
  144. uint HexDump16BE2 ( FILE * f, int indent, u64 addr,
  145. const void * data, size_t count );
  146. uint HexDump20BE2 ( FILE * f, int indent, u64 addr,
  147. const void * data, size_t count );
  148. uint HexDumpLE2 ( FILE * f, int indent, u64 addr, int addr_fw, int row_len,
  149. const void * data, size_t count );
  150. uint HexDump16LE2 ( FILE * f, int indent, u64 addr,
  151. const void * data, size_t count );
  152. uint HexDump20LE2 ( FILE * f, int indent, u64 addr,
  153. const void * data, size_t count );
  154. uint HexDumpBE4 ( FILE * f, int indent, u64 addr, int addr_fw, int row_len,
  155. const void * data, size_t count );
  156. uint HexDump16BE4 ( FILE * f, int indent, u64 addr,
  157. const void * data, size_t count );
  158. uint HexDump20BE4 ( FILE * f, int indent, u64 addr,
  159. const void * data, size_t count );
  160. uint HexDumpLE4 ( FILE * f, int indent, u64 addr, int addr_fw, int row_len,
  161. const void * data, size_t count );
  162. uint HexDump16LE4 ( FILE * f, int indent, u64 addr,
  163. const void * data, size_t count );
  164. uint HexDump20LE4 ( FILE * f, int indent, u64 addr,
  165. const void * data, size_t count );
  166. // HexDump0*() will supress null-only lines.
  167. uint HexDump0 ( FILE * f, int indent, u64 addr, int addr_fw, int row_len,
  168. const void * data, size_t count );
  169. uint HexDump016 ( FILE * f, int indent, u64 addr,
  170. const void * data, size_t count );
  171. void HexDiff ( FILE * f, int indent, u64 addr, int addr_fw, int row_len,
  172. const void * p_data1, size_t count1,
  173. const void * p_data2, size_t count2 );
  174. void HexDiff16 ( FILE * f, int indent, u64 addr,
  175. const void * data1, size_t count1,
  176. const void * data2, size_t count2 );
  177. //
  178. ///////////////////////////////////////////////////////////////////////////////
  179. /////////////// debug helpers ///////////////
  180. ///////////////////////////////////////////////////////////////////////////////
  181. // [[PrintDebugFunc]
  182. typedef int (*PrintDebugFunc)
  183. (
  184. ccp format, // format string
  185. ... // parameters for 'format'
  186. )
  187. __attribute__ ((__format__(__printf__,1,2)));
  188. //
  189. ///////////////////////////////////////////////////////////////////////////////
  190. /////////////// DEBUG and TRACING ///////////////
  191. ///////////////////////////////////////////////////////////////////////////////
  192. //
  193. // -------------------
  194. // DEBUG and TRACING
  195. // -------------------
  196. //
  197. // If symbol 'DEBUG' or symbol _DEBUG' is defined, then and only then
  198. // DEBUG, DASSERT and TRACING are enabled.
  199. //
  200. // Defined functions/macros:
  201. //
  202. // TRACE ( ccp format, ... );
  203. // Print to console only if TRACING is enabled.
  204. // Ignored when TRACING is disabled.
  205. // It works like the well known printf() function and include flushing.
  206. //
  207. // TRACE_IF ( bool condition, ccp format, ... );
  208. // Like TRACE(), but print only if 'condition' is true.
  209. //
  210. // TRACELINE
  211. // Print out current line and source if TRACING is defined.
  212. //
  213. // TRACE_SIZEOF ( object_or_type );
  214. // Print out `sizeof(object_or_type)´ if TRACING is defined.
  215. //
  216. // ASSERT(cond);
  217. // If condition is false: print info and exit program.
  218. //
  219. // DASSERT(cond);
  220. // Like ASSERT; but only active on DEBUG.
  221. //
  222. // BINGO
  223. // Like TRACELINE, but print to stderr instead custom file.
  224. //
  225. //
  226. // There are more macros with a preceding 'no' defined:
  227. //
  228. // noTRACE ( ccp format, ... );
  229. // noTRACE_IF ( bool condition, ccp format, ... );
  230. // noTRACELINE ( bool condition, ccp format, ... );
  231. // noTRACE_SIZEOF ( object_or_type );
  232. // noASSERT(cond);
  233. //
  234. // If you add a 'no' before a TRACE-Call it is disabled always.
  235. // This makes the usage and disabling of multi lines traces very easy.
  236. //
  237. //
  238. // The macros with a preceding 'x' are always active:
  239. // xTRACELINE
  240. // xBINGO
  241. //
  242. ///////////////////////////////////////////////////////////////////////////////
  243. ///////////////////////////////////////////////////////////////////////////////
  244. #if defined(RELEASE)
  245. #undef TESTTRACE
  246. #undef DEBUG
  247. #undef _DEBUG
  248. #undef DEBUG_ASSERT
  249. #undef _DEBUG_ASSERT
  250. #undef WAIT_ENABLED
  251. #endif
  252. ///////////////////////////////////////////////////////////////////////////////
  253. #if defined(IGNORE_DEBUG)
  254. #undef DEBUG
  255. #undef _DEBUG
  256. #endif
  257. ///////////////////////////////////////////////////////////////////////////////
  258. #undef TRACE
  259. #undef TRACE_IF
  260. #undef TRACELINE
  261. #undef TRACE_SIZEOF
  262. #undef TRACE0
  263. #undef TRACE_IF0
  264. #undef TRACELINE0
  265. #undef TRACE_SIZEOF0
  266. #undef TRACE1
  267. #undef TRACE_IF1
  268. #undef TRACELINE1
  269. #undef TRACE_SIZEOF1
  270. ///////////////////////////////////////////////////////////////////////////////
  271. #ifdef WIN_SZS_LIB
  272. #define __attribute__(x)
  273. #endif
  274. extern ccp TRACE_PREFIX; // never NULL
  275. extern FILE *TRACE_FILE;
  276. extern FILE *MEM_LOG_FILE;
  277. void TRACE_FUNC ( ccp format, ... )
  278. __attribute__ ((__format__(__printf__,1,2)));
  279. void TRACE_ARG_FUNC ( ccp format, va_list arg );
  280. void PRINT_FUNC ( ccp format, ... )
  281. __attribute__ ((__format__(__printf__,1,2)));
  282. void PRINT_ARG_FUNC ( ccp format, va_list arg );
  283. void BINGO_FUNC ( ccp func, int line, ccp src );
  284. void WAIT_FUNC ( ccp format, ... )
  285. __attribute__ ((__format__(__printf__,1,2)));
  286. void WAIT_ARG_FUNC ( ccp format, va_list arg );
  287. ///////////////////////////////////////////////////////////////////////////////
  288. #undef TEST0 // never defined
  289. #ifdef TESTTRACE
  290. #undef DEBUG
  291. #define DEBUG 1
  292. #undef TEST
  293. #define TEST 1
  294. #undef WAIT_ENABLED
  295. #define WAIT_ENABLED 1
  296. #undef NEW_FEATURES
  297. #define NEW_FEATURES 1
  298. #define TRACE_FUNC printf
  299. #define PRINT_FUNC printf
  300. #define WAIT_FUNC printf
  301. #define TRACE_ARG_FUNC vprintf
  302. #define PRINT_ARG_FUNC vprintf
  303. #define WAIT_ARG_FUNC vprintf
  304. #endif
  305. ///////////////////////////////////////////////////////////////////////////////
  306. // always disabled
  307. #define TRACE0(...)
  308. #define TRACE_IF0(cond,...)
  309. #define TRACELINE0
  310. #define TRACE_SIZEOF0(t)
  311. // always enabled
  312. #define TRACE1(...) TRACE_FUNC(__VA_ARGS__)
  313. #define TRACE_IF1(cond,...) if (cond) TRACE_FUNC(__VA_ARGS__)
  314. #define TRACELINE1 TRACE_FUNC("%s() %s #%u\n",__FUNCTION__,__FILE__,__LINE__)
  315. #define TRACE_SIZEOF1(t) TRACE_FUNC("%7zd ==%6zx/hex == sizeof(%s)\n",sizeof(t),sizeof(t),#t)
  316. #if defined(DEBUG) || defined(_DEBUG)
  317. #define HAVE_TRACE 1
  318. #undef DEBUG
  319. #define DEBUG 1
  320. #undef DEBUG_ASSERT
  321. #define DEBUG_ASSERT 1
  322. #define TRACE TRACE1
  323. #define TRACE_IF TRACE_IF1
  324. #define TRACELINE TRACELINE1
  325. #define TRACE_SIZEOF TRACE_SIZEOF1
  326. #define HEXDUMP(i,a,af,rl,d,c) HexDump(stdout,i,a,af,rl,d,c);
  327. #define HEXDUMP16(i,a,d,c) HexDump16(stdout,i,a,d,c);
  328. #define TRACE_HEXDUMP(i,a,af,rl,d,c) HexDump(TRACE_FILE,i,a,af,rl,d,c);
  329. #define TRACE_HEXDUMP16(i,a,d,c) HexDump16(TRACE_FILE,i,a,d,c);
  330. #define HEXDIFF(i,a,af,rl,d1,c1,d2,c2) HexDiff(stdout,i,a,af,rl,d1,c1,d2,c2);
  331. #define HEXDIFF16(i,a,d1,c1,d2,c2) HexDiff16(stdout,i,a,d1,c1,d2,c2);
  332. #define TRACE_HEXDIFF(i,a,af,rl,d1,c1,d2,c2) HexDiff(TRACE_FILE,i,a,af,rl,d1,c1,d2,c2);
  333. #define TRACE_HEXDIFF16(i,a,d1,c1,d2,c2) HexDiff16(TRACE_FILE,i,a,d1,c1,d2,c2);
  334. #else
  335. #define HAVE_TRACE 0
  336. #undef DEBUG
  337. #define TRACE(...)
  338. #define TRACE_IF(cond,...)
  339. #define TRACELINE
  340. #define TRACE_SIZEOF(t)
  341. #define HEXDUMP(i,a,af,rl,d,c)
  342. #define HEXDUMP16(a,i,d,c)
  343. #define TRACE_HEXDUMP(i,a,af,rl,d,c)
  344. #define TRACE_HEXDUMP16(i,a,d,c)
  345. #define HEXDIFF(i,a,af,rl,d1,c1,d2,c2)
  346. #define HEXDIFF16(a,i,d1,c1,d2,c2)
  347. #define TRACE_HEXDIFF(i,a,af,rl,d1,c1,d2,c2)
  348. #define TRACE_HEXDIFF16(i,a,d1,c1,d2,c2)
  349. #endif
  350. ///////////////////////////////////////////////////////////////////////////////
  351. #undef ASSERT
  352. #undef ASSERT_MSG
  353. #if defined(DEBUG_ASSERT) || defined(_DEBUG_ASSERT) || defined(TEST)
  354. #define HAVE_ASSERT 1
  355. #undef DEBUG_ASSERT
  356. #define DEBUG_ASSERT 1
  357. #define ASSERT(a) if (!(a)) ERROR0(ERR_FATAL,"ASSERTION FAILED !!!\n")
  358. #define ASSERT_MSG(a,...) if (!(a)) ERROR0(ERR_FATAL,__VA_ARGS__)
  359. #else
  360. #define HAVE_ASSERT 0
  361. #undef DEBUG_ASSERT
  362. #define ASSERT(cond)
  363. #define ASSERT_MSG(a,...)
  364. #endif
  365. ///////////////////////////////////////////////////////////////////////////////
  366. #undef HAVE_PRINT
  367. #undef PRINT
  368. #undef PRINT_IF
  369. #undef PRINT_SIZEOF
  370. #undef BINGO
  371. #undef HAVE_PRINT0
  372. #undef PRINT0
  373. #undef PRINT_IF0
  374. #undef PRINT_SIZEOF0
  375. #undef BINGO0
  376. #undef HAVE_PRINT1
  377. #undef PRINT1
  378. #undef PRINT_IF1
  379. #undef PRINT_SIZEOF1
  380. #undef BINGO1
  381. #undef HAVE_PRINTD
  382. #undef PRINTD
  383. #undef PRINT_IFD
  384. #undef PRINT_SIZEOFD
  385. #undef BINGOD
  386. #undef xBINGO
  387. #undef PRINT_TIME
  388. // always disabled
  389. #define HAVE_PRINT0 0
  390. #define PRINT0(...)
  391. #define PRINT_IF0(...)
  392. #define PRINT_SIZEOF0(...)
  393. #define BINGO0 TRACELINE
  394. // always enabled
  395. #define HAVE_PRINT1 1
  396. #define PRINT1(...) PRINT_FUNC(__VA_ARGS__)
  397. #define PRINT_IF1(cond,...) if (cond) PRINT_FUNC(__VA_ARGS__)
  398. #define PRINT_SIZEOF1(t) PRINT_FUNC("%7zd ==%6zx/hex == sizeof(%s)\n",sizeof(t),sizeof(t),#t)
  399. #define BINGO1 BINGO_FUNC(__FUNCTION__,__LINE__,__FILE__)
  400. #if defined(DEBUG) && defined(TEST)
  401. #define HAVE_PRINT 1
  402. #define PRINT PRINT1
  403. #define PRINT_IF PRINT_IF1
  404. #define PRINT_SIZEOF PRINT_SIZEOF1
  405. #define BINGO BINGO_FUNC(__FUNCTION__,__LINE__,__FILE__)
  406. void PRINT_TIME ( time_t time, ccp title );
  407. #else
  408. #define HAVE_PRINT HAVE_TRACE
  409. #define PRINT TRACE
  410. #define PRINT_IF TRACE_IF
  411. #define PRINT_SIZEOF TRACE_SIZEOF
  412. #define BINGO TRACELINE
  413. #define PRINT_TIME(...)
  414. #endif
  415. #if IS_DEVELOP
  416. #define HAVE_PRINTD 1
  417. #define PRINTD PRINT1
  418. #define PRINT_IFD PRINT_IF1
  419. #define PRINT_SIZEOFD PRINT_SIZEOF1
  420. #define BINGOD BINGO_FUNC(__FUNCTION__,__LINE__,__FILE__)
  421. #else
  422. #define HAVE_PRINTD 0
  423. #define PRINTD(...)
  424. #define PRINT_IFD(cond,...)
  425. #define PRINT_SIZEOFD(t)
  426. #define BINGOD
  427. #endif
  428. #define xBINGO BINGO_FUNC(__FUNCTION__,__LINE__,__FILE__)
  429. #define xTRACELINE TRACE_FUNC("%s() line #%d @ %s\n",__FUNCTION__,__LINE__,__FILE__)
  430. #undef PRINTF
  431. #define PRINTF PRINT
  432. ///////////////////////////////////////////////////////////////////////////////
  433. #undef WAIT
  434. #undef WAIT_IF
  435. #undef HAVE_WAIT
  436. #if defined(WAIT_ENABLED)
  437. #define HAVE_WAIT 1
  438. #define WAIT(...) WAIT_FUNC(__VA_ARGS__)
  439. #define WAIT_IF(cond,...) if (cond) WAIT_FUNC(__VA_ARGS__)
  440. #else
  441. #define HAVE_WAIT 0
  442. #define WAIT(...)
  443. #define WAIT_IF(cond,...)
  444. #endif
  445. ///////////////////////////////////////////////////////////////////////////////
  446. #undef DASSERT
  447. #undef DASSERT_MSG
  448. #undef HAVE_DASSERT
  449. #if defined(DEBUG) || defined(TEST)
  450. #define HAVE_DASSERT 1
  451. #define DASSERT ASSERT
  452. #define DASSERT_MSG ASSERT_MSG
  453. #else
  454. #define HAVE_DASSERT 0
  455. #define DASSERT(cond)
  456. #define DASSERT_MSG(a,...)
  457. #endif
  458. ///////////////////////////////////////////////////////////////////////////////
  459. // prefix 'no' deactivates traces
  460. #undef noTRACE
  461. #undef noTRACE_IF
  462. #undef noTRACELINE
  463. #undef noTRACE_SIZEOF
  464. #undef noPRINT
  465. #undef noPRINT_IF
  466. #undef noPRINT_TIME
  467. #undef noWAIT
  468. #undef noWAIT_IF
  469. #undef noASSERT
  470. #ifdef TESTTRACE
  471. #define noTRACE TRACE
  472. #define noTRACE_IF TRACE_IF
  473. #define noTRACELINE TRACELINE
  474. #define noTRACE_SIZEOF TRACE_SIZEOF
  475. #define noPRINT PRINT
  476. #define noPRINT_IF PRINT_IF
  477. #define noPRINT_TIME PRINT_TIME
  478. #define noWAIT WAIT
  479. #define noWAIT_IF WAIT_IF
  480. #define noASSERT ASSERT
  481. #define noASSERT_MSG ASSERT_MSG
  482. #else
  483. #define noTRACE(...)
  484. #define noTRACE_IF(cond,...)
  485. #define noTRACELINE
  486. #define noTRACE_SIZEOF(t)
  487. #define noPRINT(...)
  488. #define noPRINT_IF(...)
  489. #define noPRINT_TIME(...)
  490. #define noWAIT(...)
  491. #define noWAIT_IF(...)
  492. #define noASSERT(cond)
  493. #define noASSERT_MSG(cond,...)
  494. #endif
  495. //
  496. ///////////////////////////////////////////////////////////////////////////////
  497. /////////////// alloc/free system ///////////////
  498. ///////////////////////////////////////////////////////////////////////////////
  499. // define TRACE_ALLOC_MODE
  500. //
  501. // 0: standard malloc without 'out of memory' detection (don't use it!)
  502. // 1: standard malloc with 'out of memory' detection
  503. // 2: standard malloc with 'out of memory' detection and source identification
  504. // 3: like mode #2, but alloc debuging enabled too
  505. // 4: like mode #3, but alloc tracing enabled too
  506. // define ENABLE_MEM_CHECK (check specific memory areas)
  507. // 0: disabled
  508. // 1: enable a watch point for a memory location
  509. #ifndef TRACE_ALLOC_MODE
  510. #ifdef MEMDEBUG
  511. #define TRACE_ALLOC_MODE 4
  512. #elif TEST
  513. #define TRACE_ALLOC_MODE 3
  514. #elif DEBUG
  515. #define TRACE_ALLOC_MODE 2
  516. #else
  517. #define TRACE_ALLOC_MODE 1
  518. #endif
  519. #endif
  520. #ifndef ENABLE_MEM_CHECK
  521. #define ENABLE_MEM_CHECK 0
  522. #endif
  523. ///////////////////////////////////////////////////////////////////////////////
  524. #if ENABLE_MEM_CHECK
  525. extern void MemCheckSetup ( const void * ptr, unsigned int size );
  526. extern void MemCheck ( ccp func, ccp file, unsigned int line );
  527. #define MEM_CHECK_SETUP(p,s) MemCheckSetup(p,s)
  528. #define MEM_CHECK MemCheck(__FUNCTION__,__FILE__,__LINE__)
  529. #else
  530. #define MEM_CHECK_SETUP(p,s)
  531. #define MEM_CHECK
  532. #endif
  533. ///////////////////////////////////////////////////////////////////////////////
  534. void dclib_free ( void * ptr );
  535. void * dclib_xcalloc ( size_t nmemb, size_t size );
  536. void * dclib_xmalloc ( size_t size );
  537. void * dclib_xrealloc ( void * ptr, size_t size );
  538. char * dclib_xstrdup ( ccp src );
  539. // HINT: the *memdup* functions always alloc 1 additonal byte and set it to NULL.
  540. #if TRACE_ALLOC_MODE > 1
  541. void * dclib_calloc ( ccp,ccp,uint, size_t nmemb, size_t size );
  542. void * dclib_malloc ( ccp,ccp,uint, size_t size );
  543. void * dclib_realloc ( ccp,ccp,uint, void * ptr, size_t size );
  544. char * dclib_strdup ( ccp,ccp,uint, ccp src );
  545. char * dclib_strdup2 ( ccp,ccp,uint, ccp src1, ccp src2 );
  546. char * dclib_strdup3 ( ccp,ccp,uint, ccp src1, ccp src2, ccp src3 );
  547. void * dclib_memdup ( ccp,ccp,uint, cvp src, size_t copylen );
  548. void * dclib_memdup2 ( ccp,ccp,uint, cvp s1, size_t l1, cvp s2, size_t l2 );
  549. void * dclib_memdup3 ( ccp,ccp,uint, cvp s1, size_t l1, cvp s2, size_t l2, cvp s3, size_t l3 );
  550. void * dclib_allocdup( ccp,ccp,uint, cvp src, size_t copylen );
  551. char * dclib_printdup( ccp,ccp,uint, ccp format, ... ) __attribute__ ((__format__(__printf__,4,5)));
  552. #else
  553. void * dclib_calloc ( size_t nmemb, size_t size );
  554. void * dclib_malloc ( size_t size );
  555. void * dclib_realloc ( void * ptr, size_t size );
  556. char * dclib_strdup ( ccp src );
  557. char * dclib_strdup2 ( ccp src1, ccp src2 );
  558. char * dclib_strdup3 ( ccp src1, ccp src2, ccp src3 );
  559. void * dclib_memdup ( cvp src, size_t copylen );
  560. void * dclib_memdup2 ( cvp s1, size_t l1, cvp s2, size_t l2 );
  561. void * dclib_memdup3 ( cvp s1, size_t l1, cvp s2, size_t l2, cvp s3, size_t l3 );
  562. void * dclib_allocdup( cvp src, size_t copylen );
  563. char * dclib_printdup( ccp format, ... ) __attribute__ ((__format__(__printf__,1,2)));
  564. #endif
  565. uint trace_test_alloc ( ccp,ccp,uint, const void * ptr, bool hexdump );
  566. void trace_free ( ccp,ccp,uint, void * ptr );
  567. void * trace_calloc ( ccp,ccp,uint, size_t nmemb, size_t size );
  568. void * trace_malloc ( ccp,ccp,uint, size_t size );
  569. void * trace_realloc ( ccp,ccp,uint, void *ptr, size_t size );
  570. char * trace_strdup ( ccp,ccp,uint, ccp src );
  571. char * trace_strdup2 ( ccp,ccp,uint, ccp src1, ccp src2 );
  572. char * trace_strdup3 ( ccp,ccp,uint, ccp src1, ccp src2, ccp src3 );
  573. void * trace_memdup ( ccp,ccp,uint, cvp src, size_t copylen );
  574. void * trace_memdup2 ( ccp,ccp,uint, cvp s1, size_t l1, cvp s2, size_t l2 );
  575. void * trace_memdup3 ( ccp,ccp,uint, cvp s1, size_t l1, cvp s2, size_t l2, cvp s3, size_t l3 );
  576. void * trace_allocdup ( ccp,ccp,uint, cvp src, size_t copylen );
  577. char * trace_printdup ( ccp,ccp,uint, ccp format, ... ) __attribute__ ((__format__(__printf__,4,5)));
  578. #if TRACE_ALLOC_MODE > 2
  579. void InitializeTraceAlloc(void);
  580. int CheckTraceAlloc ( ccp func, ccp file, unsigned int line );
  581. void DumpTraceAlloc ( ccp func, ccp file, unsigned int line, FILE * f );
  582. struct mem_info_t *RegisterAlloc
  583. ( ccp func, ccp file, uint line, cvp data, uint size, bool filler );
  584. #endif
  585. ///////////////////////////////////////////////////////////////////////////////
  586. #if TRACE_ALLOC_MODE > 2
  587. #define TEST_ALLOC(ptr,hexd) trace_test_alloc(__FUNCTION__,__FILE__,__LINE__,ptr,hexd)
  588. #define FREE(ptr) trace_free(__FUNCTION__,__FILE__,__LINE__,ptr)
  589. #define CALLOC(nmemb,size) trace_calloc(__FUNCTION__,__FILE__,__LINE__,nmemb,size)
  590. #define MALLOC(size) trace_malloc(__FUNCTION__,__FILE__,__LINE__,size)
  591. #define REALLOC(ptr,size) trace_realloc(__FUNCTION__,__FILE__,__LINE__,ptr,size)
  592. #define STRDUP(src) trace_strdup(__FUNCTION__,__FILE__,__LINE__,src)
  593. #define STRDUP2(src1,src2) trace_strdup2(__FUNCTION__,__FILE__,__LINE__,src1,src2)
  594. #define STRDUP3(src1,src2,src3) trace_strdup3(__FUNCTION__,__FILE__,__LINE__,src1,src2,src3)
  595. #define MEMDUP(src,size) trace_memdup(__FUNCTION__,__FILE__,__LINE__,src,size)
  596. #define MEMDUP2(s1,l1,s2,l2) trace_memdup2(__FUNCTION__,__FILE__,__LINE__,s1,l1,s2,l2)
  597. #define MEMDUP3(s1,l1,s2,l2,s3,l3) trace_memdup3(__FUNCTION__,__FILE__,__LINE__,s1,l1,s2,l2,s3,l3)
  598. #define ALLOCDUP(src,size) trace_allocdup(__FUNCTION__,__FILE__,__LINE__,src,size)
  599. #define PRINTDUP(...) trace_printdup(__FUNCTION__,__FILE__,__LINE__,__VA_ARGS__)
  600. #define INIT_TRACE_ALLOC InitializeTraceAlloc()
  601. #define CHECK_TRACE_ALLOC CheckTraceAlloc(__FUNCTION__,__FILE__,__LINE__)
  602. #define DUMP_TRACE_ALLOC(f) DumpTraceAlloc(__FUNCTION__,__FILE__,__LINE__,f)
  603. #elif TRACE_ALLOC_MODE > 1
  604. #define TEST_ALLOC(ptr,hexd)
  605. #define FREE(ptr) dclib_free(ptr)
  606. #define CALLOC(nmemb,size) dclib_calloc(__FUNCTION__,__FILE__,__LINE__,nmemb,size)
  607. #define MALLOC(size) dclib_malloc(__FUNCTION__,__FILE__,__LINE__,size)
  608. #define REALLOC(ptr,size) dclib_realloc(__FUNCTION__,__FILE__,__LINE__,ptr,size)
  609. #define STRDUP(src) dclib_strdup(__FUNCTION__,__FILE__,__LINE__,src)
  610. #define STRDUP2(src1,src2) dclib_strdup2(__FUNCTION__,__FILE__,__LINE__,src1,src2)
  611. #define STRDUP3(src1,src2,src3) dclib_strdup3(__FUNCTION__,__FILE__,__LINE__,src1,src2,src3)
  612. #define MEMDUP(src,size) dclib_memdup(__FUNCTION__,__FILE__,__LINE__,src,size)
  613. #define MEMDUP2(s1,l1,s2,l2) dclib_memdup2(__FUNCTION__,__FILE__,__LINE__,s1,l1,s2,l2)
  614. #define MEMDUP3(s1,l1,s2,l2,s3,l3) dclib_memdup3(__FUNCTION__,__FILE__,__LINE__,s1,l1,s2,l2,s3,l3)
  615. #define ALLOCDUP(src,size) dclib_allocdup(__FUNCTION__,__FILE__,__LINE__,src,size)
  616. #define PRINTDUP(...) dclib_printdup(__FUNCTION__,__FILE__,__LINE__,__VA_ARGS__)
  617. #define INIT_TRACE_ALLOC
  618. #define CHECK_TRACE_ALLOC
  619. #define DUMP_TRACE_ALLOC(f)
  620. #else
  621. #define TEST_ALLOC(ptr,hexd)
  622. #define FREE(ptr) dclib_free(ptr)
  623. #define CALLOC(nmemb,size) dclib_calloc(nmemb,size)
  624. #define MALLOC(size) dclib_malloc(size)
  625. #define REALLOC(ptr,size) dclib_realloc(ptr,size)
  626. #define STRDUP(src) dclib_strdup(src)
  627. #define STRDUP2(src1,src2) dclib_strdup2(src1,src2)
  628. #define STRDUP3(src1,src2,src3) dclib_strdup3(src1,src2,src3)
  629. #define MEMDUP(src,size) dclib_memdup(src,size)
  630. #define MEMDUP2(s1,l1,s2,l2) dclib_memdup2(s1,l1,s2,l2)
  631. #define MEMDUP3(s1,l1,s2,l2,s3,l3) dclib_memdup3(s1,l1,s2,l2,s3,l3)
  632. #define ALLOCDUP(src,size) dclib_allocdup(src,size)
  633. #define PRINTDUP(...) dclib_printdup(__VA_ARGS__)
  634. #define INIT_TRACE_ALLOC
  635. #define CHECK_TRACE_ALLOC
  636. #define DUMP_TRACE_ALLOC(f)
  637. #endif
  638. #define XFREE(ptr) dclib_free(ptr)
  639. #ifndef DCLIB_DEBUG_C
  640. #define free do_not_use_free
  641. #define calloc do_not_use_calloc
  642. #define malloc do_not_use_malloc
  643. #define realloc do_not_use_realloc
  644. #undef strdup
  645. #define strdup do_not_use_strdup
  646. #endif
  647. //
  648. ///////////////////////////////////////////////////////////////////////////////
  649. /////////////// END ///////////////
  650. ///////////////////////////////////////////////////////////////////////////////
  651. #endif // DCLIB_DEBUG_H