If libc++ is built as a DLL, calls to operator new within the DLL aren't
overridden if a user provides their own operator in calling code.
Therefore, the alloc counter doesn't pick up on allocations done within
std::string, so skip that check if running on windows. (Technically,
we could keep the checks if running on windows when not built as a DLL,
but trying to keep the conditionals simple.)
Details
- Reviewers
ldionne - Group Reviewers
Restricted Project - Commits
- rG0e8f5e4a6864: [libcxx] [test] Skip alloc counter checks for operations within the libc++ DLL
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
@curdeius This one is the next one for getting rid of LIBCXX-WINDOWS-FIXME in the filesystem tests (this one drops the number of remaining fixmes from 7 to 3). What do you think of this one? I've tried to keep an explanatory comment next to each case.
libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp | ||
---|---|---|
144–146 | Should this be considered a bug in the Windows runtime? If so, it's not doing any good to work around it in our test suite, we should instead:
|
libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp | ||
---|---|---|
144–146 | It's not a bug in the Windows runtime that can be fixed reasonably, it's only between libc++ and the executable formats used on the platform. The root cause is that PE-COFF DLLs are "sealed" two-level namespaces. If you provide operator new in user code, this overrides libc++'s operator new within that executable, and within libc++ if it is linked statically. If libc++ is linked as a DLL, all references to operator new within the DLL are hardwired at link time to the operator new provided there. It doesn't have the ELF/MachO feature of a GOT where the executable can override any symbol used in libraries loaded. So here, the operator new that is overridden in the test, to count allocations, isn't invoked and doesn't count allocations that happen within the libc++ DLL. It does count the ones that are done by calls in the test executable. |
libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp | ||
---|---|---|
144–146 | If you'd prefer, I could narrow it down to the windows+dll case - that'd be a bit more verbose, but should be doable. |
Narrowed down the condition to only when specifically built as DLL, included another file with the same issue.
Thanks for the explanation. That sounds like a bug in the object format, basically, cause that means we can't implement C++ properly (which requires being able to override operator new).
Yeah I guess so.
The same effect also means that one process can have multiple copies of the C runtime (there are, historically, multiple different ones that can be linked dynamically, and each DLL can also have a private copy of the C runtime linked in statically). Then one has to take care that the same runtime that e.g. allocated memory with malloc also frees it, and e.g. calls to functions like open/write/close are confined to the same instance of the runtime.
Should this be considered a bug in the Windows runtime? If so, it's not doing any good to work around it in our test suite, we should instead: