Bug 441936 - Valgrind crashes with "Assertion 'iFuncWrapper' failed."
Summary: Valgrind crashes with "Assertion 'iFuncWrapper' failed."
Status: RESOLVED NOT A BUG
Alias: None
Product: valgrind
Classification: Developer tools
Component: memcheck (show other bugs)
Version: unspecified
Platform: Other Linux
: NOR crash
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-09-03 06:56 UTC by wissen.kompakt
Modified: 2021-10-14 10:51 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description wissen.kompakt 2021-09-03 06:56:59 UTC
SUMMARY

I'm using valgrind 3.17.0. I compiled and ran successfully the following program called "recording.c":

#include <alsa/asoundlib.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

struct WaveHeader {
  char RIFF_marker[4];
  uint32_t file_size;
  char filetype_header[4];
  char format_marker[4];
  uint32_t data_header_length;
  uint16_t format_type;
  uint16_t number_of_channels;
  uint32_t sample_rate;
  uint32_t bytes_per_second;
  uint16_t bytes_per_frame;
  uint16_t bits_per_sample;
};

struct WaveHeader *genericWAVHeader(uint32_t sample_rate, uint16_t bit_depth,
                                    uint16_t channels) {
  struct WaveHeader *hdr;
  hdr = malloc(sizeof(*hdr));
  if (!hdr) return NULL;

  memcpy(&hdr->RIFF_marker, "RIFF", 4);
  memcpy(&hdr->filetype_header, "WAVE", 4);
  memcpy(&hdr->format_marker, "fmt ", 4);
  hdr->data_header_length = 16;
  hdr->format_type = 1;
  hdr->number_of_channels = channels;
  hdr->sample_rate = sample_rate;
  hdr->bytes_per_second = sample_rate * channels * bit_depth / 8;
  hdr->bytes_per_frame = channels * bit_depth / 8;
  hdr->bits_per_sample = bit_depth;

  return hdr;
}

int writeWAVHeader(FILE *out, struct WaveHeader *hdr) {
  if (!hdr) return -1;

  fwrite(&hdr->RIFF_marker, 1, 4, out);
  fwrite(&hdr->file_size, 1, 4, out);
  fwrite(&hdr->filetype_header, 1, 4, out);
  fwrite(&hdr->format_marker, 1, 4, out);
  fwrite(&hdr->data_header_length, 1, 4, out);
  fwrite(&hdr->format_type, 1, 2, out);
  fwrite(&hdr->number_of_channels, 1, 2, out);
  fwrite(&hdr->sample_rate, 1, 4, out);
  fwrite(&hdr->bytes_per_second, 1, 4, out);
  fwrite(&hdr->bytes_per_frame, 1, 2, out);
  fwrite(&hdr->bits_per_sample, 1, 2, out);
  fwrite("data", 1, 4, out);

  // write(fd, &hdr->RIFF_marker, 4);
  // write(fd, &hdr->file_size, 4);
  // write(fd, &hdr->filetype_header, 4);
  // write(fd, &hdr->format_marker, 4);
  // write(fd, &hdr->data_header_length, 4);
  // write(fd, &hdr->format_type, 2);
  // write(fd, &hdr->number_of_channels, 2);
  // write(fd, &hdr->sample_rate, 4);
  // write(fd, &hdr->bytes_per_second, 4);
  // write(fd, &hdr->bytes_per_frame, 2);
  // write(fd, &hdr->bits_per_sample, 2);
  // write(fd, "data", 4);

  uint32_t data_size = hdr->file_size + 8 - 44;
  fwrite(&data_size, 1, 4, out);
  // write(fd, &data_size, 4);

  return 0;
}

