memtrace.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. ** 2019-01-21
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. ** May you do good and not evil.
  8. ** May you find forgiveness for yourself and forgive others.
  9. ** May you share freely, never taking more than you give.
  10. **
  11. *************************************************************************
  12. **
  13. ** This file implements an extension that uses the SQLITE_CONFIG_MALLOC
  14. ** mechanism to add a tracing layer on top of SQLite. If this extension
  15. ** is registered prior to sqlite3_initialize(), it will cause all memory
  16. ** allocation activities to be logged on standard output, or to some other
  17. ** FILE specified by the initializer.
  18. **
  19. ** This file needs to be compiled into the application that uses it.
  20. **
  21. ** This extension is used to implement the --memtrace option of the
  22. ** command-line shell.
  23. */
  24. #include <assert.h>
  25. #include <string.h>
  26. #include <stdio.h>
  27. /* The original memory allocation routines */
  28. static sqlite3_mem_methods memtraceBase;
  29. static FILE *memtraceOut;
  30. /* Methods that trace memory allocations */
  31. static void *memtraceMalloc(int n){
  32. if( memtraceOut ){
  33. fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n",
  34. memtraceBase.xRoundup(n));
  35. }
  36. return memtraceBase.xMalloc(n);
  37. }
  38. static void memtraceFree(void *p){
  39. if( p==0 ) return;
  40. if( memtraceOut ){
  41. fprintf(memtraceOut, "MEMTRACE: free %d bytes\n", memtraceBase.xSize(p));
  42. }
  43. memtraceBase.xFree(p);
  44. }
  45. static void *memtraceRealloc(void *p, int n){
  46. if( p==0 ) return memtraceMalloc(n);
  47. if( n==0 ){
  48. memtraceFree(p);
  49. return 0;
  50. }
  51. if( memtraceOut ){
  52. fprintf(memtraceOut, "MEMTRACE: resize %d -> %d bytes\n",
  53. memtraceBase.xSize(p), memtraceBase.xRoundup(n));
  54. }
  55. return memtraceBase.xRealloc(p, n);
  56. }
  57. static int memtraceSize(void *p){
  58. return memtraceBase.xSize(p);
  59. }
  60. static int memtraceRoundup(int n){
  61. return memtraceBase.xRoundup(n);
  62. }
  63. static int memtraceInit(void *p){
  64. return memtraceBase.xInit(p);
  65. }
  66. static void memtraceShutdown(void *p){
  67. memtraceBase.xShutdown(p);
  68. }
  69. /* The substitute memory allocator */
  70. static sqlite3_mem_methods ersaztMethods = {
  71. memtraceMalloc,
  72. memtraceFree,
  73. memtraceRealloc,
  74. memtraceSize,
  75. memtraceRoundup,
  76. memtraceInit,
  77. memtraceShutdown,
  78. 0
  79. };
  80. /* Begin tracing memory allocations to out. */
  81. int sqlite3MemTraceActivate(FILE *out){
  82. int rc = SQLITE_OK;
  83. if( memtraceBase.xMalloc==0 ){
  84. rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memtraceBase);
  85. if( rc==SQLITE_OK ){
  86. rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &ersaztMethods);
  87. }
  88. }
  89. memtraceOut = out;
  90. return rc;
  91. }
  92. /* Deactivate memory tracing */
  93. int sqlite3MemTraceDeactivate(void){
  94. int rc = SQLITE_OK;
  95. if( memtraceBase.xMalloc!=0 ){
  96. rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memtraceBase);
  97. if( rc==SQLITE_OK ){
  98. memset(&memtraceBase, 0, sizeof(memtraceBase));
  99. }
  100. }
  101. memtraceOut = 0;
  102. return rc;
  103. }