/ Hex Artifact Content
Login

Artifact 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b:


0000: 2f 2a 0a 2a 2a 20 32 30 31 39 2d 30 31 2d 32 31  /*.** 2019-01-21
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a  ***************.
0170: 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65 20  **.** This file 
0180: 69 6d 70 6c 65 6d 65 6e 74 73 20 61 6e 20 65 78  implements an ex
0190: 74 65 6e 73 69 6f 6e 20 74 68 61 74 20 75 73 65  tension that use
01a0: 73 20 74 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e  s the SQLITE_CON
01b0: 46 49 47 5f 4d 41 4c 4c 4f 43 0a 2a 2a 20 6d 65  FIG_MALLOC.** me
01c0: 63 68 61 6e 69 73 6d 20 74 6f 20 61 64 64 20 61  chanism to add a
01d0: 20 74 72 61 63 69 6e 67 20 6c 61 79 65 72 20 6f   tracing layer o
01e0: 6e 20 74 6f 70 20 6f 66 20 53 51 4c 69 74 65 2e  n top of SQLite.
01f0: 20 20 49 66 20 74 68 69 73 20 65 78 74 65 6e 73    If this extens
0200: 69 6f 6e 0a 2a 2a 20 69 73 20 72 65 67 69 73 74  ion.** is regist
0210: 65 72 65 64 20 70 72 69 6f 72 20 74 6f 20 73 71  ered prior to sq
0220: 6c 69 74 65 33 5f 69 6e 69 74 69 61 6c 69 7a 65  lite3_initialize
0230: 28 29 2c 20 69 74 20 77 69 6c 6c 20 63 61 75 73  (), it will caus
0240: 65 20 61 6c 6c 20 6d 65 6d 6f 72 79 0a 2a 2a 20  e all memory.** 
0250: 61 6c 6c 6f 63 61 74 69 6f 6e 20 61 63 74 69 76  allocation activ
0260: 69 74 69 65 73 20 74 6f 20 62 65 20 6c 6f 67 67  ities to be logg
0270: 65 64 20 6f 6e 20 73 74 61 6e 64 61 72 64 20 6f  ed on standard o
0280: 75 74 70 75 74 2c 20 6f 72 20 74 6f 20 73 6f 6d  utput, or to som
0290: 65 20 6f 74 68 65 72 0a 2a 2a 20 46 49 4c 45 20  e other.** FILE 
02a0: 73 70 65 63 69 66 69 65 64 20 62 79 20 74 68 65  specified by the
02b0: 20 69 6e 69 74 69 61 6c 69 7a 65 72 2e 0a 2a 2a   initializer..**
02c0: 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65 20 6e 65  .** This file ne
02d0: 65 64 73 20 74 6f 20 62 65 20 63 6f 6d 70 69 6c  eds to be compil
02e0: 65 64 20 69 6e 74 6f 20 74 68 65 20 61 70 70 6c  ed into the appl
02f0: 69 63 61 74 69 6f 6e 20 74 68 61 74 20 75 73 65  ication that use
0300: 73 20 69 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  s it..**.** This
0310: 20 65 78 74 65 6e 73 69 6f 6e 20 69 73 20 75 73   extension is us
0320: 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20  ed to implement 
0330: 74 68 65 20 2d 2d 6d 65 6d 74 72 61 63 65 20 6f  the --memtrace o
0340: 70 74 69 6f 6e 20 6f 66 20 74 68 65 0a 2a 2a 20  ption of the.** 
0350: 63 6f 6d 6d 61 6e 64 2d 6c 69 6e 65 20 73 68 65  command-line she
0360: 6c 6c 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 20  ll..*/.#include 
0370: 3c 61 73 73 65 72 74 2e 68 3e 0a 23 69 6e 63 6c  <assert.h>.#incl
0380: 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23  ude <string.h>.#
0390: 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68  include <stdio.h
03a0: 3e 0a 0a 2f 2a 20 54 68 65 20 6f 72 69 67 69 6e  >../* The origin
03b0: 61 6c 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61  al memory alloca
03c0: 74 69 6f 6e 20 72 6f 75 74 69 6e 65 73 20 2a 2f  tion routines */
03d0: 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f  .static sqlite3_
03e0: 6d 65 6d 5f 6d 65 74 68 6f 64 73 20 6d 65 6d 74  mem_methods memt
03f0: 72 61 63 65 42 61 73 65 3b 0a 73 74 61 74 69 63  raceBase;.static
0400: 20 46 49 4c 45 20 2a 6d 65 6d 74 72 61 63 65 4f   FILE *memtraceO
0410: 75 74 3b 0a 0a 2f 2a 20 4d 65 74 68 6f 64 73 20  ut;../* Methods 
0420: 74 68 61 74 20 74 72 61 63 65 20 6d 65 6d 6f 72  that trace memor
0430: 79 20 61 6c 6c 6f 63 61 74 69 6f 6e 73 20 2a 2f  y allocations */
0440: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a 6d 65  .static void *me
0450: 6d 74 72 61 63 65 4d 61 6c 6c 6f 63 28 69 6e 74  mtraceMalloc(int
0460: 20 6e 29 7b 0a 20 20 69 66 28 20 6d 65 6d 74 72   n){.  if( memtr
0470: 61 63 65 4f 75 74 20 29 7b 0a 20 20 20 20 66 70  aceOut ){.    fp
0480: 72 69 6e 74 66 28 6d 65 6d 74 72 61 63 65 4f 75  rintf(memtraceOu
0490: 74 2c 20 22 4d 45 4d 54 52 41 43 45 3a 20 61 6c  t, "MEMTRACE: al
04a0: 6c 6f 63 61 74 65 20 25 64 20 62 79 74 65 73 5c  locate %d bytes\
04b0: 6e 22 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20  n", .           
04c0: 20 6d 65 6d 74 72 61 63 65 42 61 73 65 2e 78 52   memtraceBase.xR
04d0: 6f 75 6e 64 75 70 28 6e 29 29 3b 0a 20 20 7d 0a  oundup(n));.  }.
04e0: 20 20 72 65 74 75 72 6e 20 6d 65 6d 74 72 61 63    return memtrac
04f0: 65 42 61 73 65 2e 78 4d 61 6c 6c 6f 63 28 6e 29  eBase.xMalloc(n)
0500: 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20  ;.}.static void 
0510: 6d 65 6d 74 72 61 63 65 46 72 65 65 28 76 6f 69  memtraceFree(voi
0520: 64 20 2a 70 29 7b 0a 20 20 69 66 28 20 70 3d 3d  d *p){.  if( p==
0530: 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 69 66  0 ) return;.  if
0540: 28 20 6d 65 6d 74 72 61 63 65 4f 75 74 20 29 7b  ( memtraceOut ){
0550: 0a 20 20 20 20 66 70 72 69 6e 74 66 28 6d 65 6d  .    fprintf(mem
0560: 74 72 61 63 65 4f 75 74 2c 20 22 4d 45 4d 54 52  traceOut, "MEMTR
0570: 41 43 45 3a 20 66 72 65 65 20 25 64 20 62 79 74  ACE: free %d byt
0580: 65 73 5c 6e 22 2c 20 6d 65 6d 74 72 61 63 65 42  es\n", memtraceB
0590: 61 73 65 2e 78 53 69 7a 65 28 70 29 29 3b 0a 20  ase.xSize(p));. 
05a0: 20 7d 0a 20 20 6d 65 6d 74 72 61 63 65 42 61 73   }.  memtraceBas
05b0: 65 2e 78 46 72 65 65 28 70 29 3b 0a 7d 0a 73 74  e.xFree(p);.}.st
05c0: 61 74 69 63 20 76 6f 69 64 20 2a 6d 65 6d 74 72  atic void *memtr
05d0: 61 63 65 52 65 61 6c 6c 6f 63 28 76 6f 69 64 20  aceRealloc(void 
05e0: 2a 70 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 69 66  *p, int n){.  if
05f0: 28 20 70 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  ( p==0 ) return 
0600: 6d 65 6d 74 72 61 63 65 4d 61 6c 6c 6f 63 28 6e  memtraceMalloc(n
0610: 29 3b 0a 20 20 69 66 28 20 6e 3d 3d 30 20 29 7b  );.  if( n==0 ){
0620: 0a 20 20 20 20 6d 65 6d 74 72 61 63 65 46 72 65  .    memtraceFre
0630: 65 28 70 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  e(p);.    return
0640: 20 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20 6d 65   0;.  }.  if( me
0650: 6d 74 72 61 63 65 4f 75 74 20 29 7b 0a 20 20 20  mtraceOut ){.   
0660: 20 66 70 72 69 6e 74 66 28 6d 65 6d 74 72 61 63   fprintf(memtrac
0670: 65 4f 75 74 2c 20 22 4d 45 4d 54 52 41 43 45 3a  eOut, "MEMTRACE:
0680: 20 72 65 73 69 7a 65 20 25 64 20 2d 3e 20 25 64   resize %d -> %d
0690: 20 62 79 74 65 73 5c 6e 22 2c 0a 20 20 20 20 20   bytes\n",.     
06a0: 20 20 20 20 20 20 20 6d 65 6d 74 72 61 63 65 42         memtraceB
06b0: 61 73 65 2e 78 53 69 7a 65 28 70 29 2c 20 6d 65  ase.xSize(p), me
06c0: 6d 74 72 61 63 65 42 61 73 65 2e 78 52 6f 75 6e  mtraceBase.xRoun
06d0: 64 75 70 28 6e 29 29 3b 0a 20 20 7d 0a 20 20 72  dup(n));.  }.  r
06e0: 65 74 75 72 6e 20 6d 65 6d 74 72 61 63 65 42 61  eturn memtraceBa
06f0: 73 65 2e 78 52 65 61 6c 6c 6f 63 28 70 2c 20 6e  se.xRealloc(p, n
0700: 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20  );.}.static int 
0710: 6d 65 6d 74 72 61 63 65 53 69 7a 65 28 76 6f 69  memtraceSize(voi
0720: 64 20 2a 70 29 7b 0a 20 20 72 65 74 75 72 6e 20  d *p){.  return 
0730: 6d 65 6d 74 72 61 63 65 42 61 73 65 2e 78 53 69  memtraceBase.xSi
0740: 7a 65 28 70 29 3b 0a 7d 0a 73 74 61 74 69 63 20  ze(p);.}.static 
0750: 69 6e 74 20 6d 65 6d 74 72 61 63 65 52 6f 75 6e  int memtraceRoun
0760: 64 75 70 28 69 6e 74 20 6e 29 7b 0a 20 20 72 65  dup(int n){.  re
0770: 74 75 72 6e 20 6d 65 6d 74 72 61 63 65 42 61 73  turn memtraceBas
0780: 65 2e 78 52 6f 75 6e 64 75 70 28 6e 29 3b 0a 7d  e.xRoundup(n);.}
0790: 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 65 6d 74  .static int memt
07a0: 72 61 63 65 49 6e 69 74 28 76 6f 69 64 20 2a 70  raceInit(void *p
07b0: 29 7b 0a 20 20 72 65 74 75 72 6e 20 6d 65 6d 74  ){.  return memt
07c0: 72 61 63 65 42 61 73 65 2e 78 49 6e 69 74 28 70  raceBase.xInit(p
07d0: 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64  );.}.static void
07e0: 20 6d 65 6d 74 72 61 63 65 53 68 75 74 64 6f 77   memtraceShutdow
07f0: 6e 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 6d 65  n(void *p){.  me
0800: 6d 74 72 61 63 65 42 61 73 65 2e 78 53 68 75 74  mtraceBase.xShut
0810: 64 6f 77 6e 28 70 29 3b 0a 7d 0a 0a 2f 2a 20 54  down(p);.}../* T
0820: 68 65 20 73 75 62 73 74 69 74 75 74 65 20 6d 65  he substitute me
0830: 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 6f 72 20 2a  mory allocator *
0840: 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33  /.static sqlite3
0850: 5f 6d 65 6d 5f 6d 65 74 68 6f 64 73 20 65 72 73  _mem_methods ers
0860: 61 7a 74 4d 65 74 68 6f 64 73 20 3d 20 7b 0a 20  aztMethods = {. 
0870: 20 6d 65 6d 74 72 61 63 65 4d 61 6c 6c 6f 63 2c   memtraceMalloc,
0880: 0a 20 20 6d 65 6d 74 72 61 63 65 46 72 65 65 2c  .  memtraceFree,
0890: 0a 20 20 6d 65 6d 74 72 61 63 65 52 65 61 6c 6c  .  memtraceReall
08a0: 6f 63 2c 0a 20 20 6d 65 6d 74 72 61 63 65 53 69  oc,.  memtraceSi
08b0: 7a 65 2c 0a 20 20 6d 65 6d 74 72 61 63 65 52 6f  ze,.  memtraceRo
08c0: 75 6e 64 75 70 2c 0a 20 20 6d 65 6d 74 72 61 63  undup,.  memtrac
08d0: 65 49 6e 69 74 2c 0a 20 20 6d 65 6d 74 72 61 63  eInit,.  memtrac
08e0: 65 53 68 75 74 64 6f 77 6e 2c 0a 20 20 30 0a 7d  eShutdown,.  0.}
08f0: 3b 0a 0a 2f 2a 20 42 65 67 69 6e 20 74 72 61 63  ;../* Begin trac
0900: 69 6e 67 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63  ing memory alloc
0910: 61 74 69 6f 6e 73 20 74 6f 20 6f 75 74 2e 20 2a  ations to out. *
0920: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 4d 65 6d  /.int sqlite3Mem
0930: 54 72 61 63 65 41 63 74 69 76 61 74 65 28 46 49  TraceActivate(FI
0940: 4c 45 20 2a 6f 75 74 29 7b 0a 20 20 69 6e 74 20  LE *out){.  int 
0950: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
0960: 20 20 69 66 28 20 6d 65 6d 74 72 61 63 65 42 61    if( memtraceBa
0970: 73 65 2e 78 4d 61 6c 6c 6f 63 3d 3d 30 20 29 7b  se.xMalloc==0 ){
0980: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
0990: 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45 5f  3_config(SQLITE_
09a0: 43 4f 4e 46 49 47 5f 47 45 54 4d 41 4c 4c 4f 43  CONFIG_GETMALLOC
09b0: 2c 20 26 6d 65 6d 74 72 61 63 65 42 61 73 65 29  , &memtraceBase)
09c0: 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
09d0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
09e0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f   rc = sqlite3_co
09f0: 6e 66 69 67 28 53 51 4c 49 54 45 5f 43 4f 4e 46  nfig(SQLITE_CONF
0a00: 49 47 5f 4d 41 4c 4c 4f 43 2c 20 26 65 72 73 61  IG_MALLOC, &ersa
0a10: 7a 74 4d 65 74 68 6f 64 73 29 3b 0a 20 20 20 20  ztMethods);.    
0a20: 7d 0a 20 20 7d 0a 20 20 6d 65 6d 74 72 61 63 65  }.  }.  memtrace
0a30: 4f 75 74 20 3d 20 6f 75 74 3b 0a 20 20 72 65 74  Out = out;.  ret
0a40: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 44 65  urn rc;.}../* De
0a50: 61 63 74 69 76 61 74 65 20 6d 65 6d 6f 72 79 20  activate memory 
0a60: 74 72 61 63 69 6e 67 20 2a 2f 0a 69 6e 74 20 73  tracing */.int s
0a70: 71 6c 69 74 65 33 4d 65 6d 54 72 61 63 65 44 65  qlite3MemTraceDe
0a80: 61 63 74 69 76 61 74 65 28 76 6f 69 64 29 7b 0a  activate(void){.
0a90: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
0aa0: 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 6d 65 6d 74  E_OK;.  if( memt
0ab0: 72 61 63 65 42 61 73 65 2e 78 4d 61 6c 6c 6f 63  raceBase.xMalloc
0ac0: 21 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  !=0 ){.    rc = 
0ad0: 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53  sqlite3_config(S
0ae0: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 4d 41 4c  QLITE_CONFIG_MAL
0af0: 4c 4f 43 2c 20 26 6d 65 6d 74 72 61 63 65 42 61  LOC, &memtraceBa
0b00: 73 65 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d  se);.    if( rc=
0b10: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
0b20: 20 20 20 20 6d 65 6d 73 65 74 28 26 6d 65 6d 74      memset(&memt
0b30: 72 61 63 65 42 61 73 65 2c 20 30 2c 20 73 69 7a  raceBase, 0, siz
0b40: 65 6f 66 28 6d 65 6d 74 72 61 63 65 42 61 73 65  eof(memtraceBase
0b50: 29 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  ));.    }.  }.  
0b60: 6d 65 6d 74 72 61 63 65 4f 75 74 20 3d 20 30 3b  memtraceOut = 0;
0b70: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.