int main() {
  int i;
  int err;
  char *buffer;
  int buffer_frames = 160;
  unsigned int rate = 16000;
  unsigned int channels = 5;
  uint32_t duration = 5000;
  char hardware[] = "hw:2,0";
  snd_pcm_uframes_t frames = 32;
  snd_pcm_t *capture_handle;
  snd_pcm_hw_params_t *hw_params;
  snd_pcm_format_t format = SND_PCM_FORMAT_S32_LE;

  if ((err = snd_pcm_open(&capture_handle, hardware, SND_PCM_STREAM_CAPTURE,
                          0)) < 0) {
    fprintf(stderr, "cannot open audio device %s (%s)\n", hardware,
            snd_strerror(err));
    exit(1);
  }

  fprintf(stdout, "audio interface opened\n");

  if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
    fprintf(stderr, "cannot allocate hardware parameter structure (%s)\n",
            snd_strerror(err));
    exit(1);
  }

  fprintf(stdout, "hw_params allocated\n");

  if ((err = snd_pcm_hw_params_any(capture_handle, hw_params)) < 0) {
    fprintf(stderr, "cannot initialize hardware parameter structure (%s)\n",
            snd_strerror(err));
    exit(1);
  }

  fprintf(stdout, "hw_params initialized\n");

  if ((err = snd_pcm_hw_params_set_access(capture_handle, hw_params,
                                          SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
    fprintf(stderr, "cannot set access type (%s)\n", snd_strerror(err));
    exit(1);
  }

  fprintf(stdout, "hw_params access setted\n");

  if ((err = snd_pcm_hw_params_set_format(capture_handle, hw_params, format)) <
      0) {
    fprintf(stderr, "cannot set sample format (%s)\n", snd_strerror(err));
    exit(1);
  }

  fprintf(stdout, "hw_params format setted\n");

  if ((err = snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &rate,
                                             0)) < 0) {
    fprintf(stderr, "cannot set sample rate (%s)\n", snd_strerror(err));
    exit(1);
  }

  fprintf(stdout, "hw_params rate setted\n");

  if ((err = snd_pcm_hw_params_set_channels(capture_handle, hw_params, channels)) <
      0) {
    fprintf(stderr, "cannot set channel count (%s)\n", snd_strerror(err));
    exit(1);
  }

  fprintf(stdout, "hw_params channels setted\n");

  if ((err = snd_pcm_hw_params(capture_handle, hw_params)) < 0) {
    fprintf(stderr, "cannot set parameters (%s)\n", snd_strerror(err));
    exit(1);
  }

  fprintf(stdout, "hw_params setted\n");

  snd_pcm_hw_params_free(hw_params);

  fprintf(stdout, "hw_params freed\n");

  if ((err = snd_pcm_prepare(capture_handle)) < 0) {
    fprintf(stderr, "cannot prepare audio interface for use (%s)\n",
            snd_strerror(err));
    exit(1);
  }

  fprintf(stdout, "audio interface prepared\n");

  buffer = (char *)malloc(160 * snd_pcm_format_width(format) / 8 * 5);

  fprintf(stdout, "buffer allocated\n");

  struct WaveHeader *hdr;
  int size = frames * hdr->bits_per_sample / 8 * hdr->number_of_channels;

  FILE *out;
  out = fopen("zwave.wav", "wb");

  // write empty header
  for (int i = 0; i < 44; i++) {
    fputc(0x00, out);
  }

  fprintf(stdout, "Recording...\n");
  for (int i = duration * 1000 / rate; i > 0; i--) {
    if ((err = snd_pcm_readi(capture_handle, buffer, buffer_frames)) !=
        buffer_frames) {
      fprintf(stderr, "read from audio interface failed (%s)\n", err,
              snd_strerror(err));
      exit(1);
    }
    
    fwrite(buffer, 1, 160 * snd_pcm_format_width(format) / 8 * 5, out);
    // write(filedesc, buffer, size);
  }

  // Write real header to file
  rewind(out);
  hdr = genericWAVHeader(rate, 32, channels);
  uint32_t pcm_data_size =
      hdr->sample_rate * hdr->bytes_per_frame * duration / 1000;
  hdr->file_size = pcm_data_size + 44 - 8;
  err = writeWAVHeader(out, hdr);
  fclose(out);

  free(buffer);

  fprintf(stdout, "buffer freed\n");

  snd_pcm_close(capture_handle);
  fprintf(stdout, "audio interface closed\n");

  return 0;
}


