Shopify / ruby_memcheck

Use Valgrind memcheck on your native gem without going crazy
MIT License
236 stars 12 forks source link

rake test fails with "Don't know how to build task 'test/ruby_memcheck/ext/extconf.rb'" #11

Closed Apteryks closed 1 year ago

Apteryks commented 1 year ago

Hi,

I'm hoping that's a simple thing I've overlooked; trying to package this gem for Guix, I run into:

starting phase `check'
mkdir -p test/ruby_memcheck/ext
mkdir -p tmp/x86_64-linux/ruby_memcheck_c_test/2.7.4
rake aborted!
Don't know how to build task 'test/ruby_memcheck/ext/extconf.rb' (See the list of available tasks with `rake --tasks`)
Did you mean?  test/ruby_memcheck/ext

Tasks: TOP => test => test:compile => test:compile:x86_64-linux => test:compile:ruby_memcheck_c_test:x86_64-linux => test:copy:ruby_memcheck_c_test:x86_64-linux:2.7.4 => tmp/x86_64-linux/ruby_memcheck_c_test/2.7.4/ruby_memcheck_c_test.so => tmp/x86_64-linux/ruby_memcheck_c_test/2.7.4/Makefile
(See full trace by running task with --trace)
error: in phase 'check': uncaught exception:
%exception #<&invoke-error program: "rake" arguments: ("test") exit-status: 1 term-signal: #f stop-signal: #f> 
phase `check' failed after 0.1 seconds
command "rake" "test" failed with status 1

What am I missing? :-)

Thanks!

peterzhu2118 commented 1 year ago

Hello!

Can you provide your Rakefile and the change diff?

Apteryks commented 1 year ago

Hi! What do you mean by change diff? I haven't edited the Rakefile. I believe the above problem was due to the gem release not containing all the needed files to run the test suite. When I use a git checkout instead, it proceeds further. I have errors to investigate that look like:

valgrind:  Fatal error at startup: a function redirection
valgrind:  which is mandatory for this platform-tool combination
valgrind:  cannot be set up.  Details of the redirection are:
valgrind:  
valgrind:  A must-be-redirected function
valgrind:  whose name matches the pattern:      strlen
valgrind:  in an object with soname matching:   ld-linux-x86-64.so.2
valgrind:  was not found whilst processing
valgrind:  symbols from the object with soname: ld-linux-x86-64.so.2
valgrind:  
valgrind:  Possible fixes: (1, short term): install glibc's debuginfo
valgrind:  package on this machine.  (2, longer term): ask the packagers
valgrind:  for your Linux distribution to please in future ship a non-
valgrind:  stripped ld.so (or whatever the dynamic linker .so is called)
valgrind:  that exports the above-named function using the standard
valgrind:  calling conventions for this platform.  The package you need
valgrind:  to install for fix (1) is called
valgrind:  
valgrind:    On Debian, Ubuntu:                 libc6-dbg
valgrind:    On SuSE, openSuSE, Fedora, RHEL:   glibc-debuginfo
valgrind:  
valgrind:  Note that if you are debugging a 32 bit process on a
valgrind:  64 bit system, you will need a corresponding 32 bit debuginfo
valgrind:  package (e.g. libc6-dbg:i386).
valgrind:  
valgrind:  Cannot continue -- exiting now.  Sorry.
peterzhu2118 commented 1 year ago

Ah sorry, I misunderstood your question. I thought you're experiencing an issue with a gem that's using this tool.

The gem files on rubygems.org do not contain test files and only contain code (to save space). So to be able to run tests, you have to use a git clone of this project.

It looks like valgrind is failing due to lacking debug symbols for system libraries. Have you tried installing the debuginfo package for your system?

Apteryks commented 1 year ago

There's a glibc:debug package found in Guix, but that's usually made useful/discoverable to GDB by some .gdbinit file that sets the correct debug-directory-file gdb variable. I'm not sure how valgrind copes with this (if at all) in Guix, I'll have to investigate. Thank you!

Apteryks commented 1 year ago

It seems valgrind mecheck alone works normally:

$ valgrind --tool=memcheck ./hello
==22215== Memcheck, a memory error detector
==22215== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==22215== Using Valgrind-3.20.0 and LibVEX; rerun with -h for copyright info
==22215== Command: ./hello
==22215== 
Hello, world!
==22215== 
==22215== HEAP SUMMARY:
==22215==     in use at exit: 0 bytes in 0 blocks
==22215==   total heap usage: 2,994 allocs, 2,994 frees, 205,672 bytes allocated
==22215== 
==22215== All heap blocks were freed -- no leaks are possible
==22215== 
==22215== For lists of detected and suppressed errors, rerun with: -s
==22215== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
peterzhu2118 commented 1 year ago

