Sanitizer nie wykrywa memory leak'u a Valgrind wykrywa ?

1

free(reg); sanitizer nie wykrywa ze brak free() a valgrind to wykrywa

#include <regex.h>
#include <stdio.h>
#include <stdlib.h>

void print_regerror (int errcode, size_t length, const regex_t * compiled) {
   if (! compiled) {
      fputs("regex is null", stderr);
      exit(EXIT_FAILURE);
   } 
  char* buffer = calloc(length, sizeof(char));
  regerror (errcode, compiled, buffer, length);
  fprintf(stderr, "Regex match failed: %s\n", buffer);
  free(buffer);
}

void compile_regex(regex_t * regex, const char * pattern, const int cflags) {
   if (! pattern || ! regex) {
      fputs("regex or regex's pattern is null\n", stderr);
      exit(EXIT_FAILURE);
   }
   int result = regcomp(regex, pattern, cflags);
   if (0 != result) {
      size_t length = regerror (result, regex, NULL, 0);
      print_regerror (result, length, regex); 
      exit(EXIT_FAILURE);
   }
}

int main(const int argc, const char * argv[]) {
   regex_t * reg = malloc(sizeof(regex_t));
   compile_regex(reg, "^[[:upper:]][[:lower:]]*( [[:upper:]][[:lower:]]*)?$", REG_EXTENDED);

   regfree(reg); /*
   free(reg);  sanitizer nie wykrywa ze brak free   */
}
#gcc -Wfatal-errors -Wall -Wextra -Wconversion -std=c11 -c reg.c -o v_reg.o
#gcc -Wfatal-errors -Wall -Wextra -Wconversion -std=c11 v_reg.o -o v_reg
# valgrind --leak-check=full --show-leak-kinds=all ./v_reg 
# valgrind wg mnie wskazuje na poprawne wyniki


#gcc -Wfatal-errors -Wall -Wextra -Wconversion -std=c11 -fsanitize=address  -c reg.c -o s_reg.o
#gcc -Wfatal-errors -Wall -Wextra -Wconversion -std=c11 -fsanitize=address -static-libasan s_reg.o -o s_reg
# ./s_reg
# sanitizer wg mnie wskazuje niepoprawny wynik

CC = gcc
CFLAGS = -Wfatal-errors -Wall -Wextra -Wconversion -std=c11 
LDFLAGS =

PROGRAMS  = v_reg s_reg

.PHONY: clean all

all: $(PROGRAMS)

v_reg: v_reg.o
	$(CC) $(CFLAGS) $(LDFLAGS) v_reg.o -o v_reg 
	
v_reg.o: reg.c
	$(CC) $(CFLAGS) -c reg.c -o v_reg.o 
	
s_reg: s_reg.o
	$(CC) $(CFLAGS) -fsanitize=address $(LDFLAGS) -fsanitize=address -static-libasan  s_reg.o -o s_reg 
	
s_reg.o: reg.c
	$(CC) $(CFLAGS) -fsanitize=address -c reg.c -o s_reg.o
	
clean :
	rm $(PROGRAMS) *.o

2

Hmm?

/tmp $ cat xd.c | tail -n 5
   compile_regex(reg, "^[[:upper:]][[:lower:]]*( [[:upper:]][[:lower:]]*)?$", REG_EXTENDED);

   regfree(reg); 
//   free(reg); // sanitizer nie wykrywa ze brak free   
}
/tmp $ gcc -fsanitize=address xd.c
/tmp $ ./a.out

=================================================================
==220032==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 64 byte(s) in 1 object(s) allocated from:
    #0 0x7ff41d00693f in __interceptor_malloc (/lib64/libasan.so.6+0xae93f)
    #1 0x4013d2 in main (/tmp/a.out+0x4013d2)
    #2 0x7ff41cdb0b74 in __libc_start_main (/lib64/libc.so.6+0x27b74)

SUMMARY: AddressSanitizer: 64 byte(s) leaked in 1 allocation(s).
1

Błąd w gcc clang sobie radzi: https://godbolt.org/z/9a61MP8cc

Co ciekawe wystarczy dopisać printf na końcu i działa: https://godbolt.org/z/8nYTzoWeK

0

korzystam z gcc (Debian 8.3.0-6) 8.3.0 https://gcc.gnu.org/gcc-8/ instalowanego poprzez pakiety Antix19.4 - w takim razie chyba skompiluje GCC ze zrodel.

1 użytkowników online, w tym zalogowanych: 0, gości: 1