Kannel: Open Source WAP and SMS gateway  svn-r5335
gwmem-check.c File Reference
#include "gw-config.h"
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include "gwlib.h"

Go to the source code of this file.

Data Structures

struct  location
 
struct  area
 

Macros

#define NEW_AREA_PATTERN   0xcafebabe
 
#define FREE_AREA_PATTERN   0xdeadbeef
 
#define START_MARK_PATTERN   0xdadaface
 
#define END_MARK_PATTERN   0xadadafec
 
#define MAX_DUMP   16
 
#define MARKER_SIZE   16
 
#define MAX_TAB_SIZE   (100*1024*1024L)
 
#define MAX_ALLOCATIONS   ((long) (MAX_TAB_SIZE/sizeof(struct area)))
 
#define FREE_RING_SIZE   1024
 

Functions

static void lock (void)
 
static void unlock (void)
 
static unsigned long round_pow2 (unsigned long num)
 
static void fill (unsigned char *p, size_t bytes, long pattern)
 
static int untouched (unsigned char *p, size_t bytes, long pattern)
 
static void endmark (unsigned char *p, size_t size)
 
static void startmark (unsigned char *p, long number)
 
static long check_startmark (unsigned char *p)
 
static int check_endmark (unsigned char *p, size_t size)
 
static int check_marks (struct area *area, long index)
 
static void dump_area (struct area *area)
 
static struct areafind_area (unsigned char *p)
 
static void change_total_size (long change)
 
static struct arearecord_allocation (unsigned char *p, size_t size, const char *filename, long lineno, const char *function)
 
static void remove_allocation (struct area *area)
 
static void drop_from_free_ring (long index)
 
static void put_on_free_ring (struct area *area)
 
static void free_area (struct area *area)
 
void gw_check_init_mem (int slow_flag)
 
void gw_check_shutdown (void)
 
void * gw_check_malloc (size_t size, const char *filename, long lineno, const char *function)
 
void * gw_check_calloc (int nmemb, size_t size, const char *filename, long lineno, const char *function)
 
void * gw_check_realloc (void *p, size_t size, const char *filename, long lineno, const char *function)
 
void gw_check_free (void *p, const char *filename, long lineno, const char *function)
 
char * gw_check_strdup (const char *str, const char *filename, long lineno, const char *function)
 
void * gw_check_claim_area (void *p, const char *filename, long lineno, const char *function)
 
void gw_check_check_leaks (void)
 
int gw_check_is_allocated (void *p)
 
long gw_check_area_size (void *p)
 

Variables

static int initialized = 0
 
static int slow = 0
 
static Mutex gwmem_lock
 
static struct area allocated [MAX_ALLOCATIONS]
 
static struct area free_ring [FREE_RING_SIZE]
 
static long num_allocations
 
static long free_ring_start
 
static long free_ring_len
 
static long highest_num_allocations
 
static long highest_total_size
 
static long total_size
 

Macro Definition Documentation

◆ END_MARK_PATTERN

#define END_MARK_PATTERN   0xadadafec

Definition at line 122 of file gwmem-check.c.

Referenced by check_endmark(), endmark(), and find_area().

◆ FREE_AREA_PATTERN

#define FREE_AREA_PATTERN   0xdeadbeef

Definition at line 115 of file gwmem-check.c.

Referenced by drop_from_free_ring(), find_area(), and free_area().

◆ FREE_RING_SIZE

#define FREE_RING_SIZE   1024

Definition at line 175 of file gwmem-check.c.

Referenced by put_on_free_ring().

◆ MARKER_SIZE

◆ MAX_ALLOCATIONS

#define MAX_ALLOCATIONS   ((long) (MAX_TAB_SIZE/sizeof(struct area)))

Definition at line 168 of file gwmem-check.c.

Referenced by record_allocation().

◆ MAX_DUMP

#define MAX_DUMP   16

Definition at line 125 of file gwmem-check.c.

Referenced by dump_area().

◆ MAX_TAB_SIZE

#define MAX_TAB_SIZE   (100*1024*1024L)

Definition at line 167 of file gwmem-check.c.

◆ NEW_AREA_PATTERN

#define NEW_AREA_PATTERN   0xcafebabe

Definition at line 111 of file gwmem-check.c.

Referenced by find_area(), gw_check_malloc(), and gw_check_realloc().

◆ START_MARK_PATTERN

#define START_MARK_PATTERN   0xdadaface

Definition at line 119 of file gwmem-check.c.

Referenced by check_startmark(), find_area(), and startmark().

Function Documentation

◆ change_total_size()

static void change_total_size ( long  change)
static

Definition at line 411 of file gwmem-check.c.

References highest_total_size, and total_size.

Referenced by gw_check_realloc(), record_allocation(), and remove_allocation().

412 {
413  total_size += change;
416 }
static long total_size
Definition: gwmem-check.c:194
static long highest_total_size
Definition: gwmem-check.c:192

◆ check_endmark()

static int check_endmark ( unsigned char *  p,
size_t  size 
)
static

