Почему дезинфицирующее средство для устранения утечек LLVM не работает при использовании с включенными другими дезинфицирующими средствами

#c #memory-leaks #llvm #sanitizer #dynamic-analysis

#c #утечки памяти #llvm #дезинфицирующее средство #динамический анализ

Вопрос:

Я пытался найти утечку памяти из простой программы:

 #include lt;stdio.hgt; #include lt;stdlib.hgt; #include lt;string.hgt; #include lt;stdint.hgt;  void parse(const char* input) {  // Goal: parse out a string between brackets  // (e.g. " [target string]" -gt; "target string")   char *mutable_copy = strdup(input);   // Find open bracket  char *open_bracket = strchr(mutable_copy, '[');  if (open_bracket == NULL) {  printf("Malformed input!n");  free(mutable_copy);  return;  }   // Make the output string start after the open bracket  char *parsed = open_bracket   1;   // Make sure there is at least one character in brackets  if (parsed[0] == '') {  printf("There should be at least one character in brackets!n");  free(mutable_copy);  return;  }   // Find the close bracket  char *close_bracket = strchr(parsed, ']');  if (close_bracket == NULL) {  printf("Malformed input!n");  return;  }   // Replace the close bracket with a null terminator to end the parsed  // string there  *close_bracket = '';   printf("Parsed string: %sn", parsed);  free(mutable_copy); }  int main(int argc, char *argv[]) {  if (argc lt; 2) {  printf("Usage: %s lt;string to parsegt;n", argv[0]);  return 1;  }   parse(argv[1]);   return 0; }  

с помощью следующей команды: clang -g -O0 -Wall -Wextra -std=gnu99 -fsanitize=address,leak -o 3-bracket-parser 3-bracket-parser.c

Очевидно, что в этой программе, если close_bracket == NULL верно, то программа возвращается без свободной изменяемой копии, поэтому происходит утечка памяти.

Однако, когда я запускаю эту команду, она не сообщает об ошибке, и мои дезинфицирующие средства не выводят никаких данных. Я попробовал еще раз, включив только дезинфицирующее средство для утечки, и на этот раз оно работает:

 ================================================================= ==19699==ERROR: LeakSanitizer: detected memory leaks  Direct leak of 17 byte(s) in 1 object(s) allocated from:  #0 0x10f77ab48 in wrap_malloc 0x58 (libclang_rt.lsan_osx_dynamic.dylib:x86_64h 0x9b48)  #1 0x7fff202b88d1 in strdup 0x1f (libsystem_c.dylib:x86_64 0x578d1)  #2 0x10f763db4 in parse 3-bracket-parser.c:10  #3 0x10f763edd in main 3-bracket-parser.c:51  #4 0x7fff203a7f3c in start 0x0 (libdyld.dylib:x86_64 0x15f3c)  SUMMARY: LeakSanitizer: 17 byte(s) leaked in 1 allocation(s).  

Мне было интересно, почему дезинфицирующее средство для утечки не работает, когда включены другие дезинфицирующие средства.

Моя версия clang-это домашняя версия clang 12.0.1, а моя ОС-macOS Big Sur 11.5.2

Ответ №1:

Проблема решена. Оказывается, в OS X lsan интегрирован в asan, и для включения lsan при использовании asan необходимо вручную использовать ASAN_OPTIONS=detect_leak=1. Похоже,что если кто-то использует-fsanitize=адрес, утечка, clang считает, что этот параметр утечки избыточен, поскольку средство для очистки адресов уже включает средство для очистки утечек. Если вы внимательно посмотрите на команду связывания, вы можете обнаружить, что ld связывает только asan dylib, когда включены оба дезинфицирующих средства, и вам нужно добавить ASAN_OPTIONS, чтобы включить lsan. Однако, если вы используете автономное средство для очистки от утечек, поэтому нет необходимости использовать ASAN_OPTIONS, чтобы указать, что вы также хотите включить lsan, и lsan отлично работает таким образом.