From 26fe5d396c5c99ddcd89b3f8722cea1d4940b9e9 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Thu, 31 Oct 2013 01:17:41 +0000 Subject: [sanitizer] Intercept getline, getdelim. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@193730 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/msan/lit_tests/getline.cc | 30 ++++++++++++++++++++ lib/msan/lit_tests/getline_test_data | 2 ++ .../sanitizer_common_interceptors.inc | 32 ++++++++++++++++++++++ .../sanitizer_platform_interceptors.h | 3 ++ lib/tsan/rtl/tsan_stat.cc | 2 ++ lib/tsan/rtl/tsan_stat.h | 2 ++ 6 files changed, 71 insertions(+) create mode 100644 lib/msan/lit_tests/getline.cc create mode 100644 lib/msan/lit_tests/getline_test_data diff --git a/lib/msan/lit_tests/getline.cc b/lib/msan/lit_tests/getline.cc new file mode 100644 index 00000000..27168a88 --- /dev/null +++ b/lib/msan/lit_tests/getline.cc @@ -0,0 +1,30 @@ +// RUN: %clangxx_msan -O0 %s -o %t && %t %p + +#include +#include +#include +#include + +int main(int argc, char **argv) { + assert(argc == 2); + char buf[1024]; + snprintf(buf, sizeof(buf), "%s/%s", argv[1], "getline_test_data"); + + FILE *fp = fopen(buf, "r"); + assert(fp); + + char *line = 0; + size_t len = 0; + int n = getline(&line, &len, fp); + assert(n == 6); + assert(strcmp(line, "abcde\n") == 0); + + n = getline(&line, &len, fp); + assert(n == 6); + assert(strcmp(line, "12345\n") == 0); + + free(line); + fclose(fp); + + return 0; +} diff --git a/lib/msan/lit_tests/getline_test_data b/lib/msan/lit_tests/getline_test_data new file mode 100644 index 00000000..5ba1d4ce --- /dev/null +++ b/lib/msan/lit_tests/getline_test_data @@ -0,0 +1,2 @@ +abcde +12345 diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc index 7c8669a2..3e716a7c 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -2811,6 +2811,37 @@ INTERCEPTOR(int, lrand48_r, void *buffer, long *result) { #define INIT_DRAND48_R #endif +#if SANITIZER_INTERCEPT_GETLINE +INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream); + SSIZE_T res = REAL(getline)(lineptr, n, 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; +} +INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim, + void *stream) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getdelim, lineptr, n, delim, stream); + 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); + } + return res; +} +#define INIT_GETLINE \ + INTERCEPT_FUNCTION(getline); \ + INTERCEPT_FUNCTION(getdelim); +#else +#define INIT_GETLINE +#endif + #define SANITIZER_COMMON_INTERCEPTORS_INIT \ INIT_STRCMP; \ INIT_STRNCMP; \ @@ -2918,4 +2949,5 @@ INTERCEPTOR(int, lrand48_r, void *buffer, long *result) { INIT_LGAMMA; \ INIT_LGAMMA_R; \ INIT_DRAND48_R; \ + INIT_GETLINE; \ /**/ diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h index 3346be01..f9a9870c 100644 --- a/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -150,6 +150,9 @@ # define SANITIZER_INTERCEPT_LGAMMA_R SI_LINUX # define SANITIZER_INTERCEPT_DRAND48_R SI_LINUX_NOT_ANDROID +// FIXME: getline seems to be available on OSX 10.7 +# define SANITIZER_INTERCEPT_GETLINE SI_LINUX_NOT_ANDROID + # define SANITIZER_INTERCEPT__EXIT SI_LINUX # define SANITIZER_INTERCEPT_PHTREAD_MUTEX SI_NOT_WINDOWS diff --git a/lib/tsan/rtl/tsan_stat.cc b/lib/tsan/rtl/tsan_stat.cc index 6082120f..72d173de 100644 --- a/lib/tsan/rtl/tsan_stat.cc +++ b/lib/tsan/rtl/tsan_stat.cc @@ -412,6 +412,8 @@ void StatOutput(u64 *stat) { name[StatInt_lgammal_r] = " lgammal_r "; name[StatInt_drand48_r] = " drand48_r "; name[StatInt_lrand48_r] = " lrand48_r "; + name[StatInt_getline] = " getline "; + name[StatInt_getdelim] = " getdelim "; name[StatInt_pthread_attr_getdetachstate] = " pthread_addr_getdetachstate "; // NOLINT name[StatInt_pthread_attr_getguardsize] = " pthread_addr_getguardsize "; // NOLINT diff --git a/lib/tsan/rtl/tsan_stat.h b/lib/tsan/rtl/tsan_stat.h index 4d0ec3fc..d6ff93c5 100644 --- a/lib/tsan/rtl/tsan_stat.h +++ b/lib/tsan/rtl/tsan_stat.h @@ -407,6 +407,8 @@ enum StatType { StatInt_lgammal_r, StatInt_drand48_r, StatInt_lrand48_r, + StatInt_getline, + StatInt_getdelim, StatInt_pthread_attr_getdetachstate, StatInt_pthread_attr_getguardsize, -- cgit v1.2.3