public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug sanitizer/97229] New: pointer-compare sanitizer is very slow due to __asan::IsAddressNearGlobal
@ 2020-09-28 13:34 mail at milianw dot de
  2020-09-29 15:15 ` [Bug sanitizer/97229] " marxin at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: mail at milianw dot de @ 2020-09-28 13:34 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97229

            Bug ID: 97229
           Summary: pointer-compare sanitizer is very slow due to
                    __asan::IsAddressNearGlobal
           Product: gcc
           Version: 10.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mail at milianw dot de
                CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
                    jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at gcc dot gnu.org
  Target Milestone: ---

I am trying to use the pointer-compare sanitizer during product development. I
noticed that it is usually fine from a performance POV, but one specific code
path is getting extremely slow. Quasi 99% of the CPU samples point at this
backtrace:

```
<our code>
__sanitizer_ptr_cmp
__asanCheckForInvalidPointerPair
__asanCheckForInvalidPointerPair
__asan::IsInvalidPointerPair
__asan::GetGlobalAddressInformation(unsigned long, unsigned long, ...)
__asan::GetGlobalsForAddress(unsigned long, __asan_global*, ...)
__asan::isAddressNearGlobal
```

I have tried to simulate what our code does in this simplistic example: It
copies one file to another in a stupid way via mmap. The pointer comparison is
within the copy() function below.

```
#include <cstdio>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

#include <algorithm>

static
__attribute__((noinline))
void copy(const unsigned char *source, size_t source_size,
          unsigned char *target, size_t target_size)
{
    if (target + source_size > target + target_size) {
        fprintf(stderr, "bad offsets: %zu %zu\n", target_size, source_size);
        return;
    }
    std::copy_n(source, source_size, target);
}

unsigned char* mapBuffer(const char *path, size_t size)
{
    auto fd = open(path, O_CREAT | O_RDWR, 0600);
    if (fd == -1) {
        perror("failed to open file");
        return nullptr;
    }

    if (posix_fallocate64(fd, 0, size) != 0) {
        perror("failed to resize file");
        close(fd);
        return nullptr;
    }

    auto buffer = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
0);
    close(fd);

    if (!buffer) {
        perror("failed to mmap file");
        return nullptr;
    }

    return reinterpret_cast<unsigned char*>(buffer);
}

int main(int argc, char **argv)
{
    if (argc != 3) {
        fprintf(stderr, "USAGE: ./a.out BUFFER_SIZE COPY_SIZE\n");
        return 1;
    }

    const auto size_i = atoi(argv[1]);
    if (size_i < 0) {
        fprintf(stderr, "bad size: %d\n", size_i);
        return 1;
    }
    const auto size = static_cast<size_t>(size_i);

    const auto copySize_i = atoi(argv[2]);
    if (copySize_i < 0 || copySize_i > size_i || (size_i % copySize_i) != 0) {
        fprintf(stderr, "bad copy size: %d %d\n", copySize_i, size_i);
        return 1;
    }
    const auto copySize = static_cast<size_t>(copySize_i);

    auto source = mapBuffer("/tmp/source.dat", size);
    if (!source) {
        return 1;
    }

    auto target = mapBuffer("/tmp/target.dat", size);
    if (!target) {
        return 1;
    }

    for (int i = 0; i < size; i += copySize) {
        copy(source + i, copySize, target + i, copySize);
    }

    munmap(source, size);
    munmap(target, size);
    return 0;
}
```

But that demo does not show the extreme slow down. It is actually behaving
quite well, at most 10% slow down, when enabling pointer-compare with the
ASAN_OPTIONS env var.

In the real application, the slow-down is more in the order of 100x or more.
That app links in a lot of other libraries and also runs code in multiple
threads, so I suspect that the issue I'm seeing is related to the amount of
globals and potentially libraries available in the application?  Any idea how I
could reproduce this to create a proper MWE?

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-10-02  9:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-28 13:34 [Bug sanitizer/97229] New: pointer-compare sanitizer is very slow due to __asan::IsAddressNearGlobal mail at milianw dot de
2020-09-29 15:15 ` [Bug sanitizer/97229] " marxin at gcc dot gnu.org
2020-09-30 13:26 ` mail at milianw dot de
2020-10-02  9:48 ` marxin at gcc dot gnu.org
2020-10-02  9:50 ` marxin at gcc dot gnu.org
2020-10-02  9:51 ` marxin at gcc dot gnu.org
2020-10-02  9:53 ` marxin at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).