All for clang and mostly Apple clang
There are still numerous deprecated warnings on macOS 10.13
(sem* functions, syscall, sbrk, i386, PIEi, OSSpinLocki, swapcontext, getcontext)
These tests generate a varying number of errors per argument
depending on the platform and compiler.
The filter just prints the first unique error stanza which
allows 8 expecteds to be removed.
Adds a new warning to memcheck when realloc is used with a size of 0.
For a long time this has been "implementation defined" and so
non-portable. With C23 it will become UB.
Also adds a switch to turn off the error generation and a
second switch to select between the most common
"implementation" behaviours. The defaults for this second
switch are baked in at build time.
The number of errors for arguments that gets triggered depends
on how GCC optimzes and generates code for the vg_replace_malloc.c
wrappers. PPC seems to trigger more than amd64.
This is the first part of
Bug 466104 aligned_alloc problems, part 1
The bulk of this change is try try to get memalign to be more
platform aware. Previously the Valgrind implementation only
reflected the glibc implementation. That meant non-power of
two alignment values would silently get bumped up to the
next largest power of two. Most other platforms return NULL
and set errno to EINVAL.
There are a few other changes. A couple of the other aligned alloc
functions like valloc were caling the Valgrind memalign. This meant
that there weould be an extra Valgrind memalign in any error
callstacks. Now these functions call the allocator directly.
The memcheck memalign2 testcase has been redone. The memalign
parts moved out to per-platform versions and the tescase
itdelf renamed to posix_memalign, since that is all that is left.
I also modified the testcase so that it checks that the
memalign calls check for non-NULL returns, and on platforms
that set errno that it is correctly set. Previously the
test only worked on non-glibc because NULL & alignment is
zero. The platform versions have been tested on glibc,
MUSL, FreeBSD and OpenIndiana and should hopefully run OK
both under memcheck and standalone.
There is stil quite a lot that is NOT done
1. I'm not certain that implementations allocate more memory
and/or use a wider alignment. It doesn't help that almost
universally the memalign implementations are badly
documented, undocumented or buggy.
2. We don't handle very large alignment requests well.
Most implementations will fail and set EINVAL if the
alignment is over half the memory space. Valgrind will
core panic if an aligmnt of over 16Mbytes is requested.
3. We don't generate any memcheck errors for invalid values
of alignment. That's planned in Part 2.
4. The code is static and fixed at compile time. That means that
if you are using MUSL with a glibc-built Valgrind you
will still get glibc memalign behaviour.
I'll wait to see if there are any requests before trying
to make the behaviour selectable at runtime.
Many changes mostly related to modifying VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd )
so that instead of triggering debuginfo reading after seeing one RX PT_LOAD and 1 RW PT_LOAD it
can handle either 1 or 2 RW PT_LOADs.
There is a difference between the outputs when using
32bit and 64bit with clang++/libc++
Running the test in a shell with the output piped through c++filt I see
64bit:
--2153-- operator new[](unsigned long)(32) = 0x55AB040
--2153-- malloc(31) = 0x55AB0A0
--2153-- operator new[](unsigned long)(8) = 0x55AB100
--2153-- operator new(unsigned long)(16) = 0x55AB150
--2153-- operator new(unsigned long)(16) = 0x55AB1A0
--2153-- operator new(unsigned long)(32) = 0x55AB1F0
--2153-- operator new(unsigned long)(32) = 0x55AB250
32bit:
--55024-- operator new[](unsigned int)(28) = 0x7D41030
--55024-- malloc(31) = 0x7D41090
--55024-- operator new[](unsigned int)(4) = 0x7D410F0
--55024-- operator new(unsigned int)(8) = 0x7D41140
--55024-- operator new(unsigned int)(8) = 0x7D41190
--55024-- operator new(unsigned int)(16) = 0x7D411E0
--55024-- operator new(unsigned int)(16) = 0x7D41230
--55024-- operator new(unsigned int)(32) = 0x7D41280
Note the extra 32 byte allocation at the end. This is because of
str2 += " rocks (str2)\n"; // interior ptr.
at the end of void doit(void)
Details of the mechaism here
https://stackoverflow.com/questions/21694302/what-are-the-mechanics-of-short-string-optimization-in-libc
str2 starts containing 9 characters "Valgrind"
Catenating to it makes it "Valgrind rocks (str2)\n" which is exactly 22 characters.
The 64bit SSO has a capacity of 22 chars, so there is no need to switch from
SSO in the stack variable to using heap allocation.
The 32bit SSO only has a capacity of 10, so there there is space
in the SSO for the initial string but the catenation expands it
beyond the SSO capacity and there is a heap allocation
via the std::basic_string allocator, which calls raw ::operator new.
The difference is in the si_code. Linux has a value of 0, FreeBSD has
65537. This is correct.
From vki-freebsd.h
/*
* si_code values
*/
and indeed this signal gets sent by kill()
Was getting warnings with clang like
memalign2.c:62:17: warning: requested alignment is not a power of 2 [-Wnon-power-of-two-alignment]
p = memalign(0, 100); assert(0 == (long)p % 8);
This is unfortunately a big and complex patch, to implement LD{,A}XP and
ST{,L}XP. These were omitted from the original AArch64 v8.0 implementation
for unknown reasons.
(Background) the patch is made significantly more complex because for AArch64
we actually have two implementations of the underlying
Load-Linked/Store-Conditional (LL/SC) machinery: a "primary" implementation,
which translates LL/SC more or less directly into IR and re-emits them at the
back end, and a "fallback" implementation that implements LL/SC "manually", by
taking advantage of the fact that V serialises thread execution, so we can
"implement" LL/SC by simulating a reservation using fields LLSC_* in the guest
state, and invalidating the reservation at every thread switch.
(Background) the fallback scheme is needed because the primary scheme is in
violation of the ARMv8 semantics in that it can (easily) introduce extra
memory references between the LL and SC, hence on some hardware causing the
reservation to always fail and so the simulated program to wind up looping
forever.
For these instructions, big picture:
* for the primary implementation, we take advantage of the fact that
IRStmt_LLSC allows I128 bit transactions to be represented. Hence we bundle
up the two 64-bit data elements into an I128 (or vice versa) and present a
single I128-typed IRStmt_LLSC in the IR. In the backend, those are
re-emitted as LDXP/STXP respectively. For LL/SC on 32-bit register pairs,
that bundling produces a single 64-bit item, and so the existing LL/SC
backend machinery handles it. The effect is that a doubleword 32-bit LL/SC
in the front end translates into a single 64-bit LL/SC in the back end.
Overall, though, the implementation is straightforward.
* for the fallback implementation, it is necessary to extend the guest state
field `guest_LLSC_DATA` to represent a 128-bit transaction, by splitting it
into _DATA_LO64 and DATA_HI64. Then, the implementation is an exact
analogue of the fallback implementation for single-word LL/SC. It takes
advantage of the fact that the backend already supports 128-bit CAS, as
fixed in bug 445354. As with the primary implementation, doubleword 32-bit
LL/SC is bundled into a single 64-bit transaction.
Detailed changes:
* new arm64 guest state fields LLSC_DATA_LO64/LLSC_DATA_LO64 to replace
guest_LLSC_DATA
* (ridealong fix) arm64 front end: a fix to a minor and harmless decoding bug
for the single-word LDX/STX case.
* arm64 front end: IR generation for LD{,A}XP/ST{,L}XP: tedious and
longwinded, but per comments above, an exact(ish) analogue of the singleword
case
* arm64 backend: new insns ARM64Instr_LdrEXP / ARM64Instr_StrEXP to wrap up 2
x 64 exclusive loads/stores. Per comments above, there's no need to handle
the 2 x 32 case.
* arm64 isel: translate I128-typed IRStmt_LLSC into the above two insns
* arm64 isel: some auxiliary bits and pieces needed to handle I128 values;
this is standard doubleword isel stuff
* arm64 isel: (ridealong fix): Ist_CAS: check for endianness of the CAS!
* arm64 isel: (ridealong) a couple of formatting fixes
* IR infrastructure: add support for I128 constants, done the same as V128
constants
* memcheck: handle shadow loads and stores for I128 values
* testcase: memcheck/tests/atomic_incs.c: on arm64, also test 128-bit atomic
addition, to check we really have atomicity right
* testcase: new test none/tests/arm64/ldxp_stxp.c, tests operation but not
atomicity. (Smoke test).
The demangle-rust.vgtest would fail because the demangle-rust binary
wasn't build by default. Add it to check_PROGRAMS and define
demangle_rust_SOURCES to make sure it is always build.
There's one remaining
memalign2.c:29:9: warning: unused variable 'piece' [-Wunused-variable]
because of a block of #if FreeBSD for memalign that looks unnecessary
Otherwise all that is left is a few like
warning: unknown warning option '-Wno-alloc-size-larger-than'; did you mean '-Wno-frame-larger-than='? [-Wunknown-warning-option]
because there is no standard for compiler arguments.
GCC12 catches various issues in tests at compile time that we want to
catch at runtime. Also glibc 2.34 deprecated various mallinfo related
functions. Add the relevant -Wno-foobar flags to those tests. In one
case, unit_oset.c, the warning was correct and the uninitialized
variable was explicitly set.
Various tests do things which we want to detect at runtime, like
ignoring the result of malloc or doing a deliberate impossibly large
allocation or operations that would result in overflowing or
truncated strings, that generate a warning from gcc.
In once case, mq_setattr called with new and old attrs overlapping,
this was explicitly fixed, in others -Wno-foobar was added to silence
the warning. This is safe even for older gcc, since a compiler will
ignore any -Wno-foobar they don't know about - since they do know they
won't warn for foobar.
Files in the root directory
Several Makefile.am files that have dependencies on FreeBSD autoconf
variables. Included a few new filter files to act as placeholders
to create new freebsd subdirectories.
Updated NEWS with the FreeBSD bugzilla items plus a couple of other
items fixed indirectly.
This patch changes the option parsing framework to allow a set of
core or tool (currently only memcheck) options to be changed dynamically.
Here is a summary of the new functionality (extracted from NEWS):
* It is now possible to dynamically change the value of many command
line options while your program (or its children) are running under
Valgrind.
To have the list of dynamically changeable options, run
valgrind --help-dyn-options
You can change the options from the shell by using vgdb to launch
the monitor command "v.clo <clo option>...".
The same monitor command can be used from a gdb connected
to the valgrind gdbserver.
Your program can also change the dynamically changeable options using
the client request VALGRIND_CLO_CHANGE(option).
Here is a brief description of the code changes.
* the command line options parsing macros are now checking a 'parsing' mode
to decide if the given option must be handled or not.
(more about the parsing mode below).
* the 'main' command option parsing code has been split in a function
'process_option' that can be called now by:
- early_process_cmd_line_options
(looping over args, calling process_option in mode "Early")
- main_process_cmd_line_options
(looping over args, calling process_option in mode "Processing")
- the new function VG_(process_dynamic_option) called from
gdbserver or from VALGRIND_CLO_CHANGE (calling
process_option in mode "Dynamic" or "Help")
* So, now, during startup, process_option is called twice for each arg:
- once during Early phase
- once during normal Processing
Then process_option can then be called again during execution.
So, the parsing mode is defined so that the option parsing code
behaves differently (e.g. allows or not to handle the option)
depending on the mode.
// Command line option parsing happens in the following modes:
// cloE : Early processing, used by coregrind m_main.c to parse the
// command line options that must be handled early on.
// cloP : Processing, used by coregrind and tools during startup, when
// doing command line options Processing.
// clodD : Dynamic, used to dynamically change options after startup.
// A subset of the command line options can be changed dynamically
// after startup.
// cloH : Help, special mode to produce the list of dynamically changeable
// options for --help-dyn-options.
typedef
enum {
cloE = 1,
cloP = 2,
cloD = 4,
cloH = 8
} Clo_Mode;
The option parsing macros in pub_tool_options.h have now all a new variant
*_CLOM with the mode(s) in which the given option is accepted.
The old variant is kept and calls the new variant with mode cloP.
The function VG_(check_clom) in the macro compares the current mode
with the modes allowed for the option, and returns True if qq_arg
should be further processed.
For example:
// String argument, eg. --foo=yes or --foo=no
(VG_(check_clom) \
(qq_mode, qq_arg, qq_option, \
VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) && \
({const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \
if VG_STREQ(val, "yes") (qq_var) = True; \
else if VG_STREQ(val, "no") (qq_var) = False; \
else VG_(fmsg_bad_option)(qq_arg, "Invalid boolean value '%s'" \
" (should be 'yes' or 'no')\n", val); \
True; }))
VG_BOOL_CLOM(cloP, qq_arg, qq_option, qq_var)
To make an option dynamically excutable, it is typically enough to replace
VG_BOOL_CLO(...)
by
VG_BOOL_CLOM(cloPD, ...)
For example:
- else if VG_BOOL_CLO(arg, "--show-possibly-lost", tmp_show) {
+ else if VG_BOOL_CLOM(cloPD, arg, "--show-possibly-lost", tmp_show) {
cloPD means the option value is set/changed during the main command
Processing (P) and Dynamically during execution (D).
Note that the 'body/further processing' of a command is only executed when
the option is recognised and the current parsing mode is ok for this option.
On powerpc partial unaligned loads of words from partially invalid
addresses are OK and could be generated by our translation of ldbrx.
Adjust partial_load memcheck tests to allow partial loads of words
on powerpc64.
Part of resolving bug #386945.
glibc 2.28 filters out some bad signal numbers and returns
Invalid argument instead of passing such bad signal numbers
the kernel sigaction syscall. So we won't see such bad signal
numbers and won't print "bad signal number" ourselves.
Add a new memcheck/tests/sigkill.stderr.exp-glibc-2.28 to catch
this case.