Description of problem: valgrind appears to only interject readlink on /proc/self/exe to redirect it to the executed program's binary, but not a direct open on the link. This means any sensibly written program opening its own binary that wants to avoid bad race conditions (which you get by readlink'ing /proc/self/exe as a path, then opening the path which leaves a short time window where the path target could be switched out) will now open the memcheck binary instead of itself, and break if it expects to find some specific data in its own binary. Since I do not really wish to reintroduce race conditions just to have valgrind compatibility, it would be great if this could be addressed. Version-Release number of selected component (if applicable): $ valgrind --version valgrind-3.16.1 How reproducible: 100% Steps to Reproduce: 1. Write a small program which firstly uses fopen on "/proc/self/exe" inside the program (not readlink!), secondly uses fseek(file_handle, 0, CURR_END) and ftell(file_handle) and prints the result 2. Run the program in valgrind Actual results: Printed size matches /usr/lib64/valgrind/amd64-linux/memcheck exactly in bytes Expected results: Printed size matches what your program binary is sized in bytes Additional info:
Would have a real example? And/Or could you test this (untested) patch? diff --git a/coregrind/m_syswrap/priv_syswrap-generic.h b/coregrind/m_syswrap/priv_syswrap-generic.h index 4717abac6..c50b31399 100644 --- a/coregrind/m_syswrap/priv_syswrap-generic.h +++ b/coregrind/m_syswrap/priv_syswrap-generic.h @@ -106,6 +106,10 @@ extern Bool ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename, int flags); +extern Bool +ML_(handle_self_exe_open)(SyscallStatus *status, const HChar *filename, + int flags); + /* Helper function for generic mprotect and linux pkey_mprotect. */ extern void handle_sys_mprotect (ThreadId tid, SyscallStatus *status, Addr *addr, SizeT *len, Int *prot); diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 7d4b385a3..3810f7474 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -4078,6 +4078,38 @@ Bool ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename, } #endif // defined(VGO_linux) || defined(VGO_solaris) +#if defined(VGO_linux) +Bool ML_(handle_self_exe_open)(SyscallStatus *status, const HChar *filename, + int flags) +{ + HChar name[30]; // large enough for /proc/<int>/exe + + if (!ML_(safe_to_deref)((const void *) filename, 1)) + return False; + + /* Opening /proc/<pid>/exe or /proc/self/exe? */ + VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)()); + if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/exe")) + return False; + + /* Allow to open the file only for reading. */ + if (flags & (VKI_O_WRONLY | VKI_O_RDWR)) { + SET_STATUS_Failure(VKI_EACCES); + return True; + } + + SysRes sres = VG_(dup)(VG_(cl_exec_fd)); + SET_STATUS_from_SysRes(sres); + if (!sr_isError(sres)) { + OffT off = VG_(lseek)(sr_Res(sres), 0, VKI_SEEK_SET); + if (off < 0) + SET_STATUS_Failure(VKI_EMFILE); + } + + return True; +} +#endif // defined(VGO_linux) + PRE(sys_open) { if (ARG2 & VKI_O_CREAT) { @@ -4119,8 +4151,10 @@ PRE(sys_open) } } - /* Handle also the case of /proc/self/auxv or /proc/<pid>/auxv. */ - if (ML_(handle_auxv_open)(status, (const HChar *)(Addr)ARG1, ARG2)) + /* Handle also the case of /proc/self/auxv or /proc/<pid>/auxv + or /proc/self/exe or /proc/<pid>/exe. */ + if (ML_(handle_auxv_open)(status, (const HChar *)(Addr)ARG1, ARG2) + || ML_(handle_self_exe_open)(status, (const HChar *)(Addr)ARG1, ARG2)) return; #endif // defined(VGO_linux)
> Would have a real example? #include <inttypes.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, const char **argv) { printf("Program starting.\n"); printf("Waiting for 10 seconds...\n"); usleep(10 * 1000000); printf("Opening /proc/self/exe...\n"); FILE *f = fopen("/proc/self/exe", "rb"); if (!f) { printf("Opening failed.\n"); return 1; } if (fseek(f, 0, SEEK_END) != 0) { printf("Seek failed.\n"); return 1; } int64_t result = ftell(f); if (result < 0) { printf("ftell() failed.\n"); return 1; } printf("size: %" PRId64 "\n", (int64_t)result); return 0; } The printed size is wrong with valgrind, you can compare using stat on the binary before you run it. Also, my real world program fails because it reads archive data appended to its binary via this method, and in valgrind the archive data is just not found (since it ends up opening the memcheck binary which of course doesn't have the appended archives). > And/Or could you test this (untested) patch? Hmm I actually have no clue how to compile valgrind, but let me have a look if I can figure it out
Additional note: the usleep() is not necessary to test this, I just wanted to test what happened to /proc/self/exe when unlinking it while the program is running. (If you were curious, it still works and points to the deleted file.) If that part doesn't work inside valgrind anymore that'd be a somewhat acceptable corner case to me though, as long as it at least works when the excuted file isn't moved or removed.
Okay, so I tried https://sourceware.org/git?p=valgrind.git;a=commit;h=b918f710208889d579026627830a80b24be1513d with your patch applied, and at least my own real world test program does NOT work with it, assuming I built valgrind right: ... 2021-02-06T18:41:50.6551174Z Step 7/15 : RUN cd /tmp/valgrind && patch -p1 < ./valgrind.patch 2021-02-06T18:41:50.6877802Z ---> Running in 7e62a32f22b6 2021-02-06T18:41:50.9693833Z patching file coregrind/m_syswrap/priv_syswrap-generic.h 2021-02-06T18:41:50.9694617Z patching file coregrind/m_syswrap/syswrap-generic.c 2021-02-06T18:41:52.2818650Z Removing intermediate container 7e62a32f22b6 2021-02-06T18:41:52.2819726Z ---> c3ea5ac1bba2 2021-02-06T18:41:52.2820153Z Step 8/15 : RUN cd /tmp/valgrind && ./autogen.sh && ./configure 2021-02-06T18:41:52.3183451Z ---> Running in c028d49f9953 2021-02-06T18:41:52.6388174Z running: aclocal ... 2021-02-06T18:42:16.4265194Z Step 9/15 : RUN cd /tmp/valgrind && make && make install 2021-02-06T18:42:16.4514762Z ---> Running in f4ebb5657020 2021-02-06T18:42:16.7380313Z echo "# This is a generated file, composed of the following suppression rules:" > default.supp 2021-02-06T18:42:16.7421658Z echo "# " xfree-3.supp xfree-4.supp glibc-2.X-drd.supp glibc-2.34567-NPTL-helgrind.supp glibc-2.X.supp >> default.supp 2021-02-06T18:42:16.7461736Z cat xfree-3.supp xfree-4.supp glibc-2.X-drd.supp glibc-2.34567-NPTL-helgrind.supp glibc-2.X.supp >> default.supp 2021-02-06T18:42:16.7479421Z ./auxprogs/make_or_upd_vgversion_h . 2021-02-06T18:42:17.3134343Z make all-recursive ... 2021-02-06T18:45:14.6365964Z Step 10/15 : RUN valgrind --help; valgrind --version 2021-02-06T18:45:14.6534721Z ---> Running in 7e1361e3e8bf 2021-02-06T18:45:14.9669994Z usage: valgrind [options] prog-and-args 2021-02-06T18:45:14.9670549Z 2021-02-06T18:45:14.9698572Z tool-selection option, with default in [ ]: 2021-02-06T18:45:14.9699524Z --tool=<name> use the Valgrind tool named <name> [memcheck] 2021-02-06T18:45:14.9699884Z 2021-02-06T18:45:14.9701315Z basic user options for all Valgrind tools, with defaults in [ ]: 2021-02-06T18:45:14.9702344Z -h --help show this message 2021-02-06T18:45:14.9703114Z --help-debug show this message, plus debugging options 2021-02-06T18:45:14.9704562Z --help-dyn-options show the dynamically changeable options 2021-02-06T18:45:14.9705254Z --version show version 2021-02-06T18:45:14.9706114Z -q --quiet run silently; only print error msgs 2021-02-06T18:45:14.9706897Z -v --verbose be more verbose -- show misc extra info 2021-02-06T18:45:14.9707763Z --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no] 2021-02-06T18:45:14.9708812Z --trace-children-skip=patt1,patt2,... specifies a list of executables 2021-02-06T18:45:14.9709704Z that --trace-children=yes should not trace into 2021-02-06T18:45:14.9710842Z --trace-children-skip-by-arg=patt1,patt2,... same as --trace-children-skip= 2021-02-06T18:45:14.9711637Z but check the argv[] entries for children, rather 2021-02-06T18:45:14.9712360Z than the exe name, to make a follow/no-follow decision 2021-02-06T18:45:14.9713231Z --child-silent-after-fork=no|yes omit child output between fork & exec? [no] 2021-02-06T18:45:14.9714034Z --vgdb=no|yes|full activate gdbserver? [yes] 2021-02-06T18:45:14.9714590Z full is slower but provides precise watchpoint/step 2021-02-06T18:45:14.9715393Z --vgdb-error=<number> invoke gdbserver after <number> errors [999999999] 2021-02-06T18:45:14.9716151Z to get started quickly, use --vgdb-error=0 2021-02-06T18:45:14.9716826Z and follow the on-screen directions 2021-02-06T18:45:14.9717618Z --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none] 2021-02-06T18:45:14.9718202Z where event is one of: 2021-02-06T18:45:14.9718635Z startup exit valgrindabexit all none 2021-02-06T18:45:14.9719334Z --track-fds=no|yes track open file descriptors? [no] 2021-02-06T18:45:14.9720056Z --time-stamp=no|yes add timestamps to log messages? [no] 2021-02-06T18:45:14.9721028Z --log-fd=<number> log messages to file descriptor [2=stderr] 2021-02-06T18:45:14.9721772Z --log-file=<file> log messages to <file> 2021-02-06T18:45:14.9722514Z --log-socket=ipaddr:port log messages to socket ipaddr:port 2021-02-06T18:45:14.9723064Z 2021-02-06T18:45:14.9723631Z user options for Valgrind tools that report errors: 2021-02-06T18:45:14.9724334Z --xml=yes emit error output in XML (some tools only) 2021-02-06T18:45:14.9725008Z --xml-fd=<number> XML output to file descriptor 2021-02-06T18:45:14.9725653Z --xml-file=<file> XML output to <file> 2021-02-06T18:45:14.9726321Z --xml-socket=ipaddr:port XML output to socket ipaddr:port 2021-02-06T18:45:14.9727087Z --xml-user-comment=STR copy STR verbatim into XML output 2021-02-06T18:45:14.9727853Z --demangle=no|yes automatically demangle C++ names? [yes] 2021-02-06T18:45:14.9728627Z --num-callers=<number> show <number> callers in stack traces [12] 2021-02-06T18:45:14.9729386Z --error-limit=no|yes stop showing new errors if too many? [yes] 2021-02-06T18:45:14.9730474Z --exit-on-first-error=no|yes exit code on the first error found? [no] 2021-02-06T18:45:14.9731741Z --error-exitcode=<number> exit code to return if errors found [0=disable] 2021-02-06T18:45:14.9732965Z --error-markers=<begin>,<end> add lines with begin/end markers before/after 2021-02-06T18:45:14.9733731Z each error output in plain text mode [none] 2021-02-06T18:45:14.9734413Z --show-error-list=no|yes show detected errors list and 2021-02-06T18:45:14.9734951Z suppression counts at exit [no] 2021-02-06T18:45:14.9735556Z -s same as --show-error-list=yes 2021-02-06T18:45:14.9736271Z --keep-debuginfo=no|yes Keep symbols etc for unloaded code [no] 2021-02-06T18:45:14.9736851Z This allows saved stack traces (e.g. memory leaks) 2021-02-06T18:45:14.9737374Z to include file/line info for code that has been 2021-02-06T18:45:14.9738030Z dlclose'd (or similar) 2021-02-06T18:45:14.9738738Z --show-below-main=no|yes continue stack traces below main() [no] 2021-02-06T18:45:14.9739416Z --default-suppressions=yes|no 2021-02-06T18:45:14.9739927Z load default suppressions [yes] 2021-02-06T18:45:14.9741118Z --suppressions=<filename> suppress errors described in <filename> 2021-02-06T18:45:14.9742320Z --gen-suppressions=no|yes|all print suppressions for errors? [no] 2021-02-06T18:45:14.9746897Z --input-fd=<number> file descriptor for input [0=stdin] 2021-02-06T18:45:14.9750530Z --dsymutil=no|yes run dsymutil on Mac OS X when helpful? [yes] 2021-02-06T18:45:14.9752759Z --max-stackframe=<number> assume stack switch for SP changes larger 2021-02-06T18:45:14.9753470Z than <number> bytes [2000000] 2021-02-06T18:45:14.9754197Z --main-stacksize=<number> set size of main thread's stack (in bytes) 2021-02-06T18:45:14.9754916Z [min(max(current 'ulimit' value,1MB),16MB)] 2021-02-06T18:45:14.9755213Z 2021-02-06T18:45:14.9755712Z user options for Valgrind tools that replace malloc: 2021-02-06T18:45:14.9756481Z --alignment=<number> set minimum alignment of heap allocations [16] 2021-02-06T18:45:14.9757305Z --redzone-size=<number> set minimum size of redzones added before/after 2021-02-06T18:45:14.9757835Z heap blocks (in bytes). [16] 2021-02-06T18:45:14.9758527Z --xtree-memory=none|allocs|full profile heap memory in an xtree [none] 2021-02-06T18:45:14.9759131Z and produces a report at the end of the execution 2021-02-06T18:45:14.9759685Z none: no profiling, allocs: current allocated 2021-02-06T18:45:14.9760584Z size/blocks, full: profile current and cumulative 2021-02-06T18:45:14.9761448Z allocated size/blocks and freed size/blocks. 2021-02-06T18:45:14.9762317Z --xtree-memory-file=<file> xtree memory report file [xtmemory.kcg.%p] 2021-02-06T18:45:14.9762786Z 2021-02-06T18:45:14.9763174Z uncommon user options for all Valgrind tools: 2021-02-06T18:45:14.9764401Z --fullpath-after= (with nothing after the '=') 2021-02-06T18:45:14.9764888Z show full source paths in call stacks 2021-02-06T18:45:14.9765614Z --fullpath-after=string like --fullpath-after=, but only show the 2021-02-06T18:45:14.9766358Z part of the path after 'string'. Allows removal 2021-02-06T18:45:14.9766877Z of path prefixes. Use this flag multiple times 2021-02-06T18:45:14.9767399Z to specify a set of prefixes to remove. 2021-02-06T18:45:14.9768166Z --extra-debuginfo-path=path absolute path to search for additional 2021-02-06T18:45:14.9768814Z debug symbols, in addition to existing default 2021-02-06T18:45:14.9769280Z well known search paths. 2021-02-06T18:45:14.9769949Z --debuginfo-server=ipaddr:port also query this server 2021-02-06T18:45:14.9771036Z (valgrind-di-server) for debug symbols 2021-02-06T18:45:14.9772024Z --allow-mismatched-debuginfo=no|yes [no] 2021-02-06T18:45:14.9772788Z for the above two flags only, accept debuginfo 2021-02-06T18:45:14.9773625Z objects that don't "match" the main object 2021-02-06T18:45:14.9774295Z --smc-check=none|stack|all|all-non-file [all-non-file] 2021-02-06T18:45:14.9775009Z checks for self-modifying code: none, only for 2021-02-06T18:45:14.9775536Z code found in stacks, for all code, or for all 2021-02-06T18:45:14.9776192Z code except that from file-backed mappings 2021-02-06T18:45:14.9777049Z --read-inline-info=yes|no read debug info about inlined function calls 2021-02-06T18:45:14.9777627Z and use it to do better stack traces. 2021-02-06T18:45:14.9778105Z [yes] on Linux/Android/Solaris for the tools 2021-02-06T18:45:14.9778582Z Memcheck/Massif/Helgrind/DRD only. 2021-02-06T18:45:14.9779061Z [no] for all other tools and platforms. 2021-02-06T18:45:14.9779798Z --read-var-info=yes|no read debug info on stack and global variables 2021-02-06T18:45:14.9780793Z and use it to print better error messages in 2021-02-06T18:45:14.9781340Z tools that make use of it (Memcheck, Helgrind, 2021-02-06T18:45:14.9781769Z DRD) [no] 2021-02-06T18:45:14.9782503Z --vgdb-poll=<number> gdbserver poll max every <number> basic blocks [5000] 2021-02-06T18:45:14.9783701Z --vgdb-shadow-registers=no|yes let gdb see the shadow registers [no] 2021-02-06T18:45:14.9784544Z --vgdb-prefix=<prefix> prefix for vgdb FIFOs [/tmp/vgdb-pipe] 2021-02-06T18:45:14.9785334Z --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes] 2021-02-06T18:45:14.9786161Z --run-cxx-freeres=no|yes free up libstdc++ memory at exit on Linux 2021-02-06T18:45:14.9786660Z and Solaris? [yes] 2021-02-06T18:45:14.9787326Z --sim-hints=hint1,hint2,... activate unusual sim behaviours [none] 2021-02-06T18:45:14.9787820Z where hint is one of: 2021-02-06T18:45:14.9788466Z lax-ioctls lax-doors fuse-compatible enable-outer 2021-02-06T18:45:14.9789358Z no-inner-prefix no-nptl-pthread-stackcache fallback-llsc none 2021-02-06T18:45:14.9790505Z --fair-sched=no|yes|try schedule threads fairly on multicore systems [no] 2021-02-06T18:45:14.9791295Z --kernel-variant=variant1,variant2,... 2021-02-06T18:45:14.9791990Z handle non-standard kernel variants [none] 2021-02-06T18:45:14.9792466Z where variant is one of: 2021-02-06T18:45:14.9793004Z bproc android-no-hw-tls 2021-02-06T18:45:14.9794052Z android-gpu-sgx5xx android-gpu-adreno3xx none 2021-02-06T18:45:14.9794906Z --merge-recursive-frames=<number> merge frames between identical 2021-02-06T18:45:14.9796670Z program counters in max <number> frames) [0] 2021-02-06T18:45:14.9797718Z --num-transtab-sectors=<number> size of translated code cache [32] 2021-02-06T18:45:14.9798538Z more sectors may increase performance, but use more memory. 2021-02-06T18:45:14.9800566Z --avg-transtab-entry-size=<number> avg size in bytes of a translated 2021-02-06T18:45:14.9801448Z basic block [0, meaning use tool provided default] 2021-02-06T18:45:14.9802455Z --aspace-minaddr=0xPP avoid mapping memory below 0xPP [guessed] 2021-02-06T18:45:14.9803558Z --valgrind-stacksize=<number> size of valgrind (host) thread's stack 2021-02-06T18:45:14.9804262Z (in bytes) [1048576] 2021-02-06T18:45:14.9805061Z --show-emwarns=no|yes show warnings about emulation limits? [no] 2021-02-06T18:45:14.9805922Z --require-text-symbol=:sonamepattern:symbolpattern abort run if the 2021-02-06T18:45:14.9806911Z stated shared object doesn't have the stated 2021-02-06T18:45:14.9807425Z text symbol. Patterns can contain ? and *. 2021-02-06T18:45:14.9808586Z --soname-synonyms=syn1=pattern1,syn2=pattern2,... synonym soname 2021-02-06T18:45:14.9809287Z specify patterns for function wrapping or replacement. 2021-02-06T18:45:14.9810873Z To use a non-libc malloc library that is 2021-02-06T18:45:14.9811763Z in the main exe: --soname-synonyms=somalloc=NONE 2021-02-06T18:45:14.9812600Z in libxyzzy.so: --soname-synonyms=somalloc=libxyzzy.so 2021-02-06T18:45:14.9813801Z --sigill-diagnostics=yes|no warn about illegal instructions? [yes] 2021-02-06T18:45:14.9814945Z --unw-stack-scan-thresh=<number> Enable stack-scan unwind if fewer 2021-02-06T18:45:14.9815589Z than <number> good frames found [0, meaning "disabled"] 2021-02-06T18:45:14.9816320Z NOTE: stack scanning is only available on arm-linux. 2021-02-06T18:45:14.9817079Z --unw-stack-scan-frames=<number> Max number of frames that can be 2021-02-06T18:45:14.9817651Z recovered by stack scanning [5] 2021-02-06T18:45:14.9818311Z --resync-filter=no|yes|verbose [yes on MacOS, no on other OSes] 2021-02-06T18:45:14.9819123Z attempt to avoid expensive address-space-resync operations 2021-02-06T18:45:14.9820181Z --max-threads=<number> maximum number of threads that valgrind can 2021-02-06T18:45:14.9820833Z handle [500] 2021-02-06T18:45:14.9821060Z 2021-02-06T18:45:14.9821384Z user options for Memcheck: 2021-02-06T18:45:14.9822155Z --leak-check=no|summary|full search for memory leaks at exit? [summary] 2021-02-06T18:45:14.9823203Z --leak-resolution=low|med|high differentiation of leak stack traces [high] 2021-02-06T18:45:14.9824191Z --show-leak-kinds=kind1,kind2,.. which leak kinds to show? 2021-02-06T18:45:14.9824737Z [definite,possible] 2021-02-06T18:45:14.9825507Z --errors-for-leak-kinds=kind1,kind2,.. which leak kinds are errors? 2021-02-06T18:45:14.9826115Z [definite,possible] 2021-02-06T18:45:14.9826524Z where kind is one of: 2021-02-06T18:45:14.9826959Z definite indirect possible reachable all none 2021-02-06T18:45:14.9827779Z --leak-check-heuristics=heur1,heur2,... which heuristics to use for 2021-02-06T18:45:14.9828400Z improving leak search false positive [all] 2021-02-06T18:45:14.9828811Z where heur is one of: 2021-02-06T18:45:14.9829337Z stdstring length64 newarray multipleinheritance all none 2021-02-06T18:45:14.9830330Z --show-reachable=yes same as --show-leak-kinds=all 2021-02-06T18:45:14.9831130Z --show-reachable=no --show-possibly-lost=yes 2021-02-06T18:45:14.9832098Z same as --show-leak-kinds=definite,possible 2021-02-06T18:45:14.9832880Z --show-reachable=no --show-possibly-lost=no 2021-02-06T18:45:14.9833899Z same as --show-leak-kinds=definite 2021-02-06T18:45:14.9834596Z --xtree-leak=no|yes output leak result in xtree format? [no] 2021-02-06T18:45:14.9835349Z --xtree-leak-file=<file> xtree leak report file [xtleak.kcg.%p] 2021-02-06T18:45:14.9836160Z --undef-value-errors=no|yes check for undefined value errors [yes] 2021-02-06T18:45:14.9836949Z --track-origins=no|yes show origins of undefined values? [no] 2021-02-06T18:45:14.9837713Z --partial-loads-ok=no|yes too hard to explain here; see manual [yes] 2021-02-06T18:45:14.9838530Z --expensive-definedness-checks=no|auto|yes 2021-02-06T18:45:14.9839318Z Use extra-precise definedness tracking [auto] 2021-02-06T18:45:14.9840270Z --freelist-vol=<number> volume of freed blocks queue [20000000] 2021-02-06T18:45:14.9841278Z --freelist-big-blocks=<number> releases first blocks with size>= [1000000] 2021-02-06T18:45:14.9842223Z --workaround-gcc296-bugs=no|yes self explanatory [no]. Deprecated. 2021-02-06T18:45:14.9843429Z Use --ignore-range-below-sp instead. 2021-02-06T18:45:14.9844212Z --ignore-ranges=0xPP-0xQQ[,0xRR-0xSS] assume given addresses are OK 2021-02-06T18:45:14.9845213Z --ignore-range-below-sp=<number>-<number> do not report errors for 2021-02-06T18:45:14.9845838Z accesses at the given offsets below SP 2021-02-06T18:45:14.9846530Z --malloc-fill=<hexnumber> fill malloc'd areas with given value 2021-02-06T18:45:14.9847398Z --free-fill=<hexnumber> fill free'd areas with given value 2021-02-06T18:45:14.9848778Z --keep-stacktraces=alloc|free|alloc-and-free|alloc-then-free|none 2021-02-06T18:45:14.9850269Z stack trace(s) to keep for malloc'd/free'd areas [alloc-and-free] 2021-02-06T18:45:14.9851237Z --show-mismatched-frees=no|yes show frees that don't match the allocator? [yes] 2021-02-06T18:45:14.9851751Z 2021-02-06T18:45:14.9852386Z Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc 2021-02-06T18:45:14.9852773Z 2021-02-06T18:45:14.9853851Z Memcheck is Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. 2021-02-06T18:45:14.9854583Z Valgrind is Copyright (C) 2000-2017, and GNU GPL'd, by Julian Seward et al. 2021-02-06T18:45:14.9855294Z LibVEX is Copyright (C) 2004-2017, and GNU GPL'd, by OpenWorks LLP et al. 2021-02-06T18:45:14.9855630Z 2021-02-06T18:45:14.9856077Z Bug reports, feedback, admiration, abuse, etc, to: www.valgrind.org. 2021-02-06T18:45:14.9856464Z 2021-02-06T18:45:14.9856881Z valgrind-3.17.0.GIT 2021-02-06T18:45:16.4950178Z Removing intermediate container 7e1361e3e8bf ... 2021-02-06T18:48:55.4996129Z for x in ./horse64/test_uri.bin ./horse64/test_bytecode.bin ./horse64/test_widechar.bin ./horse64/test_stack.bin ./horse64/test_vmexec.bin ./horse64/compiler/test_lexer.bin ./horse64/compiler/test_scope.bin ./horse64/compiler/test_ast.bin; do echo ">>> TEST RUN: $x"; CK_FORK=no valgrind --track-origins=yes --leak-check=full ./$x || { exit 1; }; done 2021-02-06T18:48:55.5011739Z >>> TEST RUN: ./horse64/test_uri.bin 2021-02-06T18:48:55.5149107Z ==9183== Memcheck, a memory error detector 2021-02-06T18:48:55.5150093Z ==9183== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. 2021-02-06T18:48:55.5151037Z ==9183== Using Valgrind-3.17.0.GIT and LibVEX; rerun with -h for copyright info 2021-02-06T18:48:55.5151964Z ==9183== Command: ././horse64/test_uri.bin 2021-02-06T18:48:55.5152300Z ==9183== 2021-02-06T18:48:56.8312665Z Running suite(s): Core 2021-02-06T18:48:56.8942499Z horsevm: error: fatal, failed to unpack integrated unicode data, out of memory? 2021-02-06T18:48:56.9499135Z ==9183== 2021-02-06T18:48:56.9499465Z ==9183== HEAP SUMMARY: 2021-02-06T18:48:56.9499841Z ==9183== in use at exit: 9,359 bytes in 128 blocks 2021-02-06T18:48:56.9500773Z ==9183== total heap usage: 4,124 allocs, 3,996 frees, 236,448 bytes allocated 2021-02-06T18:48:56.9501392Z ==9183== 2021-02-06T18:48:56.9509392Z ==9183== LEAK SUMMARY: 2021-02-06T18:48:56.9509786Z ==9183== definitely lost: 0 bytes in 0 blocks 2021-02-06T18:48:56.9510230Z ==9183== indirectly lost: 0 bytes in 0 blocks 2021-02-06T18:48:56.9510696Z ==9183== possibly lost: 0 bytes in 0 blocks 2021-02-06T18:48:56.9511134Z ==9183== still reachable: 9,359 bytes in 128 blocks 2021-02-06T18:48:56.9511556Z ==9183== suppressed: 0 bytes in 0 blocks 2021-02-06T18:48:56.9512076Z ==9183== Reachable blocks (those to which a pointer was found) are not shown. 2021-02-06T18:48:56.9513844Z ==9183== To see them, rerun with: --leak-check=full --show-leak-kinds=all 2021-02-06T18:48:56.9514462Z ==9183== 2021-02-06T18:48:56.9515048Z ==9183== For lists of detected and suppressed errors, rerun with: -s 2021-02-06T18:48:56.9515643Z ==9183== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) (full log: https://github.com/horse64/core.horse64.org/runs/1845964361 click three dots at the right > raw log) This is the expected output, and what happens without valgrind: $ ./horse64/test_uri.bin Running suite(s): Core 100%: Checks: 1, Failures: 0, Errors: 0 So as far as I can tell, it's not working yet.
It seems to work with your test program for me: $ gcc -g -o selfexe selfexe.c $ ./selfexe Program starting. Waiting for 10 seconds... Opening /proc/self/exe... size: 11040 $ valgrind -q ./selfexe Program starting. Waiting for 10 seconds... Opening /proc/self/exe... size: 2799312 $ ./vg-in-place -q ./selfexe Program starting. Waiting for 10 seconds... Opening /proc/self/exe... size: 11040 Where ./vg-in-place is my patched valgrind.
(In reply to ell1e from comment #3) > Additional note: the usleep() is not necessary to test this, I just wanted > to test what happened to /proc/self/exe when unlinking it while the program > is running. (If you were curious, it still works and points to the deleted > file.) If that part doesn't work inside valgrind anymore that'd be a > somewhat acceptable corner case to me though, as long as it at least works > when the excuted file isn't moved or removed. This part also seems to work as expected: $ ./vg-in-place -q ./selfexe & [1] 13082 $ Program starting. Waiting for 10 seconds... rm selfexe $ Opening /proc/self/exe... size: 11040
(In reply to ell1e from comment #4) > (full log: https://github.com/horse64/core.horse64.org/runs/1845964361 click > three dots at the right > raw log) > > This is the expected output, and what happens without valgrind: > > $ ./horse64/test_uri.bin > Running suite(s): Core > 100%: Checks: 1, Failures: 0, Errors: 0 > > So as far as I can tell, it's not working yet. Sorry, I don't really understand what is going on there. And it seems you need some kind of account on github to even see that full log.
Fascinating, even the small example isn't working for me: Step 13/18 : RUN cd /tmp/ && stat ./blatest && valgrind ./blatest ---> Running in 95b307aac0e2 File: ./blatest Size: 8520 Blocks: 24 IO Block: 4096 regular file Device: 44h/68d Inode: 1799948 Links: 1 Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2021-02-06 20:55:20.000000000 +0000 Modify: 2021-02-06 20:55:20.000000000 +0000 Change: 2021-02-06 20:55:20.407532446 +0000 Birth: - ==7== Memcheck, a memory error detector ==7== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==7== Using Valgrind-3.17.0.GIT and LibVEX; rerun with -h for copyright info ==7== Command: ./blatest ==7== Program starting. Waiting for 10 seconds... Opening /proc/self/exe... size: 14572336 ==7== ==7== HEAP SUMMARY: ==7== in use at exit: 552 bytes in 1 blocks ==7== total heap usage: 3 allocs, 2 frees, 8,744 bytes allocated ==7== ==7== LEAK SUMMARY: ==7== definitely lost: 0 bytes in 0 blocks ==7== indirectly lost: 0 bytes in 0 blocks ==7== possibly lost: 0 bytes in 0 blocks ==7== still reachable: 552 bytes in 1 blocks ==7== suppressed: 0 bytes in 0 blocks ==7== Rerun with --leak-check=full to see details of leaked memory ==7== ==7== For lists of detected and suppressed errors, rerun with: -s ==7== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) So I guess I'm just compiling the patched valgrind wrong. > And it seems you need some kind of account on github to even see that full log. Ouch, that is horrible, my apologies I wasn't aware of that limitation. In any case, if the example works for you with the patch I guess it might be worth committing, and I'll try again with the latest git. Maybe I just applied the patch wrong, it has happened before...
(In reply to ell1e from comment #8) > In any case, if the example works for you with the patch I guess it might be > worth committing, and I'll try again with the latest git. Maybe I just > applied the patch wrong, it has happened before... Turns out this was already reported upstream (in 2007!): https://bugs.kde.org/show_bug.cgi?id=140178 Attached my patch there. I did a new valgrind package build with the patch for rawhide: https://bodhi.fedoraproject.org/updates/FEDORA-2021-9c25f75e01 Maybe you can use that for testing?
Hmm it looks like my GLIBC is too old: > $ sudo dnf install valgrind-3.16.1-17.fc34.x86_64.rpm > [sudo] password for ellie: > Last metadata expiration check: 0:46:00 ago on Sat 06 Feb 2021 10:11:57 PM CET. > Error: > Problem: conflicting requests > - nothing provides libc.so.6(GLIBC_2.33)(64bit) needed by valgrind-1:3.16.1-17.fc34.x86_64 > (try to add '--skip-broken' to skip uninstallable packages) (I'm sadly still stuck on 33 and don't know when I'll be able to upgrade due to https://bugzilla.redhat.com/show_bug.cgi?id=1899805 ) I also tested it again inside docker, and even tried 1. applying the patch twice which led to the expected error, 2. verified valgrind wasn't available as a command before inside the docker container (-> I'm not running a different version unintentionally), 3. reran the minimal test with this but it still doesn't work for me. I'm really not sure what I'm doing wrong. These are the docker file steps: RUN valgrind --help || { echo "no valgrind"; } RUN mkdir -p /tmp/valgrind && cd /tmp/valgrind && git clone git://sourceware.org/git/valgrind.git . ADD ./tools/valgrind_patch /tmp/valgrind/valgrind.patch RUN cd /tmp/valgrind && patch -p1 < ./valgrind.patch RUN cd /tmp/valgrind && ./autogen.sh && ./configure RUN cd /tmp/valgrind && patch -p1 < ./valgrind.patch || { echo "fail"; } RUN cd /tmp/valgrind && make && make install RUN valgrind --help; valgrind --version ADD ./tools/blatest.c /tmp/blatest.c RUN cd /tmp/ && gcc -o ./blatest ./blatest.c RUN cd /tmp/ && stat ./blatest && valgrind ./blatest It gives the "no valgrind" and the "fail" on second patch output as expected, sadly blatest (which is the minimal test code from above) still gives the wrong size for me. The environment I'm testing this in is an Ubuntu 18.04 image, if that should be relevant. Anyway, if you're certain enough this fixes it then just go ahead. I never built valgrind before so who knows what step I might have possibly forgotten that impacts this. Thanks in any case for your very quick response and patch!
(In reply to ell1e from comment #10) > Hmm it looks like my GLIBC is too old: > > > $ sudo dnf install valgrind-3.16.1-17.fc34.x86_64.rpm > > [sudo] password for ellie: > > Last metadata expiration check: 0:46:00 ago on Sat 06 Feb 2021 10:11:57 PM CET. > > Error: > > Problem: conflicting requests > > - nothing provides libc.so.6(GLIBC_2.33)(64bit) needed by valgrind-1:3.16.1-17.fc34.x86_64 > > (try to add '--skip-broken' to skip uninstallable packages) > > (I'm sadly still stuck on 33 and don't know when I'll be able to upgrade due > to https://bugzilla.redhat.com/show_bug.cgi?id=1899805 ) Fedora 33 scratch build: https://koji.fedoraproject.org/koji/taskinfo?taskID=61484971
Fascinating, I tried the scratch build and it really doesn't like me: $ sudo dnf install ./valgrind-3.16.1-17.fc33.x86_64.rpm --allowerasing Last metadata expiration check: 2:40:00 ago on Sat 06 Feb 2021 10:11:57 PM CET. Dependencies resolved. ===================================================================================================================================== Package Architecture Version Repository Size ===================================================================================================================================== Upgrading: valgrind x86_64 1:3.16.1-17.fc33 @commandline 4.8 M Removing dependent packages: valgrind-devel x86_64 1:3.16.1-11.fc33 @updates 493 k Transaction Summary ===================================================================================================================================== Upgrade 1 Package Remove 1 Package Total size: 4.8 M Is this ok [y/N]: y Downloading Packages: Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Upgrading : valgrind-1:3.16.1-17.fc33.x86_64 1/3 Erasing : valgrind-devel-1:3.16.1-11.fc33.x86_64 2/3 Cleanup : valgrind-1:3.16.1-11.fc33.x86_64 3/3 Running scriptlet: valgrind-1:3.16.1-11.fc33.x86_64 3/3 Verifying : valgrind-1:3.16.1-17.fc33.x86_64 1/3 Verifying : valgrind-1:3.16.1-11.fc33.x86_64 2/3 Verifying : valgrind-devel-1:3.16.1-11.fc33.x86_64 3/3 Upgraded: valgrind-1:3.16.1-17.fc33.x86_64 Removed: valgrind-devel-1:3.16.1-11.fc33.x86_64 Complete! $ cd blatest $ cat blatest.c #include <inttypes.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, const char **argv) { printf("Program starting.\n"); printf("Waiting for 10 seconds...\n"); usleep(10 * 1000000); printf("Opening /proc/self/exe...\n"); FILE *f = fopen("/proc/self/exe", "rb"); if (!f) { printf("Opening failed.\n"); return 1; } if (fseek(f, 0, SEEK_END) != 0) { printf("Seek failed.\n"); return 1; } int64_t result = ftell(f); if (result < 0) { printf("ftell() failed.\n"); return 1; } printf("size: %" PRId64 "\n", (int64_t)result); return 0; } $ gcc -o ./blatest ./blatest.c $ valgrind ./blatest ==844479== Memcheck, a memory error detector ==844479== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==844479== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info ==844479== Command: ./blatest ==844479== Program starting. Waiting for 10 seconds... Opening /proc/self/exe... size: 2659128 ==844479== ==844479== HEAP SUMMARY: ==844479== in use at exit: 472 bytes in 1 blocks ==844479== total heap usage: 3 allocs, 2 frees, 5,592 bytes allocated ==844479== ==844479== LEAK SUMMARY: ==844479== definitely lost: 0 bytes in 0 blocks ==844479== indirectly lost: 0 bytes in 0 blocks ==844479== possibly lost: 0 bytes in 0 blocks ==844479== still reachable: 472 bytes in 1 blocks ==844479== suppressed: 0 bytes in 0 blocks ==844479== Rerun with --leak-check=full to see details of leaked memory ==844479== ==844479== For lists of detected and suppressed errors, rerun with: -s ==844479== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) $ stat blatest File: blatest Size: 25376 Blocks: 56 IO Block: 4096 regular file Device: fd02h/64770d Inode: 13775431 Links: 1 Access: (0775/-rwxrwxr-x) Uid: ( 1000/ ellie) Gid: ( 1001/ ellie) Context: unconfined_u:object_r:container_file_t:s0:c42,c208 Access: 2021-02-07 00:53:22.488929294 +0100 Modify: 2021-02-07 00:53:19.665949562 +0100 Change: 2021-02-07 00:53:19.665949562 +0100 Birth: 2021-02-07 00:53:19.651949663 +0100 $ stat /usr/libexec/valgrind/memcheck-amd64-linux File: /usr/libexec/valgrind/memcheck-amd64-linux Size: 2659128 Blocks: 5200 IO Block: 4096 regular file Device: fd01h/64769d Inode: 799321 Links: 1 Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) Context: system_u:object_r:bin_t:s0 Access: 2021-02-07 00:52:08.856454962 +0100 Modify: 2021-02-06 23:13:09.000000000 +0100 Change: 2021-02-07 00:52:02.974496321 +0100 Birth: 2021-02-07 00:52:02.961496413 +0100
(In reply to ell1e from comment #12) > Fascinating, I tried the scratch build and it really doesn't like me: You aren't the only one. Just tried the f33 package myself and it also doesn't work as intended for me. Investigating...
Got it. "modern" glibc/kernels translate the open call to openat (AT_FDCWD, ...). So we also need to do the same trick for openat. I was using a terribly old setup for my replication. But at least we know both the open and openat path work now.
OK, now it should be properly fixed. New f33 scratch build for testing: https://koji.fedoraproject.org/koji/taskinfo?taskID=61495205
Can confirm valgrind-3.16.1-18/the f33 scratch build work for me. Really cool. I'm amazed by how fast this was fixed!
Great, thanks for the testing. I'll try to do a proper f33 build soon to pull in this and some other fixes from rawhide.
FEDORA-2021-df23f1f7db has been submitted as an update to Fedora 33. https://bodhi.fedoraproject.org/updates/FEDORA-2021-df23f1f7db
FEDORA-2021-aae6525270 has been submitted as an update to Fedora 32. https://bodhi.fedoraproject.org/updates/FEDORA-2021-aae6525270
FEDORA-2021-df23f1f7db has been pushed to the Fedora 33 testing repository. Soon you'll be able to install the update with the following command: `sudo dnf upgrade --enablerepo=updates-testing --advisory=FEDORA-2021-df23f1f7db` You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2021-df23f1f7db See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.
FEDORA-2021-aae6525270 has been pushed to the Fedora 32 testing repository. Soon you'll be able to install the update with the following command: `sudo dnf upgrade --enablerepo=updates-testing --advisory=FEDORA-2021-aae6525270` You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2021-aae6525270 See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.
FEDORA-2021-df23f1f7db has been pushed to the Fedora 33 stable repository. If problem still persists, please make note of it in this bug report.
FEDORA-2021-aae6525270 has been pushed to the Fedora 32 stable repository. If problem still persists, please make note of it in this bug report.