| Summary: | big malloc() causes: Valgrind received a signal 11 (SIGSEGV) - exiting | ||
|---|---|---|---|
| Product: | [Developer tools] valgrind | Reporter: | mntadent |
| Component: | general | Assignee: | Paul Floyd <pjfloyd> |
| Status: | RESOLVED NOT A BUG | ||
| Severity: | crash | CC: | pjfloyd |
| Priority: | NOR | ||
| Version First Reported In: | 3.26.0 | ||
| Target Milestone: | --- | ||
| Platform: | unspecified | ||
| OS: | Unspecified | ||
| Latest Commit: | Version Fixed/Implemented In: | ||
| Sentry Crash Report: | |||
| Attachments: | Output from valgrind -v | ||
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. |
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.