Definition at line 286 of file gwmem-check.c.

References END_MARK_PATTERN, MARKER_SIZE, size, and untouched().

Referenced by check_marks(), and find_area().

287 {
289  return -1;
290  return 0;
291 }
int size
Definition: wsasm.c:84
#define END_MARK_PATTERN
Definition: gwmem-check.c:122
#define MARKER_SIZE
Definition: gwmem-check.c:164
static int untouched(unsigned char *p, size_t bytes, long pattern)
Definition: gwmem-check.c:241

◆ check_marks()

static int check_marks ( struct area area,
long  index 
)
static

Definition at line 293 of file gwmem-check.c.

References area::area, area::area_size, check_endmark(), check_startmark(), and error().

Referenced by drop_from_free_ring(), gw_check_check_leaks(), and remove_allocation().

294 {
295  int result = 0;
296 
297  if (check_startmark(area->area) != index) {
298  error(0, "Start marker was damaged for area %ld", index);
299  result = -1;
300  }
301  if (check_endmark(area->area, area->area_size) < 0) {
302  error(0, "End marker was damaged for area %ld", index);
303  result = -1;
304  }
305 
306  return result;
307 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static int check_endmark(unsigned char *p, size_t size)
Definition: gwmem-check.c:286
static long check_startmark(unsigned char *p)
Definition: gwmem-check.c:276
size_t area_size
Definition: gwmem-check.c:150
void * area
Definition: gwmem-check.c:149

◆ check_startmark()

static long check_startmark ( unsigned char *  p)
static

Definition at line 276 of file gwmem-check.c.

References MARKER_SIZE, number, START_MARK_PATTERN, and untouched().

Referenced by check_marks(), and find_area().

277 {
278  long number;
279  if (!untouched(p - MARKER_SIZE + sizeof(long),
280  MARKER_SIZE - sizeof(long), START_MARK_PATTERN))
281  return -1;
282  memcpy(&number, p - MARKER_SIZE, sizeof(number));
283  return number;
284 }
int number
Definition: smsc_cimd2.c:213
#define START_MARK_PATTERN
Definition: gwmem-check.c:119
#define MARKER_SIZE
Definition: gwmem-check.c:164
static int untouched(unsigned char *p, size_t bytes, long pattern)
Definition: gwmem-check.c:241

◆ drop_from_free_ring()

static void drop_from_free_ring ( long  index)
static

Definition at line 462 of file gwmem-check.c.

References area::area, area::area_size, check_marks(), dump_area(), error(), free(), FREE_AREA_PATTERN, free_ring, MARKER_SIZE, and untouched().

Referenced by gw_check_check_leaks(), and put_on_free_ring().

463 {
464  struct area *area;
465 
466  area = &free_ring[index];
467  if (check_marks(area, index) < 0 ||
469  error(0, "Freed area %p has been tampered with.", area->area);
470  dump_area(area);
471  }
472  free((unsigned char *)area->area - MARKER_SIZE);
473 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static void dump_area(struct area *area)
Definition: gwmem-check.c:309
#define FREE_AREA_PATTERN
Definition: gwmem-check.c:115
static struct area free_ring[FREE_RING_SIZE]
Definition: gwmem-check.c:178
size_t area_size
Definition: gwmem-check.c:150
void free(void *)
static int check_marks(struct area *area, long index)
Definition: gwmem-check.c:293
#define MARKER_SIZE
Definition: gwmem-check.c:164
static int untouched(unsigned char *p, size_t bytes, long pattern)
Definition: gwmem-check.c:241
void * area
Definition: gwmem-check.c:149

◆ dump_area()

static void dump_area ( struct area area)
static

Definition at line 309 of file gwmem-check.c.

References area::allocator, area::area, area::area_size, area::claimer, debug(), location::filename, free(), location::function, location::lineno, MAX_DUMP, area::max_size, and area::reallocator.

Referenced by drop_from_free_ring(), find_area(), and gw_check_check_leaks().

310 {
311  debug("gwlib.gwmem", 0, "Area %p, size %ld, max_size %ld",
312  area->area, (long) area->area_size, (long) area->max_size);
313  debug("gwlib.gwmem", 0, "Allocated by %s() at %s:%ld",
317  if (area->reallocator.function) {
318  debug("gwlib.gwmem", 0, "Re-allocated by %s() at %s:%ld",
322  }
323  if (area->claimer.function) {
324  debug("gwlib.gwmem", 0, "Claimed by %s() at %s:%ld",
327  area->claimer.lineno);
328  }
329  if (area->area_size > 0) {
330  size_t i;
331  unsigned char *p;
332  char buf[MAX_DUMP * 3 + 1];
333 
334  p = area->area;
335  buf[0] = '\0';
336  for (i = 0; i < area->area_size && i < MAX_DUMP; ++i)
337  sprintf(strchr(buf, '\0'), "%02x ", p[i]);
338 
339  debug("gwlib.gwmem", 0, "Contents of area (first %d bytes):", MAX_DUMP);
340  debug("gwlib.gwmem", 0, " %s", buf);
341  }
342 #if HAVE_BACKTRACE
343  {
344  size_t i;
345  char **strings = backtrace_symbols(area->frames, area->frame_size);
346  debug("gwlib.gwmem", 0, "Backtrace of last malloc/realloc:");
347  for (i = 0; i < area->frame_size; i++) {
348  if (strings != NULL)
349  debug("gwlib.gwmem", 0, "%s", strings[i]);
350  else
351  debug("gwlib.gwmem", 0, "%p", area->frames[i]);
352  }
353  free(strings);
354  }
355 #endif
356 }
const char * function
Definition: gwmem-check.c:141
const char * filename
Definition: gwmem-check.c:139
size_t area_size
Definition: gwmem-check.c:150
void free(void *)
long lineno
Definition: gwmem-check.c:140
struct location claimer
Definition: gwmem-check.c:154
struct location reallocator
Definition: gwmem-check.c:153
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
struct location allocator
Definition: gwmem-check.c:152
#define MAX_DUMP
Definition: gwmem-check.c:125
size_t max_size
Definition: gwmem-check.c:151
void * area
Definition: gwmem-check.c:149

◆ endmark()

static void endmark ( unsigned char *  p,
size_t  size 
)
inlinestatic

Definition at line 255 of file gwmem-check.c.

References END_MARK_PATTERN, fill(), MARKER_SIZE, and size.

Referenced by conn_read_packet(), gw_check_realloc(), and record_allocation().

256 {
258 }
int size
Definition: wsasm.c:84
static void fill(unsigned char *p, size_t bytes, long pattern)
Definition: gwmem-check.c:229
#define END_MARK_PATTERN
Definition: gwmem-check.c:122
#define MARKER_SIZE
Definition: gwmem-check.c:164

◆ fill()

static void fill ( unsigned char *  p,
size_t  bytes,
long  pattern 
)
static

Definition at line 229 of file gwmem-check.c.

Referenced by endmark(), free_area(), gw_check_malloc(), gw_check_realloc(), and startmark().

230 {
231  while (bytes > sizeof(pattern)) {
232  memcpy(p, &pattern, sizeof(pattern));
233  p += sizeof(pattern);
234  bytes -= sizeof(pattern);
235  }
236  if (bytes > 0)
237  memcpy(p, &pattern, bytes);
238 }

◆ find_area()

static struct area* find_area ( unsigned char *  p)
static

Definition at line 358 of file gwmem-check.c.

References allocated, area::area, area::area_size, check_endmark(), check_startmark(), dump_area(), END_MARK_PATTERN, error(), FREE_AREA_PATTERN, gw_assert(), NEW_AREA_PATTERN, num_allocations, slow, and START_MARK_PATTERN.

Referenced by gw_check_area_size(), gw_check_claim_area(), gw_check_free(), gw_check_is_allocated(), and gw_check_realloc().

359 {
360  long index;
361  struct area *area;
362  long suspicious_pointer;
363  unsigned long p_ul;
364 
365  gw_assert(p != NULL);
366 
367  p_ul = (unsigned long) p;
368  suspicious_pointer =
369  (sizeof(p) == sizeof(long) &&
370  (p_ul == NEW_AREA_PATTERN || p_ul == FREE_AREA_PATTERN ||
371  p_ul == START_MARK_PATTERN || p_ul == END_MARK_PATTERN));
372 
373  if (slow || suspicious_pointer) {
374  /* Extra check, which does not touch the (perhaps not allocated)
375  * memory area. It's slow, but may help pinpoint problems that
376  * would otherwise cause segfaults. */
377  for (index = 0; index < num_allocations; index++) {
378  if (allocated[index].area == p)
379  break;
380  }
381  if (index == num_allocations) {
382  error(0, "Area %p not found in allocation table.", p);
383  return NULL;
384  }
385  }
386 
387  index = check_startmark(p);
388  if (index >= 0 && index < num_allocations &&
389  allocated[index].area == p) {
390  area = &allocated[index];
391  if (check_endmark(p, area->area_size) < 0) {
392  error(0, "End marker was damaged for area %p", p);
393  dump_area(area);
394  }
395  return area;
396  }
397 
398  error(0, "Start marker was damaged for area %p", p);
399  for (index = 0; index < num_allocations; index++) {
400  if (allocated[index].area == p) {
401  area = &allocated[index];
402  dump_area(area);
403  return area;
404  }
405  }
406 
407  error(0, "Could not find area information.");
408  return NULL;
409 }
void error(int err, const char *fmt,...)
Definition: log.c:648
gw_assert(wtls_machine->packet_to_send !=NULL)
static int check_endmark(unsigned char *p, size_t size)
Definition: gwmem-check.c:286
static void dump_area(struct area *area)
Definition: gwmem-check.c:309
#define FREE_AREA_PATTERN
Definition: gwmem-check.c:115
static int slow
Definition: gwmem-check.c:130
static long check_startmark(unsigned char *p)
Definition: gwmem-check.c:276
size_t area_size
Definition: gwmem-check.c:150
#define NEW_AREA_PATTERN
Definition: gwmem-check.c:111
#define START_MARK_PATTERN
Definition: gwmem-check.c:119
#define END_MARK_PATTERN
Definition: gwmem-check.c:122
static long num_allocations
Definition: gwmem-check.c:182
static struct area allocated[MAX_ALLOCATIONS]
Definition: gwmem-check.c:177
void * area
Definition: gwmem-check.c:149

◆ free_area()

static void free_area ( struct area area)
static

Definition at line 494 of file gwmem-check.c.

References area::area, area::area_size, fill(), FREE_AREA_PATTERN, put_on_free_ring(), and remove_allocation().

Referenced by gw_check_free(), and gw_check_realloc().

495 {
499 }
static void fill(unsigned char *p, size_t bytes, long pattern)
Definition: gwmem-check.c:229
#define FREE_AREA_PATTERN
Definition: gwmem-check.c:115
size_t area_size
Definition: gwmem-check.c:150
static void put_on_free_ring(struct area *area)
Definition: gwmem-check.c:475
void * area
Definition: gwmem-check.c:149
static void remove_allocation(struct area *area)
Definition: gwmem-check.c:451

◆ gw_check_area_size()

long gw_check_area_size ( void *  p)

Definition at line 723 of file gwmem-check.c.

References area::area, area::area_size, find_area(), lock(), size, unlock(), and warning().

724 {
725  struct area *area;
726  size_t size;
727 
728  lock();
729  area = find_area(p);
730  if (!area) {
731  unlock();
732  warning(0, "Area_size called on non-allocated area %p", p);
733  return -1;
734  }
735  size = area->area_size;
736  unlock();
737  return size;
738 }
static void lock(void)
Definition: gwmem-check.c:198
int size
Definition: wsasm.c:84
static void unlock(void)
Definition: gwmem-check.c:203
static struct area * find_area(unsigned char *p)
Definition: gwmem-check.c:358
size_t area_size
Definition: gwmem-check.c:150
void warning(int err, const char *fmt,...)
Definition: log.c:660
void * area
Definition: gwmem-check.c:149

◆ gw_check_calloc()

void* gw_check_calloc ( int  nmemb,
size_t  size,
const char *  filename,
long  lineno,
const char *  function 
)

Definition at line 537 of file gwmem-check.c.

References calloc, filename, gw_assert(), initialized, lock(), MARKER_SIZE, panic, record_allocation(), size, and unlock().

539 {
540  unsigned char *p;
541 
543 
544  /* ANSI C89 says malloc(0) is implementation-defined. Avoid it. */
545  gw_assert(size > 0);
546  gw_assert(nmemb > 0);
547 
548  p = calloc(1, (nmemb*size) + 2 * MARKER_SIZE);
549  if (p == NULL)
550  panic(errno, "Memory allocation of %ld bytes failed.", (long)size);
551 
552  p += MARKER_SIZE;
553 
554  lock();
555  record_allocation(p, size, filename, lineno, function);
556  unlock();
557 
558  return p;
559 }
static void lock(void)
Definition: gwmem-check.c:198
int size
Definition: wsasm.c:84
static void unlock(void)
Definition: gwmem-check.c:203
gw_assert(wtls_machine->packet_to_send !=NULL)
#define calloc(a, b)
Definition: gwmem.h:192
static struct area * record_allocation(unsigned char *p, size_t size, const char *filename, long lineno, const char *function)
Definition: gwmem-check.c:418
char filename[FILENAME_MAX+1]
Definition: log.c:171
#define MARKER_SIZE
Definition: gwmem-check.c:164
static int initialized
Definition: gwmem-check.c:127
#define panic
Definition: log.h:87

◆ gw_check_check_leaks()

void gw_check_check_leaks ( void  )

Definition at line 679 of file gwmem-check.c.

References allocated, area::area_size, check_marks(), debug(), drop_from_free_ring(), dump_area(), free_ring_len, gw_assert(), highest_num_allocations, highest_total_size, initialized, lock(), num_allocations, total_size, and unlock().

680 {
681  long calculated_size;
682  long index;
683 
685  lock();
686 
687  for (index = 0; index < free_ring_len; index++) {
688  drop_from_free_ring(index);
689  }
690  free_ring_len = 0;
691 
692  calculated_size = 0;
693  for (index = 0; index < num_allocations; index++) {
694  calculated_size += allocated[index].area_size;
695  }
696  gw_assert(calculated_size == total_size);
697 
698  debug("gwlib.gwmem", 0, "----------------------------------------");
699  debug("gwlib.gwmem", 0, "Current allocations: %ld areas, %ld bytes",
701  debug("gwlib.gwmem", 0, "Highest number of allocations: %ld areas",
703  debug("gwlib.gwmem", 0, "Highest memory usage: %ld bytes",
705  for (index = 0; index < num_allocations; index++) {
706  check_marks(&allocated[index], index);
707  dump_area(&allocated[index]);
708  }
709 
710  unlock();
711 }
static void lock(void)
Definition: gwmem-check.c:198
static void unlock(void)
Definition: gwmem-check.c:203
static void drop_from_free_ring(long index)
Definition: gwmem-check.c:462
gw_assert(wtls_machine->packet_to_send !=NULL)
static void dump_area(struct area *area)
Definition: gwmem-check.c:309
size_t area_size
Definition: gwmem-check.c:150
static long free_ring_len
Definition: gwmem-check.c:186
static int check_marks(struct area *area, long index)
Definition: gwmem-check.c:293
static long num_allocations
Definition: gwmem-check.c:182
static long total_size
Definition: gwmem-check.c:194
static int initialized
Definition: gwmem-check.c:127
static long highest_num_allocations
Definition: gwmem-check.c:190
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
static struct area allocated[MAX_ALLOCATIONS]
Definition: gwmem-check.c:177
static long highest_total_size
Definition: gwmem-check.c:192

◆ gw_check_claim_area()

void* gw_check_claim_area ( void *  p,
const char *  filename,
long  lineno,
const char *  function 
)

Definition at line 654 of file gwmem-check.c.

References area::area, area::claimer, location::filename, filename, find_area(), location::function, location::lineno, lock(), panic, and unlock().

656 {
657  struct area *area;
658 
659  /* Allow this for the convenience of wrapper macros. */
660  if (p == NULL)
661  return NULL;
662 
663  lock();
664  area = find_area(p);
665  if (!area) {
666  unlock();
667  panic(0, "Claim_area called on non-allocated area");
668  }
669 
671  area->claimer.lineno = lineno;
672  area->claimer.function = function;
673  unlock();
674 
675  /* For convenience of calling macros */
676  return p;
677 }
static void lock(void)
Definition: gwmem-check.c:198
static void unlock(void)
Definition: gwmem-check.c:203
static struct area * find_area(unsigned char *p)
Definition: gwmem-check.c:358
const char * function
Definition: gwmem-check.c:141
const char * filename
Definition: gwmem-check.c:139
long lineno
Definition: gwmem-check.c:140
struct location claimer
Definition: gwmem-check.c:154
char filename[FILENAME_MAX+1]
Definition: log.c:171
#define panic
Definition: log.h:87
void * area
Definition: gwmem-check.c:149

◆ gw_check_free()

void gw_check_free ( void *  p,
const char *  filename,
long  lineno,
const char *  function 
)

Definition at line 619 of file gwmem-check.c.

References area::area, find_area(), free_area(), gw_assert(), initialized, lock(), panic, and unlock().

621 {
622  struct area *area;
624 
625  if (p == NULL)
626  return;
627 
628  lock();
629  area = find_area(p);
630  if (!area) {
631  unlock();
632  panic(0, "Free called on non-allocated area");
633  }
634 
635  free_area(area);
636  unlock();
637 }
static void lock(void)
Definition: gwmem-check.c:198
static void unlock(void)
Definition: gwmem-check.c:203
static struct area * find_area(unsigned char *p)
Definition: gwmem-check.c:358
gw_assert(wtls_machine->packet_to_send !=NULL)
static void free_area(struct area *area)
Definition: gwmem-check.c:494
static int initialized
Definition: gwmem-check.c:127
#define panic
Definition: log.h:87
void * area
Definition: gwmem-check.c:149

◆ gw_check_init_mem()

void gw_check_init_mem ( int  slow_flag)

Definition at line 501 of file gwmem-check.c.

References gwmem_lock, initialized, mutex_init_static, and slow.

502 {
504  slow = slow_flag;
505  initialized = 1;
506 }
static int slow
Definition: gwmem-check.c:130
#define mutex_init_static(mutex)
Definition: thread.h:115
static int initialized
Definition: gwmem-check.c:127
static Mutex gwmem_lock
Definition: gwmem-check.c:135

◆ gw_check_is_allocated()

int gw_check_is_allocated ( void *  p)

Definition at line 713 of file gwmem-check.c.

References area::area, find_area(), lock(), and unlock().

714 {
715  struct area *area;
716 
717  lock();
718  area = find_area(p);
719  unlock();
720  return area != NULL;
721 }
static void lock(void)
Definition: gwmem-check.c:198
static void unlock(void)
Definition: gwmem-check.c:203
static struct area * find_area(unsigned char *p)
Definition: gwmem-check.c:358
void * area
Definition: gwmem-check.c:149

◆ gw_check_malloc()

void* gw_check_malloc ( size_t  size,
const char *  filename,
long  lineno,
const char *  function 
)

Definition at line 514 of file gwmem-check.c.

References filename, fill(), gw_assert(), initialized, lock(), malloc(), MARKER_SIZE, NEW_AREA_PATTERN, panic, record_allocation(), size, and unlock().

Referenced by gw_check_realloc(), and gw_check_strdup().

516 {
517  unsigned char *p;
518 
520 
521  /* ANSI C89 says malloc(0) is implementation-defined. Avoid it. */
522  gw_assert(size > 0);
523 
524  p = malloc(size + 2 * MARKER_SIZE);
525  if (p == NULL)
526  panic(errno, "Memory allocation of %ld bytes failed.", (long)size);
527  p += MARKER_SIZE;
528 
529  lock();
531  record_allocation(p, size, filename, lineno, function);
532  unlock();
533 
534  return p;
535 }
static void lock(void)
Definition: gwmem-check.c:198
int size
Definition: wsasm.c:84
static void unlock(void)
Definition: gwmem-check.c:203
static void fill(unsigned char *p, size_t bytes, long pattern)
Definition: gwmem-check.c:229
gw_assert(wtls_machine->packet_to_send !=NULL)
void * malloc(YYSIZE_T)
static struct area * record_allocation(unsigned char *p, size_t size, const char *filename, long lineno, const char *function)
Definition: gwmem-check.c:418
#define NEW_AREA_PATTERN
Definition: gwmem-check.c:111
char filename[FILENAME_MAX+1]
Definition: log.c:171
#define MARKER_SIZE
Definition: gwmem-check.c:164
static int initialized
Definition: gwmem-check.c:127
#define panic
Definition: log.h:87

◆ gw_check_realloc()

void* gw_check_realloc ( void *  p,
size_t  size,
const char *  filename,
long  lineno,
const char *  function 
)

Definition at line 561 of file gwmem-check.c.

References area::allocator, area::area, area::area_size, change_total_size(), endmark(), location::filename, filename, fill(), find_area(), free_area(), location::function, gw_assert(), gw_check_malloc(), initialized, location::lineno, lock(), malloc(), MARKER_SIZE, area::max_size, NEW_AREA_PATTERN, panic, area::reallocator, record_allocation(), round_pow2(), size, and unlock().

563 {
564  struct area *area;
565 
566  if (p == NULL)
567  return gw_check_malloc(size, filename, lineno, function);
568 
570  gw_assert(size > 0);
571 
572  lock();
573  area = find_area(p);
574  if (!area) {
575  unlock();
576  panic(0, "Realloc called on non-allocated area");
577  }
578 
579  if (size == area->area_size) {
580  /* No changes */
581  } else if (size <= area->max_size) {
583  area->area_size = size;
584  endmark(p, size);
585  } else if (size > area->max_size) {
586  /* The current block is not large enough for the reallocation.
587  * We will allocate a new block, copy the data over, and free
588  * the old block. We round the size up to a power of two,
589  * to prevent frequent reallocations. */
590  struct area *new_area;
591  size_t new_size;
592  unsigned char *new_p;
593 
594  new_size = round_pow2(size + 2 * MARKER_SIZE);
595  new_p = malloc(new_size);
596  new_size -= 2 * MARKER_SIZE;
597  new_p += MARKER_SIZE;
598  memcpy(new_p, p, area->area_size);
599  fill(new_p + area->area_size, size - area->area_size,
601  new_area = record_allocation(new_p, size,
605  new_area->max_size = new_size;
606  free_area(area);
607 
608  p = new_p;
609  area = new_area;
610  }
611 
613  area->reallocator.lineno = lineno;
614  area->reallocator.function = function;
615  unlock();
616  return p;
617 }
static void lock(void)
Definition: gwmem-check.c:198
int size
Definition: wsasm.c:84
static void unlock(void)
Definition: gwmem-check.c:203
static struct area * find_area(unsigned char *p)
Definition: gwmem-check.c:358
static void fill(unsigned char *p, size_t bytes, long pattern)
Definition: gwmem-check.c:229
gw_assert(wtls_machine->packet_to_send !=NULL)
const char * function
Definition: gwmem-check.c:141
static void endmark(unsigned char *p, size_t size)
Definition: gwmem-check.c:255
void * malloc(YYSIZE_T)
static void change_total_size(long change)
Definition: gwmem-check.c:411
const char * filename
Definition: gwmem-check.c:139
static struct area * record_allocation(unsigned char *p, size_t size, const char *filename, long lineno, const char *function)
Definition: gwmem-check.c:418
size_t area_size
Definition: gwmem-check.c:150
long lineno
Definition: gwmem-check.c:140
#define NEW_AREA_PATTERN
Definition: gwmem-check.c:111
char filename[FILENAME_MAX+1]
Definition: log.c:171
void * gw_check_malloc(size_t size, const char *filename, long lineno, const char *function)
Definition: gwmem-check.c:514
static unsigned long round_pow2(unsigned long num)
Definition: gwmem-check.c:208
#define MARKER_SIZE
Definition: gwmem-check.c:164
static void free_area(struct area *area)
Definition: gwmem-check.c:494
struct location reallocator
Definition: gwmem-check.c:153
static int initialized
Definition: gwmem-check.c:127
#define panic
Definition: log.h:87
struct location allocator
Definition: gwmem-check.c:152
size_t max_size
Definition: gwmem-check.c:151
void * area
Definition: gwmem-check.c:149

◆ gw_check_shutdown()

void gw_check_shutdown ( void  )

Definition at line 508 of file gwmem-check.c.

References gwmem_lock, initialized, and mutex_destroy().

509 {
511  initialized = 0;
512 }
void mutex_destroy(Mutex *mutex)
Definition: thread.c:97
static int initialized
Definition: gwmem-check.c:127
static Mutex gwmem_lock
Definition: gwmem-check.c:135

◆ gw_check_strdup()

char* gw_check_strdup ( const char *  str,
const char *  filename,
long  lineno,
const char *  function 
)

Definition at line 639 of file gwmem-check.c.

References filename, gw_assert(), gw_check_malloc(), initialized, and size.

641 {
642  char *copy;
643  int size;
644 
646  gw_assert(str != NULL);
647 
648  size = strlen(str) + 1;
649  copy = gw_check_malloc(size, filename, lineno, function);
650  memcpy(copy, str, size);
651  return copy;
652 }
int size
Definition: wsasm.c:84
gw_assert(wtls_machine->packet_to_send !=NULL)
char filename[FILENAME_MAX+1]
Definition: log.c:171
void * gw_check_malloc(size_t size, const char *filename, long lineno, const char *function)
Definition: gwmem-check.c:514
static int initialized
Definition: gwmem-check.c:127

◆ lock()

static void lock ( void  )
inlinestatic

Definition at line 198 of file gwmem-check.c.

References gwmem_lock, and mutex_lock.

Referenced by gw_check_area_size(), gw_check_calloc(), gw_check_check_leaks(), gw_check_claim_area(), gw_check_free(), gw_check_is_allocated(), gw_check_malloc(), and gw_check_realloc().

199 {
201 }
static Mutex gwmem_lock
Definition: gwmem-check.c:135
#define mutex_lock(m)
Definition: thread.h:130

◆ put_on_free_ring()

static void put_on_free_ring ( struct area area)
static

Definition at line 475 of file gwmem-check.c.

References area::area, drop_from_free_ring(), free_ring, free_ring_len, FREE_RING_SIZE, free_ring_start, and startmark().

Referenced by free_area().

476 {
477  /* Simple case: We're still filling the free ring. */
481  free_ring_len++;
482  return;
483  }
484 
485  /* Normal case: We need to check and release a free ring entry,
486  * then put this one in its place. */
487 
492 }
static void drop_from_free_ring(long index)
Definition: gwmem-check.c:462
static void startmark(unsigned char *p, long number)
Definition: gwmem-check.c:263
static struct area free_ring[FREE_RING_SIZE]
Definition: gwmem-check.c:178
static long free_ring_len
Definition: gwmem-check.c:186
static long free_ring_start
Definition: gwmem-check.c:185
#define FREE_RING_SIZE
Definition: gwmem-check.c:175
void * area
Definition: gwmem-check.c:149

◆ record_allocation()

static struct area* record_allocation ( unsigned char *  p,
size_t  size,
const char *  filename,
long  lineno,
const char *  function 
)
static

Definition at line 418 of file gwmem-check.c.

References allocated, area::allocator, area::area, area::area_size, change_total_size(), endmark(), location::filename, filename, location::function, highest_num_allocations, location::lineno, MAX_ALLOCATIONS, area::max_size, num_allocations, panic, size, and startmark().

Referenced by gw_check_calloc(), gw_check_malloc(), and gw_check_realloc().

420 {
421  struct area *area;
422  static struct area empty_area;
423 
425  panic(0, "Too many concurrent allocations.");
426  }
427 
429  *area = empty_area;
430  area->area = p;
431  area->area_size = size;
432  area->max_size = size;
434  area->allocator.lineno = lineno;
435  area->allocator.function = function;
436 #if HAVE_BACKTRACE
437  area->frame_size = backtrace(area->frames, sizeof(area->frames) / sizeof(void*));
438 #endif
439 
442 
443  num_allocations++;
447 
448  return area;
449 }
int size
Definition: wsasm.c:84
static void startmark(unsigned char *p, long number)
Definition: gwmem-check.c:263
const char * function
Definition: gwmem-check.c:141
static void endmark(unsigned char *p, size_t size)
Definition: gwmem-check.c:255
static void change_total_size(long change)
Definition: gwmem-check.c:411
const char * filename
Definition: gwmem-check.c:139
size_t area_size
Definition: gwmem-check.c:150
long lineno
Definition: gwmem-check.c:140
#define MAX_ALLOCATIONS
Definition: gwmem-check.c:168
static long num_allocations
Definition: gwmem-check.c:182
char filename[FILENAME_MAX+1]
Definition: log.c:171
static long highest_num_allocations
Definition: gwmem-check.c:190
#define panic
Definition: log.h:87
static struct area allocated[MAX_ALLOCATIONS]
Definition: gwmem-check.c:177
struct location allocator
Definition: gwmem-check.c:152
size_t max_size
Definition: gwmem-check.c:151
void * area
Definition: gwmem-check.c:149

◆ remove_allocation()

static void remove_allocation ( struct area area)
static

Definition at line 451 of file gwmem-check.c.

References allocated, area::area, area::area_size, change_total_size(), check_marks(), num_allocations, and startmark().

Referenced by free_area().

452 {
454  num_allocations--;
455  if (area == &allocated[num_allocations])
456  return;
460 }
static void startmark(unsigned char *p, long number)
Definition: gwmem-check.c:263
static void change_total_size(long change)
Definition: gwmem-check.c:411
size_t area_size
Definition: gwmem-check.c:150
static int check_marks(struct area *area, long index)
Definition: gwmem-check.c:293
static long num_allocations
Definition: gwmem-check.c:182
static struct area allocated[MAX_ALLOCATIONS]
Definition: gwmem-check.c:177
void * area
Definition: gwmem-check.c:149

◆ round_pow2()

static unsigned long round_pow2 ( unsigned long  num)
static

Definition at line 208 of file gwmem-check.c.

Referenced by gw_check_realloc().

209 {
210  unsigned long i;
211 
212  if (num <= 16)
213  return 16;
214 
215  for (i = 32; i < 0x80000000L; i <<= 1) {
216  if (num <= i)
217  return i;
218  }
219 
220  /* We have to handle this case separately; the loop cannot go that
221  * far because i would overflow. */
222  if (num <= 0x80000000L)
223  return 0x80000000L;
224 
225  return 0xffffffffL;
226 }

◆ startmark()

static void startmark ( unsigned char *  p,
long  number 
)
static

Definition at line 263 of file gwmem-check.c.

References fill(), gw_assert(), MARKER_SIZE, number, and START_MARK_PATTERN.

Referenced by conn_read_packet(), put_on_free_ring(), record_allocation(), and remove_allocation().

264 {
265  gw_assert(MARKER_SIZE >= sizeof(long));
266  gw_assert(number >= 0);
267 
268  fill(p - MARKER_SIZE, sizeof(long), number);
269  fill(p - MARKER_SIZE + sizeof(long),
270  MARKER_SIZE - sizeof(long), START_MARK_PATTERN);
271 }
int number
Definition: smsc_cimd2.c:213
static void fill(unsigned char *p, size_t bytes, long pattern)
Definition: gwmem-check.c:229
gw_assert(wtls_machine->packet_to_send !=NULL)
#define START_MARK_PATTERN
Definition: gwmem-check.c:119
#define MARKER_SIZE
Definition: gwmem-check.c:164

◆ unlock()

static void unlock ( void  )
inlinestatic

Definition at line 203 of file gwmem-check.c.

References gwmem_lock, and mutex_unlock.

Referenced by gw_check_area_size(), gw_check_calloc(), gw_check_check_leaks(), gw_check_claim_area(), gw_check_free(), gw_check_is_allocated(), gw_check_malloc(), and gw_check_realloc().

204 {
206 }
#define mutex_unlock(m)
Definition: thread.h:136
static Mutex gwmem_lock
Definition: gwmem-check.c:135

◆ untouched()

static int untouched ( unsigned char *  p,
size_t  bytes,
long  pattern 
)
static

Definition at line 241 of file gwmem-check.c.

Referenced by check_endmark(), check_startmark(), and drop_from_free_ring().

242 {
243  while (bytes > sizeof(pattern)) {
244  if (memcmp(p, &pattern, sizeof(pattern)) != 0)
245  return 0;
246  p += sizeof(pattern);
247  bytes -= sizeof(pattern);
248  }
249  if (bytes > 0 && memcmp(p, &pattern, bytes) != 0)
250  return 0;
251  return 1;
252 }

Variable Documentation

◆ allocated

struct area allocated[MAX_ALLOCATIONS]
static

◆ free_ring

struct area free_ring[FREE_RING_SIZE]
static

Definition at line 178 of file gwmem-check.c.

Referenced by drop_from_free_ring(), and put_on_free_ring().

◆ free_ring_len

long free_ring_len
static

Definition at line 186 of file gwmem-check.c.

Referenced by gw_check_check_leaks(), and put_on_free_ring().

◆ free_ring_start

long free_ring_start
static

Definition at line 185 of file gwmem-check.c.

Referenced by put_on_free_ring().

◆ gwmem_lock

Mutex gwmem_lock
static

Definition at line 135 of file gwmem-check.c.

Referenced by gw_check_init_mem(), gw_check_shutdown(), lock(), and unlock().

◆ highest_num_allocations

long highest_num_allocations
static

Definition at line 190 of file gwmem-check.c.

Referenced by gw_check_check_leaks(), and record_allocation().

◆ highest_total_size

long highest_total_size
static

Definition at line 192 of file gwmem-check.c.

Referenced by change_total_size(), and gw_check_check_leaks().

◆ initialized

◆ num_allocations

long num_allocations
static

◆ slow

int slow = 0
static

Definition at line 130 of file gwmem-check.c.

Referenced by find_area(), and gw_check_init_mem().

◆ total_size

long total_size
static

Definition at line 194 of file gwmem-check.c.

Referenced by change_total_size(), and gw_check_check_leaks().

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.