I compiled it with "gcc -g recording.c -o recording -lasound -lpthread"

OBSERVED RESULT
# valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose ./recording
==3530== Memcheck, a memory error detector
==3530== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3530== Using Valgrind-3.17.0-07f0cdcbb4-20210319X and LibVEX; rerun with -h for copyright info
==3530== Command: ./recording
==3530==
--3530-- Valgrind options:
--3530--    --leak-check=full
--3530--    --show-leak-kinds=all
--3530--    --track-origins=yes
--3530--    --verbose
--3530-- Contents of /proc/version:
--3530--   Linux version 5.4.3-23.cm1 (root@mariner) (gcc version 9.1.0 (GCC)) #1-mariner SMP PREEMPT Tue May 11 22:19:15 UTC 2021
--3530--
--3530-- Arch and hwcaps: ARM64, LittleEndian, v8
--3530-- Page sizes: currently 4096, max supported 65536
--3530-- Valgrind library directory: /home/admin/valgrind-3.17.0/memcheck
--3530-- Reading syms from /var/custom-configs/home/admin/recording
--3530-- Reading syms from /usr/lib/ld-2.28.so
--3530-- Reading syms from /var/custom-configs/home/admin/valgrind-3.17.0/memcheck/memcheck-arm64-linux
--3530--    object doesn't have a dynamic symbol table
--3530-- Scheduler: using generic scheduler lock implementation.
--3530-- Reading suppressions file: /home/admin/valgrind-3.17.0/memcheck/default.supp
==3530== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-3530-by-root-on-???
==3530== embedded gdbserver: writing to   /tmp/vgdb-pipe-to-vgdb-from-3530-by-root-on-???
==3530== embedded gdbserver: shared mem   /tmp/vgdb-pipe-shared-mem-vgdb-3530-by-root-on-???
==3530==
==3530== TO CONTROL THIS PROCESS USING vgdb (which you probably
==3530== don't want to do, unless you know exactly what you're doing,
==3530== or are doing some strange experiment):
==3530==   /home/admin/valgrind-3.17.0/memcheck/../../bin/vgdb --pid=3530 ...command...
==3530==
==3530== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==3530==   /path/to/gdb ./recording
==3530== and then give GDB the following command
==3530==   target remote | /home/admin/valgrind-3.17.0/memcheck/../../bin/vgdb --pid=3530
==3530== --pid is optional if only one valgrind process is running
==3530==
--3530-- REDIR: 0x4017340 (ld-linux-aarch64.so.1:strlen) redirected to 0x580c8798 (vgPlain_arm64_linux_REDIR_FOR_strlen)
--3530-- REDIR: 0x40170c0 (ld-linux-aarch64.so.1:strcmp) redirected to 0x580c87ec (vgPlain_arm64_linux_REDIR_FOR_strcmp)
--3530-- REDIR: 0x4016fd0 (ld-linux-aarch64.so.1:index) redirected to 0x580c87c0 (vgPlain_arm64_linux_REDIR_FOR_index)
ERROR: ld.so: object '/home/admin/valgrind-3.17.0/memcheck/vgpreload_core-arm64-linux.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
--3530-- Reading syms from /var/custom-configs/home/admin/valgrind-3.17.0/memcheck/vgpreload_memcheck-arm64-linux.so
--3530-- Reading syms from /usr/lib/libasound.so.2.0.0
--3530--    object doesn't have a symbol table
--3530-- Reading syms from /usr/lib/libpthread-2.28.so
--3530-- Reading syms from /usr/lib/libc-2.28.so
--3530-- Reading syms from /usr/lib/libm-2.28.so
--3530-- Reading syms from /usr/lib/libdl-2.28.so
--3530-- Reading syms from /usr/lib/librt-2.28.so

