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