mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-hlr.git
synced 2025-11-03 05:33:28 +00:00
This change introduces an optional feature that allows to make
SQLite3 use talloc for all internal allocations. This would
facilitate finding memleaks. OsmoHLR needs to be configured
with '--enable-sqlite-talloc'.
full talloc report on 'OsmoHLR' (total 292168 bytes in 449 blocks)
struct osmo_gsup_server contains 162 bytes in 3 blocks (ref 0)
...
struct db_context contains 288407 bytes in 420 blocks (ref 0)
hlr.db contains 7 bytes in 1 blocks (ref 0)
SQLite3 contains 288192 bytes in 418 blocks (ref 0)
db.c:95 contains 48 bytes in 1 blocks (ref 0)
db.c:95 contains 2 bytes in 1 blocks (ref 0)
...
Unfortunately, old SQLite3 versions (such as 3.8.2) run out
of memory when trying to initialize a new database:
DDB ERROR db.c:88 (7) statement aborts at 3: []
DDB ERROR db.c:420 Unable to set Write-Ahead Logging: out of memory
DDB ERROR db.c:88 (7) statement aborts at 3: []
DDB ERROR db.c:238 Unable to prepare SQL statement
'SELECT name FROM sqlite_master WHERE type='table' AND name=?'
...
I've noticed a huge difference in heap usage footprint compared to
generic malloc. At the same time, the recent versions (at least
3.24.0), work just fine.
Change-Id: Icfe67ed0f063b63e6794f9516da3003d01cf20a7
87 lines
2.3 KiB
C
87 lines
2.3 KiB
C
/*
|
|
* libtalloc based memory allocator for SQLite3.
|
|
*
|
|
* (C) 2019 by Vadim Yanitskiy <axilirator@gmail.com>
|
|
*
|
|
* All Rights Reserved
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include <sqlite3.h>
|
|
#include <talloc.h>
|
|
#include <errno.h>
|
|
|
|
/* Dedicated talloc context for SQLite */
|
|
static void *db_sqlite_ctx = NULL;
|
|
|
|
static void *tall_xMalloc(int size)
|
|
{
|
|
return talloc_size(db_sqlite_ctx, size);
|
|
}
|
|
|
|
static void tall_xFree(void *ptr)
|
|
{
|
|
talloc_free(ptr);
|
|
}
|
|
|
|
static void *tall_xRealloc(void *ptr, int size)
|
|
{
|
|
return talloc_realloc_fn(db_sqlite_ctx, ptr, size);
|
|
}
|
|
|
|
static int tall_xSize(void *ptr)
|
|
{
|
|
return talloc_total_size(ptr);
|
|
}
|
|
|
|
/* DUMMY: talloc doesn't round up the allocation size */
|
|
static int tall_xRoundup(int size) { return size; }
|
|
|
|
/* DUMMY: nothing to initialize */
|
|
static int tall_xInit(void *data) { return 0; }
|
|
|
|
/* DUMMY: nothing to deinitialize */
|
|
static void tall_xShutdown(void *data) { }
|
|
|
|
/* Interface between SQLite and talloc memory allocator */
|
|
static const struct sqlite3_mem_methods tall_sqlite_if = {
|
|
/* Memory allocation function */
|
|
.xMalloc = &tall_xMalloc,
|
|
/* Free a prior allocation */
|
|
.xFree = &tall_xFree,
|
|
/* Resize an allocation */
|
|
.xRealloc = &tall_xRealloc,
|
|
/* Return the size of an allocation */
|
|
.xSize = &tall_xSize,
|
|
/* Round up request size to allocation size */
|
|
.xRoundup = &tall_xRoundup,
|
|
/* Initialize the memory allocator */
|
|
.xInit = &tall_xInit,
|
|
/* Deinitialize the memory allocator */
|
|
.xShutdown = &tall_xShutdown,
|
|
/* Argument to xInit() and xShutdown() */
|
|
.pAppData = NULL,
|
|
};
|
|
|
|
int db_sqlite3_use_talloc(void *ctx)
|
|
{
|
|
if (db_sqlite_ctx != NULL)
|
|
return -EEXIST;
|
|
|
|
db_sqlite_ctx = talloc_named_const(ctx, 0, "SQLite3");
|
|
return sqlite3_config(SQLITE_CONFIG_MALLOC, &tall_sqlite_if);
|
|
}
|