Skip to content

Commit

Permalink
Testing the memory debugger
Browse files Browse the repository at this point in the history
  • Loading branch information
CurlyMoo committed Jul 29, 2017
1 parent 7cb9017 commit e999574
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ script:
after_success:
- gem install coveralls-lcov
- lcov -c -d CMakeFiles/pilight.dir/libs/pilight/events/ -d CMakeFiles/pilight.dir/libs/pilight/core/ -d CMakeFiles/pilight.dir/libs/pilight/psutil/ -d CMakeFiles/pilight.dir/libs/pilight/protocols/API/ -d CMakeFiles/pilight.dir/libs/pilight/protocols/core/ -d CMakeFiles/pilight.dir/libs/pilight/protocols/generic/ -d CMakeFiles/pilight.dir/libs/pilight/protocols/network/ -d CMakeFiles/pilight.dir/libs/pilight/protocols/GPIO -o coverage.info
- lcov -r coverage.info '*adhoc.c' '*gc.c' '*mem.c' '*firmware.c' '*gpio_switch.c' '*relay.c' '*pushover.c' '*pushbullet.c' '*dht11.c' '*dht22.c' -o coverage-filtered.info
- lcov -r coverage.info '*adhoc.c' '*gc.c' '*firmware.c' '*gpio_switch.c' '*relay.c' '*pushover.c' '*pushbullet.c' '*dht11.c' '*dht22.c' -o coverage-filtered.info
- lcov --list coverage-filtered.info
- if [[ "$TRAVIS_EVENT_TYPE" != "pull_request" ]]; then coveralls-lcov --repo-token ${COVERALLS_TOKEN} coverage-filtered.info; fi
22 changes: 17 additions & 5 deletions libs/pilight/core/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ void memtrack(void) {
}

