Bug 513285 - big malloc() causes: Valgrind received a signal 11 (SIGSEGV) - exiting
Summary: big malloc() causes: Valgrind received a signal 11 (SIGSEGV) - exiting
Status: RESOLVED NOT A BUG
Alias: None
Product: valgrind
Classification: Developer tools
Component: general (other bugs)
Version First Reported In: 3.26.0
Platform: unspecified Unspecified
: NOR crash
Target Milestone: ---
Assignee: Paul Floyd
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-12-13 11:50 UTC by mntadent
Modified: 2025-12-14 08:02 UTC (History)
1 user (show)

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


Attachments
Output from valgrind -v (11.47 KB, text/x-log)
2025-12-13 11:50 UTC, mntadent
Details

Note You need to log in before you can comment on or make changes to this bug.
Description mntadent 2025-12-13 11:50:39 UTC
Created attachment 187576 [details]
Output from valgrind -v

SYSTEM INFORMATION
host- and username changed
uname -a
Linux hostname 6.1.0-41-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.158-1 (2025-11-09) x86_64 GNU/Linux

Valgrind output in the attachment.

STEPS TO REPRODUCE
this is the bugged c code that causes valgrind to segfault. 
tested with
gcc (Debian 12.2.0-14+deb12u1) 12.2.0
and
Debian clang version 14.0.6

#include <assert.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
  double re;
  double im;
} complex;

FILE *file, *output;
long long k, samplerate, amount;
char line[512];
char *buffer = 0;
long length;
int main(int argc, char **argv) {

  file = fopen(argv[1], "rb");
  if (file == NULL) {
    fprintf(stderr, "Opening file \n");
    return -1;
  };

  fscanf(file, "%s", line);
  samplerate = atoi(line);
  fscanf(file, "%s", line);
  amount = atoi(line);
  fprintf(stderr, "%lld \n", amount);
  complex *v = (complex *)malloc(amount * sizeof(real));

  complex *scratch = (complex *)malloc(amount * sizeof(double));

  fprintf(stderr, "%lld\n", amount);

  // Broken thing
  while (fscanf(file, "%s", line) != EOF) {
    v[k].re = atof(line);
    v[k].im = 0;
    k++;
  }
  fprintf(stderr, "test");
  fclose(file);

  long msb = 0;
  while (amount != 0) {
    amount = amount / 2;
    msb++;
  }
  long long bytething;
  bytething = 1 << msb;
  printf("%lld\n", bytething);
}

The amount variable read from the file is 481489 and there is that many lines with numbers after that.
Comment 1 Paul Floyd 2025-12-14 08:02:02 UTC
What I see is

1. There is a fault in your executable (writing beyond an array allocated on the heap).
2. Valgrind crashes.

That is not unusual. Valgrind does not guarantee correct execution after errors occur in guest executables.

I have a few recommendations for your code

a) Compile your code with debug information (add -g to the compiler flags). The will help you identify the location of the error in your source code.
b) Use c99 and the "double complex" type. https://en.cppreference.com/w/c/numeric/complex.html. You won't have to write any code for mathematical operators and functions if you do that.
c) Never cast the return type of malloc in C. void* is by design the generic pointer type in C and automatic conversion to and from _pointer_ types and void* is a feature of C. By casting you are potentially converting a _non pointer_ to a pointer.
d) Use the compiler when calculating the sizes of arrays allocated with malloc

Rather than

type var* = malloc(number*sizeof(hard_coded_type)))

write

type var* = malloc(number*sizeof(*var))

This will always be correct. In your code it looks like you have the wrong type for "hard_coded_type" (real which I guess is an alias for double rather than your complex type). You will also be able to change "type" and it will still be correct - there will be no danger that you forget to also update "hard_coded_type".

One of the features of Valgrind is that once a non-leak error has been reported at a given location in the code/binary Valgrind will not print the same error if it happens again.

So you have

  // allocate 3,851,912 bytes
  complex *v = (complex *)malloc(amount * sizeof(real));

   // write to twice 3,851,912 bytes
  while (fscanf(file, "%s", line) != EOF) {
    v[k].re = atof(line);
    v[k].im = 0;
    k++;
  }

The line
    v[k].re = atof(line);
probably corresponds to
==90472== Invalid write of size 8
==90472==    at 0x400141E: main (in /home/user/Asiakirjat/valgrindbug/a.out)

and the line
      v[k].im = 0;
probably corresponds to
==90472== Invalid write of size 8
==90472==    at 0x4001402: main (in /home/user/Asiakirjat/valgrindbug/a.out)

That means that you are writing 3,851,912 bytes beyond the end of "v", but Valgrind's error reduplication is only reporting the first unique instance of these errors.

I'm closing this as  "NOT A BUG". If you make the changes that I suggest [above all item d) above] then repeat your test and there is still a crash in Valgrind then please reopen this report.