Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port valgrind #414

Open
bugaevc opened this issue Aug 21, 2018 · 0 comments
Open

Port valgrind #414

bugaevc opened this issue Aug 21, 2018 · 0 comments
Labels
Enhancement A way Darling can be improved

Comments

@bugaevc
Copy link
Member

bugaevc commented Aug 21, 2018

Valgrind is one of those tools that do care about syscall ABI, so we cannot run the Darwin version directly (nor can we use the Linux version, because it doesn't know how to deal with Mach-O and stuff). Valgrind is incredibly useful for diagnosing memory-related bugs, so it'd be nice to be able to use it on Darling (for Darling itself; but also for people who want to valgrind their software targeting Darwin, e.g. on a CI server).

The way Valgrind works (link, link):

  • Valgrind itself runs in the same process as the program it inspects
  • It doesn't run the program directly; it decompiles its instructions into some intermediate representation, instruments that and compiles it back
  • Valgrind implements the syscall ABI manually, two times:
    • Whenever the program needs to do a syscall, Valgrind loads the emulated register values into the real registers and pretends it's the program that makes the syscall. It also records the effect the syscall has on program state; e.g. getcwd(2) on Linux reads a char * value from buf (so Valgrind makes sure it's initialized) and a size_t value from size and writes up to size bytes to the memory pointed to by buf (thus initializing it).
    • Valgrind itself doesn't use glibc/libSystem, it implements what it needs itself and makes syscalls directly.
  • It does something to dyld (of the target program) to have it replace the allocator, and otherwise inspects the Mach-O files it runs to e.g. record and display meaningful backtraces.

The upstream Valgrind can be built for either Linux or Darwin, but we'd have to mix & match:

  • valgrind itself (and all of its tools) should be built as Mach-O, to have access to all the LKM features
  • We need its support for dyld/Mach-Os binaries (but maybe also for ELFs/ld-linux in the same build, if that's possible? it'd be cool to catch "malloc'd on the Linux side, freed on the Darwin side" kind of bugs).
  • Valgrind itself should make vanilla Linux syscalls
  • It should expect the program to make Linux syscalls too, except it's going to have to support our /dev/mach ioctls
    • With a bit of luck, we could reuse the Darwin Mach traps support it has already
    • A complication I anticipate is Mach traps being too low-level: cmp. "the program is sending some Mach message to its task port" to "the program asks the kernel to unmap this page"
    • But then it somehow works on the upstream macOS, so it should be fine; most Mach messages only read/write the explicitly passed buffers anyway.

Apparently, "The development (trunk) versions of both Valgrind and Wine now have enough awareness of each other that they can apparently be used together.", so Valgrind devs might be interested in pulling this port, if it ever materializes, upstream. Or maybe not, and we'd have to maintain a fork.

@bugaevc bugaevc added the Enhancement A way Darling can be improved label Aug 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement A way Darling can be improved
Projects
None yet
Development

No branches or pull requests

1 participant