int xfree(void) {
int x = openallocs;
if(memdbg == 1) {
#ifdef _WIN32
DWORD dwWaitResult = WaitForSingleObject(lock, INFINITE);
Expand Down Expand Up @@ -103,18 +104,21 @@ int xfree(void) {
fprintf(stderr, "NOTICE: memory allocations total: %lu, still open: %lu\n", totalnrallocs, openallocs);*/
totalnrallocs = 0;
memdbg = 2;
openallocs = 0;
}
return openallocs;
return x;
}

void *__malloc(unsigned long a, const char *file, int line) {
if(memdbg == 1) {
struct mallocs_t *node = malloc(sizeof(mallocs_t));
if((node->p = malloc(a)) == NULL) {
/*LCOV_EXCL_START*/
fprintf(stderr, "out of memory in %s at line #%d\n", file, line);
free(node);
xfree();
exit(EXIT_FAILURE);
/*LCOV_EXCL_STOP*/
}
#ifdef _WIN32
InterlockedIncrement(&openallocs);
Expand Down Expand Up @@ -149,7 +153,7 @@ void *__malloc(unsigned long a, const char *file, int line) {
char *___strdup(char *a, const char *file, int line) {
char *d = __malloc(strlen(a) + 1, file, line);
if(d == NULL) {
return NULL;
return NULL; /*LCOV_EXCL_LINE*/
}
strcpy(d, a);
return d;
Expand All @@ -172,6 +176,7 @@ void *__realloc(void *a, unsigned long b, const char *file, int line) {
strcpy(tmp->file, file);
tmp->size = b;
if((a = realloc(a, b)) == NULL) {
/*LCOV_EXCL_START*/
fprintf(stderr, "out of memory in %s at line #%d\n", file, line);
#ifdef _WIN32
ReleaseMutex(lock);
Expand All @@ -180,6 +185,7 @@ void *__realloc(void *a, unsigned long b, const char *file, int line) {
#endif
xfree();
exit(EXIT_FAILURE);
/*LCOV_EXCL_STOP*/
}
tmp->p = a;
break;
Expand All @@ -197,7 +203,8 @@ void *__realloc(void *a, unsigned long b, const char *file, int line) {
} else if(tmp != NULL && tmp->p != NULL) {
return a;
} else {
return __malloc(b, file, line);
/* This line should not be reached */
return __malloc(b, file, line); /*LCOV_EXCL_LINE*/
}
}
} else {
Expand All @@ -208,11 +215,13 @@ void *__realloc(void *a, unsigned long b, const char *file, int line) {
void *__calloc(unsigned long a, unsigned long b, const char *file, int line) {
if(memdbg == 1) {
struct mallocs_t *node = malloc(sizeof(mallocs_t));
if((node->p = malloc(a*b)) == NULL) {
if((node->p = calloc(a, b)) == NULL) {
/*LCOV_EXCL_START*/
fprintf(stderr, "out of memory in %s at line #%d\n", file, line);
free(node);
xfree();
exit(EXIT_FAILURE);
/*LCOV_EXCL_STOP*/
}
#ifdef _WIN32
InterlockedIncrement(&openallocs);
Expand All @@ -221,7 +230,6 @@ void *__calloc(unsigned long a, unsigned long b, const char *file, int line) {
__sync_add_and_fetch(&openallocs, 1);
__sync_add_and_fetch(&totalnrallocs, 1);
#endif
memset(node->p, '\0', a*b);
node->size = a*b;
node->line = line;
strcpy(node->file, file);
Expand All @@ -245,6 +253,10 @@ void *__calloc(unsigned long a, unsigned long b, const char *file, int line) {
}
}

void xabort(void) {
memdbg = 0;
}

void __free(void *a, const char *file, int line) {
if(memdbg == 2) {
fprintf(stderr, "WARNING: calling free after xfree was called in %s at line #%d\n", file, line);
Expand Down
1 change: 1 addition & 0 deletions libs/pilight/core/mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define OUT_OF_MEMORY fprintf(stderr, "out of memory in %s #%d\n", __FILE__, __LINE__),exit(EXIT_FAILURE);

int xfree(void);
void xabort(void);
void memtrack(void);

void *__malloc(unsigned long, const char *, int);
Expand Down
4 changes: 4 additions & 0 deletions tests/alltests.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,5 +200,9 @@ int main(int argc, char **argv) {
fflush(stdout);
assert(17 == test_unittest());

printf("[ %-48s ]\n", "test_memory");
fflush(stdout);
assert(0 == test_memory());

return RunAllTests();
}
2 changes: 2 additions & 0 deletions tests/alltests.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

int suiteFailed(void);
int test_unittest(void);
int test_memory(void);

extern char whitelist[10][16];
extern int whitelistnr;
extern int config_enable;
Expand Down
236 changes: 236 additions & 0 deletions tests/memory.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
/*
Copyright (C) 2013 - 2016 CurlyMo
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "../libs/pilight/core/CuTest.h"
#include "../libs/pilight/core/mem.h"

#include "alltests.h"

static void test_memory1(CuTest *tc) {
{
memtrack();

char *a = MALLOC(128);
CuAssertPtrNotNull(tc, a);

int i = 0, check = 1;
for(i=0;i<128;i++) {
if((a[i] & 0xFF) != 0x00) {
check = 1;
}
}
CuAssertIntEquals(tc, 1, check);

FREE(a);
CuAssertPtrEquals(tc, NULL, a);

CuAssertIntEquals(tc, 0, xfree());
}

{
memtrack();

char *a = MALLOC(128);
CuAssertPtrNotNull(tc, a);

int i = 0, check = 0;
for(i=0;i<128;i++) {
if((a[i] & 0xFF) != 0x00) {
check = 1;
}
}
CuAssertIntEquals(tc, 1, check);

char *b = REALLOC(a, 10);
CuAssertPtrEquals(tc, a, b);

FREE(a);
CuAssertPtrEquals(tc, NULL, a);

CuAssertIntEquals(tc, 0, xfree());
}

{
memtrack();

char *a = STRDUP("foo");
CuAssertPtrNotNull(tc, a);
CuAssertIntEquals(tc, 3, strlen(a));
CuAssertStrEquals(tc, "foo", a);
FREE(a);
CuAssertPtrEquals(tc, NULL, a);

CuAssertIntEquals(tc, 0, xfree());
}

{
memtrack();

int line = 0;
char *format = "CHECK: calling free on already freed pointer in %s at line #%d";
char error[1024], *p = error;
char *a = MALLOC(0);
CuAssertPtrNotNull(tc, a);
FREE(a);
FREE(a); line = __LINE__;
CuAssertPtrEquals(tc, NULL, a);

CuAssertIntEquals(tc, 0, xfree());

snprintf(p, 1024, format, __FILE__, line);
printf(" %s\n", error);
}

{
memtrack();

char *a = CALLOC(sizeof(char), 128);
CuAssertPtrNotNull(tc, a);

int i = 0, check = 0;
for(i=0;i<128;i++) {
if((a[i] & 0xFF) != 0x00) {
check = 1;
}
}
CuAssertIntEquals(tc, 0, check);

FREE(a);
CuAssertPtrEquals(tc, NULL, a);

CuAssertIntEquals(tc, 0, xfree());
}

{
memtrack();

int line = 0;
char *format = "CHECK: unfreed pointer in %s at line #%d";
char error[1024], *p = error;
char *a = MALLOC(128); line = __LINE__;
CuAssertPtrNotNull(tc, a);

CuAssertIntEquals(tc, 1, xfree());

snprintf(p, 1024, format, __FILE__, line);
printf(" %s\n", error);
}

{
memtrack();

int line[2] = { 0 };
char *format = "CHECK: unfreed pointer in %s at line #%d";
char error[1024], *p = error;
char *a = MALLOC(128); line[0] = __LINE__;
CuAssertPtrNotNull(tc, a);

char *b = MALLOC(128); line[1] = __LINE__;
CuAssertPtrNotNull(tc, b);

CuAssertIntEquals(tc, 2, xfree());

snprintf(p, 1024, format, __FILE__, line[1]);
printf(" %s\n", error);
snprintf(p, 1024, format, __FILE__, line[0]);
printf(" %s\n", error);
}

{
memtrack();

int line = 0;
char *format = "CHECK: calling realloc on an unknown pointer in %s at line #%d";
char error[1024], *p = error;
char *b = malloc(0);
char *a = REALLOC(b, 128); line = __LINE__;
CuAssertPtrNotNull(tc, a);

FREE(a);

CuAssertIntEquals(tc, 0, xfree());

snprintf(p, 1024, format, __FILE__, line);
printf("%s\n", error);
}

{
memtrack();

int line = 0;
char *format = "CHECK: calling free after xfree was called in %s at line #%d";
char error[1024], *p = error;
char *b = malloc(0);
char *a = MALLOC(128);;
CuAssertPtrNotNull(tc, a);
FREE(a);
CuAssertIntEquals(tc, 0, xfree());
FREE(b); line = __LINE__;
snprintf(p, 1024, format, __FILE__, line);
printf(" %s\n", error);
}

{
xabort();

char *a = MALLOC(128);
CuAssertPtrNotNull(tc, a);
FREE(a);
CuAssertIntEquals(tc, 0, xfree());
}

{
xabort();

char *a = REALLOC(NULL, 128);
CuAssertPtrNotNull(tc, a);
FREE(a);
CuAssertIntEquals(tc, 0, xfree());
}

{
xabort();

char *a = CALLOC(sizeof(char), 128);
CuAssertPtrNotNull(tc, a);
FREE(a);
CuAssertIntEquals(tc, 0, xfree());
}

{
memtrack();

int line = 0;
char *format = "CHECK: trying to free an unknown pointer in %s at line #%d";
char error[1024], *p = error;

char *a = malloc(128);
CuAssertPtrNotNull(tc, a);
FREE(a); line = __LINE__;
CuAssertIntEquals(tc, -1, xfree());

snprintf(p, 1024, format, __FILE__, line);
printf("%s\n", error);
}
}

int test_memory(void) {
CuSuite *suite = CuSuiteNew();

SUITE_ADD_TEST(suite, test_memory1);

CuSuiteRun(suite);
CuSuiteDelete(suite);

return suite->failCount;
}

0 comments on commit e999574

Please sign in to comment.