/ Check-in [d11e8e30]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Make sure all memory allocations are 8-byte aligned. Ticket #3040. Note that the mem3.c memory allocator returns 4-byte aligned memory allocations. But as mem3.c is intended for use in 32-bit embedded systems, we are not going to change that. (CVS 4978)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d11e8e307af906db75ae7aede790464fabd06422
User & Date: drh 2008-04-10 14:57:25
Context
2008-04-10
15:12
Verify that a RAISE(ROLLBACK,...) works like RAISE(FAIL,...) when not inside a transaction. Ticket #3035. (CVS 4979) check-in: 87dc82d0 user: drh tags: trunk
14:57
Make sure all memory allocations are 8-byte aligned. Ticket #3040. Note that the mem3.c memory allocator returns 4-byte aligned memory allocations. But as mem3.c is intended for use in 32-bit embedded systems, we are not going to change that. (CVS 4978) check-in: d11e8e30 user: drh tags: trunk
14:51
Add source file test_osinst.c. A wrapper vfs with instrumentation capabilities. (CVS 4977) check-in: d9a6b653 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/mem2.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
...
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
...
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
...
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement a memory
** allocation subsystem for use by SQLite.  
**
** $Id: mem2.c,v 1.25 2008/04/03 10:13:01 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** This version of the memory allocator is used only if the
** SQLITE_MEMDEBUG macro is defined
*/
................................................................................
** The application code sees only a pointer to the allocation.  We have
** to back up from the allocation pointer to find the MemBlockHdr.  The
** MemBlockHdr tells us the size of the allocation and the number of
** backtrace pointers.  There is also a guard word at the end of the
** MemBlockHdr.
*/
struct MemBlockHdr {

  struct MemBlockHdr *pNext, *pPrev;  /* Linked list of all unfreed memory */
  int iSize;                          /* Size of this allocation */
  char nBacktrace;                    /* Number of backtraces on this alloc */
  char nBacktraceSlots;               /* Available backtrace slots */
  short nTitle;                       /* Bytes of title; includes '\0' */
  int iForeGuard;                     /* Guard word for sanity */
};

/*
................................................................................
  int *pInt;
  u8 *pU8;
  int nReserve;

  p = (struct MemBlockHdr*)pAllocation;
  p--;
  assert( p->iForeGuard==FOREGUARD );
  nReserve = (p->iSize+3)&~3;
  pInt = (int*)pAllocation;
  pU8 = (u8*)pAllocation;
  assert( pInt[nReserve/sizeof(int)]==REARGUARD );
  assert( (nReserve-0)<=p->iSize || pU8[nReserve-1]==0x65 );
  assert( (nReserve-1)<=p->iSize || pU8[nReserve-2]==0x65 );
  assert( (nReserve-2)<=p->iSize || pU8[nReserve-3]==0x65 );
  return p;
................................................................................
  if( nByte>0 ){
    int nReserve;
    enterMem();
    assert( mem.disallow==0 );
    if( mem.alarmCallback!=0 && mem.nowUsed+nByte>=mem.alarmThreshold ){
      sqlite3MemsysAlarm(nByte);
    }
    nReserve = (nByte+3)&~3;
    if( nReserve/8>NCSIZE-1 ){
      mem.sizeCnt[NCSIZE-1]++;
    }else{
      mem.sizeCnt[nReserve/8]++;
    }
    totalSize = nReserve + sizeof(*pHdr) + sizeof(int) +
                 mem.nBacktrace*sizeof(void*) + mem.nTitle;
................................................................................
*/
void sqlite3MemdebugSettitle(const char *zTitle){
  int n = strlen(zTitle) + 1;
  enterMem();
  if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1;
  memcpy(mem.zTitle, zTitle, n);
  mem.zTitle[n] = 0;
  mem.nTitle = (n+3)&~3;
  sqlite3_mutex_leave(mem.mutex);
}

void sqlite3MemdebugSync(){
  struct MemBlockHdr *pHdr;
  for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
    void **pBt = (void**)pHdr;
................................................................................
    fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
                    zFilename);
    return;
  }
  for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
    char *z = (char*)pHdr;
    z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle;
    fprintf(out, "**** %d bytes at %p from %s ****\n", 
            pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???");
    if( pHdr->nBacktrace ){
      fflush(out);
      pBt = (void**)pHdr;
      pBt -= pHdr->nBacktraceSlots;
      backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out));
      fprintf(out, "\n");







|







 







>

<







 







|







 







|







 







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
...
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
...
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
...
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement a memory
** allocation subsystem for use by SQLite.  
**
** $Id: mem2.c,v 1.26 2008/04/10 14:57:25 drh Exp $
*/
#include "sqliteInt.h"

/*
** This version of the memory allocator is used only if the
** SQLITE_MEMDEBUG macro is defined
*/
................................................................................
** The application code sees only a pointer to the allocation.  We have
** to back up from the allocation pointer to find the MemBlockHdr.  The
** MemBlockHdr tells us the size of the allocation and the number of
** backtrace pointers.  There is also a guard word at the end of the
** MemBlockHdr.
*/
struct MemBlockHdr {
  i64 iSize;                          /* Size of this allocation */
  struct MemBlockHdr *pNext, *pPrev;  /* Linked list of all unfreed memory */

  char nBacktrace;                    /* Number of backtraces on this alloc */
  char nBacktraceSlots;               /* Available backtrace slots */
  short nTitle;                       /* Bytes of title; includes '\0' */
  int iForeGuard;                     /* Guard word for sanity */
};

