Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -3904,25 +3904,33 @@ } return res; } -INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim, - void *stream) { - void *ctx; - COMMON_INTERCEPTOR_ENTER(ctx, __getdelim, lineptr, n, delim, stream); - // FIXME: under ASan the call below may write to freed memory and corrupt - // its metadata. See - // https://code.google.com/p/address-sanitizer/issues/detail?id=321. - SSIZE_T res = REAL(__getdelim)(lineptr, n, delim, stream); - if (res > 0) { - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); + +// FIXME: under ASan the call below may write to freed memory and corrupt its +// metadata. See +// https://code.google.com/p/address-sanitizer/issues/detail?id=321. +#define GETDELIM_INTERCEPTOR_IMPL(vname) \ + { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream); \ + SSIZE_T res = REAL(vname)(lineptr, n, delim, stream); \ + if (res > 0) { \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); \ + } \ + return res; \ } - return res; -} + +INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim, + void *stream) +GETDELIM_INTERCEPTOR_IMPL(__getdelim) + +// There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor +// with its own body. INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim, - void *stream) { - return __getdelim(lineptr, n, delim, stream); -} + void *stream) +GETDELIM_INTERCEPTOR_IMPL(getdelim) + #define INIT_GETLINE \ COMMON_INTERCEPT_FUNCTION(getline); \ COMMON_INTERCEPT_FUNCTION(__getdelim); \ Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -208,7 +208,7 @@ #define SANITIZER_INTERCEPT_TIMES SI_NOT_WINDOWS // FIXME: getline seems to be available on OSX 10.7 -#define SANITIZER_INTERCEPT_GETLINE SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_GETLINE SI_FREEBSD || SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT__EXIT SI_LINUX || SI_FREEBSD Index: compiler-rt/trunk/test/msan/getline.cc =================================================================== --- compiler-rt/trunk/test/msan/getline.cc +++ compiler-rt/trunk/test/msan/getline.cc @@ -7,6 +7,10 @@ // RUN: %clang_msan -O0 -xc -D_GNU_SOURCE=1 %s -o %t && %run %t %t-testdata // RUN: %clang_msan -O2 -xc -D_GNU_SOURCE=1 %s -o %t && %run %t %t-testdata +#if defined(__FreeBSD__) +#define _WITH_GETLINE // To declare getline(). +#endif + #include #include #include