It looks like it's failing on strlen. Can you try running valgrind on a small program that uses strlen?

Apteryks commented 1 year ago

It seems the test program I've run it on (GNU hello) already uses strlen:

int
main (int argc, char *argv[])
{
  const char *greeting_msg;
  wchar_t *mb_greeting;
  mbstate_t mbstate = { 0, };
  size_t len;

  set_program_name (argv[0]);

  /* Set locale via LC_ALL.  */
  setlocale (LC_ALL, "");

#if ENABLE_NLS
  /* Set the text message domain.  */
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);
#endif

  /* Having initialized gettext, get the default message. */
  greeting_msg = _("Hello, world!");

  /* Even exiting has subtleties.  On exit, if any writes failed, change
     the exit status.  The /dev/full device on GNU/Linux can be used for
     testing; for instance, hello >/dev/full should exit unsuccessfully.
     This is implemented in the Gnulib module "closeout".  */
  atexit (close_stdout);

  parse_options(argc, argv, &greeting_msg);

  len = strlen(greeting_msg) + 1;
  mb_greeting = xmalloc(len * sizeof(wchar_t));
  len = mbsrtowcs(mb_greeting, &greeting_msg, len, &mbstate);
  if (len == (size_t)-1)
    error (EXIT_FAILURE, errno, _("conversion to a multibyte string failed"));

  /* Print greeting message and exit. */
  wprintf (L"%ls\n", mb_greeting);
  free(mb_greeting);

  exit (EXIT_SUCCESS);
}
Apteryks commented 1 year ago

Are there file-hierarchy standard (FHS) assumptions made in ruby_memcheck ? Things looking at hard-coded places like /usr/lib or the likes? I couldn't see any, but perhaps I'm missing something.

This is the strace of rake test showing the valgrind exec right before the error above is printed:

