Home > Software design >  ASan not flagging leaks on WSL 2
ASan not flagging leaks on WSL 2

Time:10-03

ASan is unable to find memory leaks on WSL2.

I'm using CMake to link the ASan lib and to pass the compiler options:

cmake_minimum_required(VERSION 3.23)
project(test C)

set(CMAKE_C_STANDARD 17)

add_executable(asan_address
        src/main.c
        src/LinkedList.c src/LinkedList.h)

target_compile_options(asan_address PRIVATE
        -std=c18
        -Wall
        -Werror
        -Wextra
        -fsanitize=address
        -static-libasan
        -fno-omit-frame-pointer
        -g
        -O3
        -lm
        )

target_link_options(asan_address PRIVATE -fsanitize=address -static-libasan -fno-omit-frame-pointer)

The code is an incomplete implementation of a linked list which currently doesn't free it's nodes, so a memory leak should occur.

Steps I take to compile my code:

$> cmake .
$> make asan_address
$> ./asan_address

Code:

#include <stdio.h>
#include "LinkedList.h"

int main() {
    LinkedList *ll;
    int status = initLinkedList(&ll);
    if (status == MALLOC_FAILED) {
        return MALLOC_FAILED;
    }
    int value = 1;
    status = addValue(ll, &value);
    if (status == MALLOC_FAILED) {
        return MALLOC_FAILED;
    }
    void *valuePointer = getElement(ll, 0);
    if (valuePointer == NULL) {
        printf("value pointer was null\n");
    } else printf("value head node:\t%d\n", *((int *) valuePointer));

    return 0;
}

Header file:

#ifndef PRACT01_LINKEDLIST_H
#define PRACT01_LINKEDLIST_H

#include <stdint.h>

#define SUCCESS 0
#define MALLOC_FAILED -1
#define OUT_OF_BOUNDS_INDEX -2

typedef struct Node {
    struct Node *next;
    struct Node *prev;
    void *value;
} Node;

typedef struct LinkedList {
    Node *head;
    Node *tail;
    uint8_t length;
} LinkedList;

int initLinkedList(LinkedList **);
int addValue(LinkedList *, void*);
void* getElement(LinkedList*, unsigned int);
#endif //PRACT01_LINKEDLIST_H

LinkedList.c file:

#include "LinkedList.h"
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>


int initNode(Node **n) {
    *n = malloc(sizeof(Node));
    if (*n == NULL) {
        return MALLOC_FAILED;
    }
    (*n)->next = NULL;
    (*n)->prev = NULL;
    (*n)->value = NULL;
    return SUCCESS;
}

int initLinkedList(LinkedList **ll) {
    *ll = malloc(sizeof(LinkedList));
    if (*ll == NULL) {
        return MALLOC_FAILED;
    }
    (*ll)->length = 0;
    (*ll)->head = NULL;
    (*ll)->tail = NULL;
    return SUCCESS;
}

int addValue(LinkedList *ll, void *value) {
    unsigned int size = ll->length;
    Node *newNode;
    int result = initNode(&newNode);
    if (result != SUCCESS) {
        return result;
    }
    newNode->value = value;
    if (size == 0) {
        ll->head = newNode;
        ll->length  = 1;
        return SUCCESS;
    }
    Node *last = ll->head;
    for (unsigned int i = 0; i < size; i  ) {
        last = last->next;
    }
    last->next = newNode;
    newNode->prev = last;
    ll->length  = 1;

    return SUCCESS;
}

int addValueIndex(LinkedList *ll, unsigned int index, void *value) {
    unsigned int size = ll->length;
    Node *newNode;
    int result = initNode(&newNode);
    if (index > size) {
        return OUT_OF_BOUNDS_INDEX;
    }
    if (index == size) {
        return addValue(ll, value);
    }
    if (index == 0) {
        ll->head = newNode;
    }
    Node *last = ll->head;
    for (unsigned int i = 0; i < index; i  ) {
        last = last->next;
    }

    if (result == MALLOC_FAILED) {
        return MALLOC_FAILED;
    }

    newNode->value = value;
    last->next = newNode;
    newNode->prev = last;
    ll->length  = 1;

    return SUCCESS;
}

void *getElement(LinkedList *ll, unsigned int index) {
    printf("[DEBUG]\tindex:\t%d\n", index);
    unsigned int size = ll->length;

    printf("[DEBUG]\tsize:\t%d\n", size);
    if (size <= index || size == 0) {
        return NULL;
    }
    Node *current = ll->head;
    for (unsigned int i = 0; i < index; i  ) {
        printf("in for loop");
        current = current->next;
    }
    return current->value;
}

void printLinkedList(LinkedList *list) {
    printf("List length:\t%d", list->length);
}

CodePudding user response:

The problems of memory leaks, the address sanitizer is for detecting pointer errors, not memory leaks.

To detect memory leaks use the leak sanitizer: -fsanitize=leak.


You can use multiple sanitizers by separating them with a comma. For example -fsanitize=addres,leak,undefined to enable the address, leak and UB sanitizers.

CodePudding user response:

The leak sanitizer is supplied with the address sanitizer. To detect memory leaks run you app with the enabled leak sanitizer

ASAN_OPTIONS=detect_leaks=1 ./asan_address
  • Related