/*
................................................................................
  int *pInt;
  u8 *pU8;
  int nReserve;

  p = (struct MemBlockHdr*)pAllocation;
  p--;
  assert( p->iForeGuard==FOREGUARD );
  nReserve = (p->iSize+7)&~7;
  pInt = (int*)pAllocation;
  pU8 = (u8*)pAllocation;
  assert( pInt[nReserve/sizeof(int)]==REARGUARD );
  assert( (nReserve-0)<=p->iSize || pU8[nReserve-1]==0x65 );
  assert( (nReserve-1)<=p->iSize || pU8[nReserve-2]==0x65 );
  assert( (nReserve-2)<=p->iSize || pU8[nReserve-3]==0x65 );
  return p;
................................................................................
  if( nByte>0 ){
    int nReserve;
    enterMem();
    assert( mem.disallow==0 );
    if( mem.alarmCallback!=0 && mem.nowUsed+nByte>=mem.alarmThreshold ){
      sqlite3MemsysAlarm(nByte);
    }
    nReserve = (nByte+7)&~7;
    if( nReserve/8>NCSIZE-1 ){
      mem.sizeCnt[NCSIZE-1]++;
    }else{
      mem.sizeCnt[nReserve/8]++;
    }
    totalSize = nReserve + sizeof(*pHdr) + sizeof(int) +
                 mem.nBacktrace*sizeof(void*) + mem.nTitle;
................................................................................
*/
void sqlite3MemdebugSettitle(const char *zTitle){
  int n = strlen(zTitle) + 1;
  enterMem();
  if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1;
  memcpy(mem.zTitle, zTitle, n);
  mem.zTitle[n] = 0;
  mem.nTitle = (n+7)&~7;
  sqlite3_mutex_leave(mem.mutex);
}

void sqlite3MemdebugSync(){
  struct MemBlockHdr *pHdr;
  for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
    void **pBt = (void**)pHdr;
................................................................................
    fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
                    zFilename);
    return;
  }
  for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
    char *z = (char*)pHdr;
    z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle;
    fprintf(out, "**** %lld bytes at %p from %s ****\n", 
            pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???");
    if( pHdr->nBacktrace ){
      fflush(out);
      pBt = (void**)pHdr;
      pBt -= pHdr->nBacktraceSlots;
      backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out));
      fprintf(out, "\n");

Changes to src/vdbeaux.c.

2061
2062
2063
2064
2065
2066
2067



2068
2069
2070
2071
2072
2073
2074
....
2193
2194
2195
2196
2197
2198
2199

2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
** and store the result in pMem.  Return the number of bytes read.
*/ 
int sqlite3VdbeSerialGet(
  const unsigned char *buf,     /* Buffer to deserialize from */
  u32 serial_type,              /* Serial type to deserialize */
  Mem *pMem                     /* Memory cell to write value into */
){



  switch( serial_type ){
    case 10:   /* Reserved for future use */
    case 11:   /* Reserved for future use */
    case 0: {  /* NULL */
      pMem->flags = MEM_Null;
      break;
    }
................................................................................
  const unsigned char *aKey = (const unsigned char *)pKey;
  UnpackedRecord *p;
  int nByte;
  int i, idx, d;
  u32 szHdr;
  Mem *pMem;
  

  nByte = sizeof(*p) + sizeof(Mem)*(pKeyInfo->nField+1);
  if( nByte>szSpace ){
    p = sqlite3DbMallocRaw(pKeyInfo->db, nByte);
    if( p==0 ) return 0;
    p->needFree = 1;
  }else{
    p = pSpace;
    p->needFree = 0;
  }
  p->pKeyInfo = pKeyInfo;
  p->nField = pKeyInfo->nField + 1;
  p->needDestroy = 1;
  p->aMem = pMem = (Mem*)&p[1];
  idx = GetVarint(aKey, szHdr);
  d = szHdr;
  i = 0;
  while( idx<szHdr && i<p->nField ){
    u32 serial_type;

    idx += GetVarint( aKey+idx, serial_type);







>
>
>







 







>
|











|







2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
....
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
** and store the result in pMem.  Return the number of bytes read.
*/ 
int sqlite3VdbeSerialGet(
  const unsigned char *buf,     /* Buffer to deserialize from */
  u32 serial_type,              /* Serial type to deserialize */
  Mem *pMem                     /* Memory cell to write value into */
){
#ifndef SQLITE_MEMORY_SIZE
  assert( (7&(int)pMem)==0 );   /* Verify 8-byte alignment.  Ticket #3040 */
#endif
  switch( serial_type ){
    case 10:   /* Reserved for future use */
    case 11:   /* Reserved for future use */
    case 0: {  /* NULL */
      pMem->flags = MEM_Null;
      break;
    }
................................................................................
  const unsigned char *aKey = (const unsigned char *)pKey;
  UnpackedRecord *p;
  int nByte;
  int i, idx, d;
  u32 szHdr;
  Mem *pMem;
  
  assert( sizeof(Mem)>sizeof(*p) );
  nByte = sizeof(Mem)*(pKeyInfo->nField+2);
  if( nByte>szSpace ){
    p = sqlite3DbMallocRaw(pKeyInfo->db, nByte);
    if( p==0 ) return 0;
    p->needFree = 1;
  }else{
    p = pSpace;
    p->needFree = 0;
  }
  p->pKeyInfo = pKeyInfo;
  p->nField = pKeyInfo->nField + 1;
  p->needDestroy = 1;
  p->aMem = pMem = &((Mem*)p)[1];
  idx = GetVarint(aKey, szHdr);
  d = szHdr;
  i = 0;
  while( idx<szHdr && i<p->nField ){
    u32 serial_type;

    idx += GetVarint( aKey+idx, serial_type);