[pid 25669] execve("/gnu/store/xqd56icpl66vfq8p792dnxciqs2mj28q-valgrind-3.17.0/libexec/valgrind/memcheck-amd64-linux", ["valgrind", "--num-callers=50", "--error-limit=no", "--trace-children=yes", "--undef-value-errors=no", "--leak-check=full", "--show-leak-kinds=definite", "--xml=yes", "--xml-file=/tmp/d20230314-25622-l5woox/%p.out", "--suppressions=/tmp/ruby_memcheck/suppressions/ruby.supp", "--suppressions=/tmp/ruby_memcheck/suppressions/ruby.supp", "/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", "-r/tmp/ruby_memcheck/lib/ruby_memcheck/test_helper.rb", "-I/tmp/ruby_memcheck/test/ruby_memcheck/ext", "/tmp/20230314-25622-1nf574p"], 0x5b4560 /* 114 vars */) = 0
[pid 25669] open("/proc/self/maps", O_RDONLY) = 3
[pid 25669] getcwd("/tmp/ruby_memcheck", 499) = 19
[pid 25669] open("/home/maxim/.valgrindrc", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 25669] open("./.valgrindrc", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 25669] open("/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", O_RDONLY) = 3
[pid 25669] statx(AT_FDCWD, "/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=14440, ...}) = 0
[pid 25669] getxattr("/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", "security.capability", NULL, 0) = -1 ENODATA (No data available)
[pid 25669] statx(3, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=14440, ...}) = 0
[pid 25669] open("/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-linux-x86-64.so.2", O_RDONLY) = 4
[pid 25669] statx(3, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=14440, ...}) = 0
[pid 25669] readlink("/proc/self/fd/3", "/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", 4096) = 63
[pid 25669] statx(3, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=14440, ...}) = 0
[pid 25669] readlink("/proc/self/fd/3", "/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", 4096) = 63
[pid 25669] statx(3, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=14440, ...}) = 0
[pid 25669] readlink("/proc/self/fd/3", "/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", 4096) = 63
[pid 25669] statx(3, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=14440, ...}) = 0
[pid 25669] readlink("/proc/self/fd/3", "/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", 4096) = 63
[pid 25669] statx(4, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=194432, ...}) = 0
[pid 25669] readlink("/proc/self/fd/4", "/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so", 4096) = 69
[pid 25669] statx(4, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=194432, ...}) = 0
[pid 25669] readlink("/proc/self/fd/4", "/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so", 4096) = 69
[pid 25669] statx(4, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=194432, ...}) = 0
[pid 25669] readlink("/proc/self/fd/4", "/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so", 4096) = 69
[pid 25669] statx(4, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=194432, ...}) = 0
[pid 25669] readlink("/proc/self/fd/4", "/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so", 4096) = 69
[pid 25669] open("/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", O_RDONLY) = 3
[pid 25669] access("/gnu/store/xqd56icpl66vfq8p792dnxciqs2mj28q-valgrind-3.17.0/libexec/valgrind/vgpreload_memcheck-amd64-linux.so", R_OK) = 0
[pid 25669] open("/tmp/valgrind_proc_25669_cmdline_491c4397", O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0600) = 3
[pid 25669] unlink("/tmp/valgrind_proc_25669_cmdline_491c4397") = 0
[pid 25669] open("/tmp/valgrind_proc_25669_auxv_491c4397", O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0600) = 3
[pid 25669] unlink("/tmp/valgrind_proc_25669_auxv_491c4397") = 0
[pid 25669] open("/tmp/d20230314-25622-l5woox/25669.out", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3
[pid 25669] statx(AT_FDCWD, "/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=14440, ...}) = 0
[pid 25669] open("/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", O_RDONLY|O_LARGEFILE) = 4
[pid 25669] statx(AT_FDCWD, "/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=14440, ...}) = 0
[pid 25669] open("/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", O_RDONLY|O_LARGEFILE) = 4
[pid 25669] statx(AT_FDCWD, "/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=14440, ...}) = 0
[pid 25669] open("/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", O_RDONLY|O_LARGEFILE) = 4
[pid 25669] statx(AT_FDCWD, "/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=14440, ...}) = 0
[pid 25669] open("/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", O_RDONLY|O_LARGEFILE) = 4
[pid 25669] open("/gnu/store/shlnv21bwbj54b1hipgn7qsd7sjkl16z-ruby-2.7.7/bin/ruby", O_RDONLY) = 4
[pid 25669] statx(4, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=14440, ...}) = 0
[pid 25669] statx(AT_FDCWD, "/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=194432, ...}) = 0
[pid 25669] open("/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so", O_RDONLY|O_LARGEFILE) = 4
[pid 25669] statx(AT_FDCWD, "/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=194432, ...}) = 0
[pid 25669] open("/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so", O_RDONLY|O_LARGEFILE) = 4
[pid 25669] statx(AT_FDCWD, "/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=194432, ...}) = 0
[pid 25669] open("/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so", O_RDONLY|O_LARGEFILE) = 4
[pid 25669] statx(AT_FDCWD, "/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=194432, ...}) = 0
[pid 25669] open("/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so", O_RDONLY|O_LARGEFILE) = 4
[pid 25669] open("/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so", O_RDONLY) = 4
[pid 25669] statx(4, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0555, stx_size=194432, ...}) = 0
[pid 25669] open("/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so.debug", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 25669] open("/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/.debug/ld-2.33.so.debug", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 25669] open("/usr/lib/debug/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib/ld-2.33.so.debug", O_RDONLY) = -1 ENOENT (No such file or directory)
peterzhu2118 commented 1 year ago

I tried compiling the following code with -O3 using GCC:

#include <stdio.h>
#include <wchar.h>
#include <locale.h>
#include <string.h>
#include <stdlib.h>

int
main (int argc, char *argv[])
{
  const char *greeting_msg;
  wchar_t *mb_greeting;
  mbstate_t mbstate = { 0, };
  size_t len;

  /* Set locale via LC_ALL.  */
  setlocale (LC_ALL, "");

#if ENABLE_NLS
  /* Set the text message domain.  */
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);
#endif

  /* Having initialized gettext, get the default message. */
  greeting_msg = "Hello, world!";

  len = strlen(greeting_msg) + 1;
  mb_greeting = malloc(len * sizeof(wchar_t));
  len = mbsrtowcs(mb_greeting, &greeting_msg, len, &mbstate);

  /* Print greeting message and exit. */
  wprintf (L"%ls\n", mb_greeting);
  free(mb_greeting);

  exit (EXIT_SUCCESS);
}

And disassembling the generated binary, the strlen call is completely optimized out:

0000000000001100 <main>:
    1100:   f3 0f 1e fa             endbr64
    1104:   55                      push   %rbp
    1105:   48 8d 35 05 0f 00 00    lea    0xf05(%rip),%rsi        # 2011 <_IO_stdin_used+0x11>
    110c:   bf 06 00 00 00          mov    $0x6,%edi
    1111:   48 83 ec 20             sub    $0x20,%rsp
    1115:   64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
    111c:   00 00
    111e:   48 89 44 24 18          mov    %rax,0x18(%rsp)
    1123:   31 c0                   xor    %eax,%eax
    1125:   48 c7 44 24 10 00 00    movq   $0x0,0x10(%rsp)
    112c:   00 00
    112e:   e8 9d ff ff ff          call   10d0 <setlocale@plt>
    1133:   48 8d 05 ca 0e 00 00    lea    0xeca(%rip),%rax        # 2004 <_IO_stdin_used+0x4>
    113a:   bf 38 00 00 00          mov    $0x38,%edi
    113f:   48 89 44 24 08          mov    %rax,0x8(%rsp)
    1144:   e8 77 ff ff ff          call   10c0 <malloc@plt>
    1149:   48 8d 4c 24 10          lea    0x10(%rsp),%rcx
    114e:   48 8d 74 24 08          lea    0x8(%rsp),%rsi
    1153:   ba 0e 00 00 00          mov    $0xe,%edx
    1158:   48 89 c5                mov    %rax,%rbp
    115b:   48 89 c7                mov    %rax,%rdi
    115e:   e8 4d ff ff ff          call   10b0 <mbsrtowcs@plt>
    1163:   48 89 ea                mov    %rbp,%rdx
    1166:   bf 01 00 00 00          mov    $0x1,%edi
    116b:   31 c0                   xor    %eax,%eax
    116d:   48 8d 35 a0 0e 00 00    lea    0xea0(%rip),%rsi        # 2014 <_IO_stdin_used+0x14>
    1174:   e8 67 ff ff ff          call   10e0 <__wprintf_chk@plt>
    1179:   48 89 ef                mov    %rbp,%rdi
    117c:   e8 1f ff ff ff          call   10a0 <free@plt>
    1181:   31 ff                   xor    %edi,%edi
    1183:   e8 68 ff ff ff          call   10f0 <exit@plt>
    1188:   0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
    118f:   00

Can you try this program instead?

#include <stdio.h>
#include <string.h>

int
main (int argc, char *argv[])
{
  printf("Your binary name is %ld long\n", strlen(argv[0]));
  return 0;
}

You can see that the strlen is not optimized out:

0000000000001080 <main>:
    1080:   f3 0f 1e fa             endbr64
    1084:   48 83 ec 08             sub    $0x8,%rsp
    1088:   48 8b 3e                mov    (%rsi),%rdi
    108b:   e8 d0 ff ff ff          call   1060 <strlen@plt>
    1090:   48 8d 35 6d 0f 00 00    lea    0xf6d(%rip),%rsi        # 2004 <_IO_stdin_used+0x4>
    1097:   bf 01 00 00 00          mov    $0x1,%edi
    109c:   48 89 c2                mov    %rax,%rdx
    109f:   31 c0                   xor    %eax,%eax
    10a1:   e8 ca ff ff ff          call   1070 <__printf_chk@plt>
    10a6:   31 c0                   xor    %eax,%eax
    10a8:   48 83 c4 08             add    $0x8,%rsp
    10ac:   c3                      ret
    10ad:   0f 1f 00                nopl   (%rax)
peterzhu2118 commented 1 year ago

Are there file-hierarchy standard (FHS) assumptions made in ruby_memcheck ?

ruby_memcheck does not change anything like that. It adds some additional configuration to valgrind, but it shouldn't affect anything here.

Apteryks commented 1 year ago

Hi!

Thanks for the help! It ended up there are two valgrind packages definitions in Guix, and the package definition was using valgrind while in my live testing I was using valgrind/interactive. Using the valgrind one, I could reproduce the problem:

$ valgrind ./hello
==26189== Memcheck, a memory error detector
==26189== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==26189== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==26189== Command: ./hello
==26189== 

valgrind:  Fatal error at startup: a function redirection
valgrind:  which is mandatory for this platform-tool combination
valgrind:  cannot be set up.  Details of the redirection are:
valgrind:  
valgrind:  A must-be-redirected function
valgrind:  whose name matches the pattern:      strlen
valgrind:  in an object with soname matching:   ld-linux-x86-64.so.2
valgrind:  was not found whilst processing
valgrind:  symbols from the object with soname: ld-linux-x86-64.so.2
valgrind:  
valgrind:  Possible fixes: (1, short term): install glibc's debuginfo
valgrind:  package on this machine.  (2, longer term): ask the packagers
valgrind:  for your Linux distribution to please in future ship a non-
valgrind:  stripped ld.so (or whatever the dynamic linker .so is called)
valgrind:  that exports the above-named function using the standard
valgrind:  calling conventions for this platform.  The package you need
valgrind:  to install for fix (1) is called
valgrind:  
valgrind:    On Debian, Ubuntu:                 libc6-dbg
valgrind:    On SuSE, openSuSE, Fedora, RHEL:   glibc-debuginfo
valgrind:  
valgrind:  Note that if you are debugging a 32 bit process on a
valgrind:  64 bit system, you will need a corresponding 32 bit debuginfo
valgrind:  package (e.g. libc6-dbg:i386).
valgrind:  
valgrind:  Cannot continue -- exiting now.  Sorry.

(hello was built with CFLAGS=-O0 -g3)

So, the fix is using that valgrind/interactive package variant instead in the package definition of ruby-ruby-memcheck... (I wonder in which situation the non-interactive one is useful!). Sorry for taking your time, and hi from Montreal!