Running on a kernel that supports the SCV instruction (sets
PPC_FEATURE2_SCV in auxv AT_HWCAPS2) valgrind will assert: valgrind:
m_syswrap/syswrap-main.c:549 (getSyscallArgsFromGuestState): Assertion
'gst->guest_syscall_flag == SC_FLAG' failed.
Removing that assert makes most things work. But also filter out
PPC_FEATURE2_SCV from AT_HWCAPS2 for the client, so it shouldn't try
using the SCV instruction.
https://bugs.kde.org/show_bug.cgi?id=469097
rfork() is barely used in base FreeBSD. The main use
is in posix_spawn(). If rfork() fails with EINVAL
then it falls back to using vfork(). This is preferable
to Valgrind bombing.
ksh93 uses posix_spawn. I tested bash and csh and they had
no problems.
Also add 'hello world" smoke tests for bash csh and ksh
There was some code to handle /proc/curproc/file (a symlink to
the exe that wee need to bodge as it refers to the tool exe).
But it was neither tested nor working.
Can't use the same technique as Linux and Solaris which have more
complete /proc filesystems where each pid has symlinks for
each open file, which we use for the guest. Instead need to
copy the path ourselves. So move sys_readlink out of generic.
Simplify the handling of the resolved guest exe name - store it in
a global like VG_(args_the_exename).
This was being copied from the host. Now it's synthesized for
the guest. Also improve the none/freebsd/auxv test to
print a few of the strings in auxv (but not the envp ones).
On FreeBSD, Firefox uses the kern.proc.pathname.PID sysctl
to get the binary path (where PID can be the actual pid
or -1). The user path is /usr/local/bin/firefox which is
a symlink to /usr/local/lib/firefox/firefox.
This was failing because we were not handling this MIB.
That meant that the sysctl returned the path for the
binary of the running tool (e.g.,
/home/paulf/scratch/valgrind/memcheck/memcheck-amd64-freebsd).
Firefox looks for files in the same directory.
Since it was the wrong directory it failed to find them and
exited.
I also noticed a lot of _umtx_op errors. On analysis they
are spurious. The wake ops take an "obj" argument, a pointer
to a variable. They only use the address as a key for
lookups and don't read the contents.
Note that this modifies files on darwin/solaris/bsd but I only did a linux
build so possibly this commit might cause a compilation error, that should
then be trivial to fix.
Also added memmem test in the list of ignored files.
There is quite a lot of stuff here.
The problem is that setproctitle and kern.ps_strings were using the Valgrind host auxv
rather than the guest. The proposed patch would have just ignored those memory ranges.
I've gone a fair bit further than that
1. refactored the initimg code for building the client auxv. Previously we were
simply ignoring any non-scalar entries. Now we copy most of thse as well.
That means that 'strtab' built on the client stack no longet only contains
strings, at can also now contain binary structures. Note I was a bit
concerned that there may be some alignment issues, but I haven't seen any
problems so far.
2. Added intercepts to sysctl and sysctlbyname for kern.ps_strings, then find
AT_PS_STRINGS from the client auxv that is now usable from step 1.
3. Some refactoring of sysctl and sysctlbyname syscall wrappers. More to do
there!
4. Added a setproctitle testcase (that also tests the sysctls).
5. Updated the auxv testcase now that more AT_* entries are handled.
Like buf, path (ARG2) is a const HChar *
Prevents a gcc warning: assignment discards 'const' qualifier from
pointer target type [-Wdiscarded-qualifiers]
13328 | path = buf;
| ^
I was using a global variable. This would be set to '1' just before
calling the function to save cflags and cleared just after, then
using the variable to fill in the 'outside_rnage_ condition
in VG_(fixup_guest_state_after_syscall_interrupted)
Even though I haven't experienced any isseus with that, the comments just before
do_syscall_for_client made me want to try an alternative.
This code is very ugly and won't please the language lawyers.
Functions aren't guaranteed to have an address and there is no
guarantee that the binary layout will reflect the source layout.
Sadly C doesn't have something like "sizeof(*function)" to give
the size of a function in bytes. The next best that I could
manage was to use dummy 'marker' functions just after the
ones I want the end address of and then use the address of
'marker - 1'
I did think of one other way to do this. That would be to
generate a C file containing the function sizes. This would
require
1. "put_flag_size.c" would depend on the VEX guest_(x86|amd64)_helpers
object files
2. Extract the sizes, for instance
echo -n "const size_t x86_put_eflag_c_size = 0x" > put_flag_size.c
nm -F sysv libvex_x86_freebsd_a-guest_x86_helpers.o | awk -F\| '/LibVEX_GuestX86_put_eflag_c/{print $5}' >> put_flag_size.c
echo ";" >> put_flag_size.c
That seems fairly difficult to do in automake and I'm not sure if
it would be robust.
After working on an issue that turns out to seem to be with the
FreeBSD kernel sched_uler I played a lot with the Valgrind
syscall and scheduler code. I've kept the comments and the
reformatting.
These concern auxv, swapoff and fcntl F_KINFO
I wanted to use the new fcntl K_INFO to replace the existing
horrible implementation of resolve_filename, but it seems to
have change the behaviour for redirected files. Several
fdleak regtests fail because stdout resolves to an empty
string.
memfd_secret is a new syscall in linux 5.14. memfd_secret() is
disabled by default and a command-line option needs to be added to
enable it at boot time.
$ cat /proc/cmdline
[...] secretmem.enable=y
https://bugs.kde.org/451878https://lwn.net/Articles/865256/
FreeBSD (and Darwin) use the carry flag for syscall syscall status.
That means that in the assembler for do_syscall_for_client_WRK
they have a call to LibVEX_GuestAMD64_put_rflag_c (amd64) or
LibVEX_GuestX86_put_eflag_c (x86). These also call WRK functions.
The problem is that do_syscall_for_client_WRK has carefully crafted
labels correspinding to IP addresses. If a signal interrupts
processdings, IP can be compared to these addresses so that
VG_(fixup_guest_state_after_syscall_interrupted) can work
out how to resume the syscall. But if IP is in the save
carry flag functions, the address is not recognized and
VG_(fixup_guest_state_after_syscall_interrupted) fails.
The crash in the title happens because the interrupted
syscall does not reset its status, and on the next syscall
it is expected that the status be idle.
To fix this I added global variables that get set to 1
just before calling the save carry flag functions, and cleared
just after. VG_(fixup_guest_state_after_syscall_interrupted)
can then check this and work out which section we are in
and resume the syscall correctly.
Also:
Start a new NEWS section for 3.20
Add a regtest for this and also a similar one for Bug 445032
(x86-freebsd only, new subdir).
I saw that this problem also probably exists with macOS, so I made
the same changes there (not yet tested)