Fixes default log output to console for macOS
[sqlcipher.git] / ext / misc / pcachetrace.c
blob3757d8d4d56351c42c98355dc54ae10f5d2c4b5d
1 /*
2 ** 2023-06-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.
11 *************************************************************************
13 ** This file implements an extension that uses the SQLITE_CONFIG_PCACHE2
14 ** mechanism to add a tracing layer on top of pluggable page cache of
15 ** SQLite. If this extension is registered prior to sqlite3_initialize(),
16 ** it will cause all page cache activities to be logged on standard output,
17 ** or to some other FILE specified by the initializer.
19 ** This file needs to be compiled into the application that uses it.
21 ** This extension is used to implement the --pcachetrace option of the
22 ** command-line shell.
24 #include <assert.h>
25 #include <string.h>
26 #include <stdio.h>
28 /* The original page cache routines */
29 static sqlite3_pcache_methods2 pcacheBase;
30 static FILE *pcachetraceOut;
32 /* Methods that trace pcache activity */
33 static int pcachetraceInit(void *pArg){
34 int nRes;
35 if( pcachetraceOut ){
36 fprintf(pcachetraceOut, "PCACHETRACE: xInit(%p)\n", pArg);
38 nRes = pcacheBase.xInit(pArg);
39 if( pcachetraceOut ){
40 fprintf(pcachetraceOut, "PCACHETRACE: xInit(%p) -> %d\n", pArg, nRes);
42 return nRes;
44 static void pcachetraceShutdown(void *pArg){
45 if( pcachetraceOut ){
46 fprintf(pcachetraceOut, "PCACHETRACE: xShutdown(%p)\n", pArg);
48 pcacheBase.xShutdown(pArg);
50 static sqlite3_pcache *pcachetraceCreate(int szPage, int szExtra, int bPurge){
51 sqlite3_pcache *pRes;
52 if( pcachetraceOut ){
53 fprintf(pcachetraceOut, "PCACHETRACE: xCreate(%d,%d,%d)\n",
54 szPage, szExtra, bPurge);
56 pRes = pcacheBase.xCreate(szPage, szExtra, bPurge);
57 if( pcachetraceOut ){
58 fprintf(pcachetraceOut, "PCACHETRACE: xCreate(%d,%d,%d) -> %p\n",
59 szPage, szExtra, bPurge, pRes);
61 return pRes;
63 static void pcachetraceCachesize(sqlite3_pcache *p, int nCachesize){
64 if( pcachetraceOut ){
65 fprintf(pcachetraceOut, "PCACHETRACE: xCachesize(%p, %d)\n", p, nCachesize);
67 pcacheBase.xCachesize(p, nCachesize);
69 static int pcachetracePagecount(sqlite3_pcache *p){
70 int nRes;
71 if( pcachetraceOut ){
72 fprintf(pcachetraceOut, "PCACHETRACE: xPagecount(%p)\n", p);
74 nRes = pcacheBase.xPagecount(p);
75 if( pcachetraceOut ){
76 fprintf(pcachetraceOut, "PCACHETRACE: xPagecount(%p) -> %d\n", p, nRes);
78 return nRes;
80 static sqlite3_pcache_page *pcachetraceFetch(
81 sqlite3_pcache *p,
82 unsigned key,
83 int crFg
85 sqlite3_pcache_page *pRes;
86 if( pcachetraceOut ){
87 fprintf(pcachetraceOut, "PCACHETRACE: xFetch(%p,%u,%d)\n", p, key, crFg);
89 pRes = pcacheBase.xFetch(p, key, crFg);
90 if( pcachetraceOut ){
91 fprintf(pcachetraceOut, "PCACHETRACE: xFetch(%p,%u,%d) -> %p\n",
92 p, key, crFg, pRes);
94 return pRes;
96 static void pcachetraceUnpin(
97 sqlite3_pcache *p,
98 sqlite3_pcache_page *pPg,
99 int bDiscard
101 if( pcachetraceOut ){
102 fprintf(pcachetraceOut, "PCACHETRACE: xUnpin(%p, %p, %d)\n",
103 p, pPg, bDiscard);
105 pcacheBase.xUnpin(p, pPg, bDiscard);
107 static void pcachetraceRekey(
108 sqlite3_pcache *p,
109 sqlite3_pcache_page *pPg,
110 unsigned oldKey,
111 unsigned newKey
113 if( pcachetraceOut ){
114 fprintf(pcachetraceOut, "PCACHETRACE: xRekey(%p, %p, %u, %u)\n",
115 p, pPg, oldKey, newKey);
117 pcacheBase.xRekey(p, pPg, oldKey, newKey);
119 static void pcachetraceTruncate(sqlite3_pcache *p, unsigned n){
120 if( pcachetraceOut ){
121 fprintf(pcachetraceOut, "PCACHETRACE: xTruncate(%p, %u)\n", p, n);
123 pcacheBase.xTruncate(p, n);
125 static void pcachetraceDestroy(sqlite3_pcache *p){
126 if( pcachetraceOut ){
127 fprintf(pcachetraceOut, "PCACHETRACE: xDestroy(%p)\n", p);
129 pcacheBase.xDestroy(p);
131 static void pcachetraceShrink(sqlite3_pcache *p){
132 if( pcachetraceOut ){
133 fprintf(pcachetraceOut, "PCACHETRACE: xShrink(%p)\n", p);
135 pcacheBase.xShrink(p);
138 /* The substitute pcache methods */
139 static sqlite3_pcache_methods2 ersaztPcacheMethods = {
142 pcachetraceInit,
143 pcachetraceShutdown,
144 pcachetraceCreate,
145 pcachetraceCachesize,
146 pcachetracePagecount,
147 pcachetraceFetch,
148 pcachetraceUnpin,
149 pcachetraceRekey,
150 pcachetraceTruncate,
151 pcachetraceDestroy,
152 pcachetraceShrink
155 /* Begin tracing memory allocations to out. */
156 int sqlite3PcacheTraceActivate(FILE *out){
157 int rc = SQLITE_OK;
158 if( pcacheBase.xFetch==0 ){
159 rc = sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &pcacheBase);
160 if( rc==SQLITE_OK ){
161 rc = sqlite3_config(SQLITE_CONFIG_PCACHE2, &ersaztPcacheMethods);
164 pcachetraceOut = out;
165 return rc;
168 /* Deactivate memory tracing */
169 int sqlite3PcacheTraceDeactivate(void){
170 int rc = SQLITE_OK;
171 if( pcacheBase.xFetch!=0 ){
172 rc = sqlite3_config(SQLITE_CONFIG_PCACHE2, &pcacheBase);
173 if( rc==SQLITE_OK ){
174 memset(&pcacheBase, 0, sizeof(pcacheBase));
177 pcachetraceOut = 0;
178 return rc;