|
1 | 1 | #define CAML_NAME_SPACE
|
| 2 | +#include <caml/config.h> |
| 3 | +#ifdef WITH_ADDRESS_SANITIZER |
| 4 | +#include <dlfcn.h> |
| 5 | +#endif |
2 | 6 | #include <caml/memory.h>
|
3 | 7 | #include <caml/mlvalues.h>
|
4 | 8 | #include <caml/alloc.h>
|
@@ -71,6 +75,24 @@ static int cmp_callback(const void* p_a, const void* p_b)
|
71 | 75 | return Long_val(caml_callback2(*cmp_fn, **a, **b));
|
72 | 76 | }
|
73 | 77 |
|
| 78 | +#ifdef WITH_ADDRESS_SANITIZER |
| 79 | +/* AddressSanitizer provides its own definition of [qsort], which runs the comparator |
| 80 | + function over the entire array in order to detect memory safety issues [1]. |
| 81 | + That breaks this test, since the output of the test depends on how many times the |
| 82 | + comparator function is invoked. To work around this, we retrieve the standard [qsort] |
| 83 | + definition provided by [libc] using [dlsym], and call that directly. |
| 84 | +
|
| 85 | + [1]: https://github.com/llvm/llvm-project/blob/1101b767329dd163d528fa5f667a6c0dbdde0ad5/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc#L10047-L10051 |
| 86 | +*/ |
| 87 | +void qsort(void *base, size_t nmemb, size_t size, __compar_fn_t compar) { |
| 88 | + static void (*libc_qsort)(void *, size_t, size_t, __compar_fn_t) = NULL; |
| 89 | + if (libc_qsort == NULL) { |
| 90 | + libc_qsort = dlsym(RTLD_NEXT, "qsort"); |
| 91 | + } |
| 92 | + libc_qsort(base, nmemb, size, compar); |
| 93 | +} |
| 94 | +#endif |
| 95 | + |
74 | 96 | value sort2(value cmp_clos, value a, value b)
|
75 | 97 | {
|
76 | 98 | CAMLparam3(cmp_clos, a, b);
|
|
0 commit comments