valgrind: m_redir.c:1195 (vgPlain_redir_do_lookup): Assertion 'iFuncWrapper' failed.

host stacktrace:
==3530==    at 0x58046584: show_sched_status_wrk (m_libcassert.c:406)
==3530==    by 0x580466C3: report_and_quit (m_libcassert.c:477)
==3530==    by 0x58046823: vgPlain_assert_fail (m_libcassert.c:543)
==3530==    by 0x580C60F7: vgPlain_redir_do_lookup (m_redir.c:1195)
==3530==    by 0x58060E0F: vgPlain_translate (m_translate.c:1529)
==3530==    by 0x580A6867: handle_tt_miss (scheduler.c:1138)
==3530==    by 0x580A6867: vgPlain_scheduler (scheduler.c:1500)
==3530==    by 0x580F2EAB: thread_wrapper (syswrap-linux.c:101)
==3530==    by 0x580F2EAB: run_a_thread_NORETURN (syswrap-linux.c:154)
==3530==    by 0xFFFFFFFFFFFFFFFF: ???

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable (lwpid 3530)
==3530==    at 0x4A11778: memcpy (in /usr/lib/libc-2.28.so)
==3530==    by 0x400B2D7: _dl_relocate_object (in /usr/lib/ld-2.28.so)
==3530==    by 0x4003BEF: dl_main (in /usr/lib/ld-2.28.so)
==3530==    by 0x4014C57: _dl_sysdep_start (in /usr/lib/ld-2.28.so)
==3530==    by 0x40018CB: _dl_start_final (in /usr/lib/ld-2.28.so)
==3530==    by 0x4001B57: _dl_start (in /usr/lib/ld-2.28.so)
==3530==    by 0x4001047: ??? (in /usr/lib/ld-2.28.so)
client stack range: [0x1FFEFFE000 0x1FFF000FFF] client SP: 0x1FFEFFFCB0
valgrind stack range: [0x1008EB8000 0x1008FB7FFF] top usage: 14608 of 1048576


Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or

crashing, especially if it happened in m_mallocfree.c.

If that doesn't help, please report this bug to: www.valgrind.org

In the bug report, send all the above text, the valgrind
version, and what OS and version you are using.  Thanks.

EXPECTED RESULT
The expected result would be an error summary

SOFTWARE/OS VERSIONS
# uname -a
Linux apd-d8c0a6594e07 5.4.3-23.cm1 #1-mariner SMP PREEMPT Tue May 11 22:19:15 UTC 2021 aarch64 aarch64 aarch64 GNU/Linux
Comment 1 Paul Floyd 2021-09-24 10:48:34 UTC
Could you tell us more about your CPU? Did you build Valgrind from source?

Can you build the latest Valgrind from the git repo?

Your log contains

ERROR: ld.so: object '/home/admin/valgrind-3.17.0/memcheck/vgpreload_core-arm64-linux.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.

That's a big problem. This file contains the Valgrind versions of the C runtime functions that affect memory (like malloc, free, mem*, str*). Because these aren't being loaded, when your test executable tries to make a call to (at a guess) malloc, Valgrind is failing to redirect that call to its own version.
Comment 2 wissen.kompakt 2021-10-14 10:03:50 UTC
lscpu output:

Architecture:        aarch64
Byte Order:          Little Endian
CPU(s):              4
On-line CPU(s) list: 0-3
Thread(s) per core:  1
Core(s) per socket:  4
Socket(s):           1
NUMA node(s):        1
Vendor ID:           ARM
Model:               4
Model name:          Cortex-A53
Stepping:            r0p4
CPU max MHz:         1300.0000
CPU min MHz:         800.0000
BogoMIPS:            16.00
L1d cache:           unknown size
L1i cache:           unknown size
L2 cache:            unknown size
NUMA node0 CPU(s):   0-3
Flags:               fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid

I just rebuilt from source using sourceware.org/git/valgrind and I can't reproduce the error anymore so it seems I made initially a mistake when setting up valgrind.

Nevertheless, thanks for looking into it!