I'll copy the relevant lines:
(Declarations)
typedef struct { /* per una entrada de la taula de posicion */
int f;
int c;
} pos;
pos *p_opo[9];
(in main)
for (i = 0; i < num; i++) {
p_opo[i] = (pos *) calloc(n_fil * n_col / 2, sizeof (pos));
}
Now, after only having introduced this lines, the code breaks in an arbitrary point (in a call to a given library function). I suspect I'm corrupting something with this, although I don't know what.
All I want is to have an array of variable size arrays!
PD: num is an argument of the program. I've been running it with num=1 anyway.
num should be less or equal to 9. (0..8 allocated pointers in p_opo equals 9 !)
Note that in C that you get errors in a different place in case of memory leaks, etc. The reason for this is that by changing some code, other code or data can be rearranged and this may end up in segmentation faults.
So the problem may very well be in another part of your program. Make sure you have all you warnings turned on (like the -Wall option in gcc), it may give you some clues.
If your call to calloc asks for memory of size 0 it may return NULL, and if you are making use of that memory it could be causing the segmentation fault. So if:
0 == (n_fil * n_col / 2)
or somehow
0 == sizeof (pos) /* I don't think that this is possible */
the size of the memory that you are asking for is 0, and so calloc can return NULL.
If this is not the case then I don't think that you have enough code up there for anyone to know why it is segfaulting. You should keep in mind that errors like this can go unnoticed until you add or change some code that seems to be totally unrelated to the code that has the actual error.
Seeing you casting the return of calloc makes me suspicious. Don't do that, this leads to a typical error if you forget the include for the system function.
This happes if you are on a machine with 64 bit pointers and 32 bit int.
Related
I'm creating the below array:
int p[100];
int
main ()
{
int i = 0;
while (1)
{
p[i] = 148;
i++;
}
return (0);
}
The program aborts with a segmentation fault after writing 1000 positions of the array, instead of the 100. I know that C doesn't check if the program writes out of bounds, this is left to the OS. I'm running it on ubuntu, the size of the stack is 8MB (limit -s). Why is it aborting after 1000? How can I check how much memory my OS allocates for an array?
Sorry if it's been asked before, I've been googling this but can't seem to find a specific explanation for this.
Accessing an invalid memory location leads to Undefined Behavior which means that anything can happen. It is not necessary for a segmentation-fault to occur.
...the size of the stack is 8MB (limit -s)...
variable int p[100]; is not at the stack but in data area because it is defined as global. It is not initialized so it is placed into BSS area and filled with zeros. You can check that printing array values just at the beginning of main() function.
As other said, using p[i] = 148; you produced undefined behaviour. Filling 1000 position you most probably reached end of BSS area and got segmentation fault.
It appear that you clearly get over the 100 elements defined (int p[100];) since you make a loop without any limitation (while (1)).
I would suggest to you to use a for loop instead:
for (i = 0; i < 100; i++) {
// do your stuff...
}
Regarding you more specific question about the memory, consider that any outside range request (in your situation over the 100 elements of the array) can produce an error. The fact that you notice it was 1000 in your situation can change depending on memory usage by other program.
It will fail once the CPU says
HEY! that's not Your memory, leave it!
The fact that the memory is not inside of the array does not mean that it's not for the application to manipulate.
The program aborts with a segmentation fault after writing 1000 positions of the array, instead of the 100.
You do not reason out Undefined Behavior. Its like asking If 1000 people are under a coconut tree, will 700 hundred of them always fall unconscious if a Coconut smacks each of their heads?
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I'm getting a segmentation fault, which I've narrowed down to a for loop in a callback function. It's strange because the program was previously working, now it's not!
struct debuggerth_command debuggerth_protocol[] = { /*
* Note: These strings are NOT null-terminated. The
* strings are 4 bytes long for memory alignment and
* integer-cast comparisons.
*/
{ "run ", debuggerth_startprocess },
{ "stop", 0 },
{ "inp ", 0 },
{ "sig ", 0 },
{ 0, 0 }
};
And this is the code:
int debuggerth_callback (struct libwebsocket_context * context,
struct libwebsocket * wsi,
enum libwebsocket_callback_reasons reason,
void * user,
void * in,
size_t len){
switch (reason) {
case LWS_CALLBACK_RECEIVE:
if (len < 4){
/* send error */
return -1;
}
/* Getting a segmentation fault
* within this loop.
*/
// I used this break to determine where the seg fault starts
// break
int i = 0;
for (; debuggerth_protocol[i].cmd; i++)
if (cmpcmd (debuggerth_protocol[i].cmd, in)) break;
//break;
if (!debuggerth_protocol[i].cmd){
int byteswritten = sprintf
(debuggerth_message,
debuggerth_format,
debuggerth_headers[0],
debuggerth_errors [0]);
libwebsocket_write (wsi, debuggerth_message,
byteswritten,
LWS_WRITE_TEXT);
return -1;
}
break;
This is the string comparison macro:
#define cmpcmd(cmd, str) ((*(int*)(cmd)) == (*(int*)(str)))
Anyone have any ideas?
One idea: relying on the fact that your strings are exactly the size of an int is rather horrendous.
People often try to do clever things like that only to be badly bitten when the underlying assumptions change, such as moving to a platform where the int type is eight bytes.
I'd ditch that macro and rewrite it to use strcmp or strncmp (a).
There's also a couple of other things to do.
First, print out (or use a debugger to examine) all variables before attempting to use them. It may be that in is NULL.
Or maybe you attempt to call the NULL commands like stop or sig, or even if you get a command that's not in your table and you blindly call it when i is equal to 4. These particular possibilities are in code not shown, following the loop, so it's pure, though I'd like to think educated, speculation on my part.
Another possibility is that you're running on an architecture that disallows unaligned access. Some architectures are optimised for accessing on specific boundaries (such as getting 32-bit values from 32-bit aligned addresses) and will run slower if you violate that alignment.
However, some architectures won't allow unaligned access at all, instead giving something like a BUS error if you try.
Since you've now indicated in a comment that you're using ARM, that's almost certainly the case. See here for some more information.
If that's the case, it's even more reason to get rid of the tricky macro and use a more conventional solution.
(a): You may also want to investigate the term "strict aliasing" at some point since this may technically be undefined behaviour.
Given this is running on ARM, I think your problem is that it's doing an unaligned memory access, which will either fail or be quite slow. It is not exactly a seg fault. See this question for example, and as suggested there -Wcast-align will probably flag it as risky. You can turn on a software workaround but that's probably slower than just fixing it in your code.
One option would be to use memcmp which gcc may be able to compile down to something nearly as simple as a word read, in the case that it is aligned.
Another option, if performance is critical, is to unwind the loop into a case statement switching by the first byte of the command. Then just check the following characters are as expected.
I looked at some of the changes to my code, as #Jonothan Leffler suggested. This was the change I made:
struct debuggerth_command {
char * cmd;
int (*function)(struct debuggerth_session *, char * input);
};
struct debuggerth_command {
char cmd[4]; // changed this an array
int (*function)(struct debuggerth_session *, char * input);
};
So, when I initialized the structure here:
struct debuggerth_command debuggerth_protocol[] = { /*
* Note: These strings are NOT null-terminated. The
* strings are 4 bytes long for memory alignment and
* integer-cast comparisons.
*/
{ "run ", debuggerth_startprocess },
{ "stop", 0 },
{ "inp ", 0 },
{ "sig ", 0 },
{ 0, 0 } /* Zero used to be a pointer value,
* but now it's the first element in a
* 4 byte array
*/
};
Which changed the evaluation of the for loop:
int i = 0;
for (; debuggerth_protocol[i].cmd; i++)
if (cmpcmd (debuggerth_protocol[i].cmd, in)) break;
To always evaluate true, because cmd is now a valid pointer to a 4-byte array - of which, the first value is 0.
I'll remove the macro, since it might not perform well on some architectures. But, couldn't this be fixed with the use of C11's alignas feature?
ive got a C program that gets caught in a for loop that it shouldn't, running it with
valgrind --tool=memcheck --leak-check=yes a.out
doesnt return anything even up until the program gets caught. is there a way to change the settings of valgrind to help me find the leak? as many have pointed out, it wouldnt be considered a leak, apologies
thanks in advance
here is the loop in question
int clockstate=0;
int clocklength=0;
int datalength=0;
int datastate=0;
int dataloc = 9;
((((some other code that i don't think is important to this part))))
int dataerr[13] = {0};
int clockerr[13] = {0}; // assumes that spill does not change within an event.
int spill=0;
int k = 0;
spill = Getspill(d+4*255+1); // get spill bit from around the middle
//printf("got spill: %d \n", spill); // third breakpoint
for( k = 0; k < 512; k++)
{
// Discardheader(d); // doesnt actually do anything, since it's a header.f
int databit = Getexpecteddata(d+4*k+1);
printf("%d ",k);
int transmitted = Datasample(&datastate, &datalength, d+4*k+2,dataerr,dataloc, databit);
printf("%d ",k);
Clocksample(&clockstate, &clocklength, d+4*k+3,clockerr, transmitted);
printf("%d \n",k);
// assuming only one error per event (implying the possibility of multi-error "errors"
// we construct the final error at the very end of the (outside this loop)
}
and the loop repeats after printing
254 254 254
255 255 255
256 256 1 <- this is the problem
2 2 2
3 3 3
edit** so i've tracked down where it is happening, and at one point in
void Clocksample (int* state, int* length, char *d, int *type, int transbit);
i have code that says *length = 1; so it seems that this command is somehow writing onto int k. my question now is, how did this happen, why isnt it changing length back to one like i want, and how do i fix it. if you want, i can post the whole code to Clocksample
Similar to last time, something in one of those functions, Clocksample() this time, is writing to memory that doesn't belong to the data/arrays that the function should be using. Most likely an out of bounds array write. Note: this is not a memory leak, which is allocating then losing track of memory blocks that should be freed.
Set a breakpoint at the call to Clocksample() for when k is 256. Then step into Clocksample(), keeping a watch on k (or the memory used by k). You can probably also just set a hardware memory write breakpoint on the memory allocated to k. How you do any of this depends on the debugger you're using.
Now single-step (or just run to the return of Clocksample() if you have a hardware breakpoint set) and when k changes, you'll have the culprit.
Please note that Valgrind is exceedingly weak when it comes to detecting stack buffer overflows (which is what appears to be happening here).
Google address-sanitizer is much better at detecting stack overflows, and I suggest you try it instead.
So your debugging output indicates that k is being changed during the call to your function Clocksample. I see that you are passing the addresses of at least two variables, &clockstate and &clocklength into that call. It seems quite likely to me that you have an array overrun or some other wild pointer in Clocksample that ends up overwriting the memory location where k is stored.
It might be possible to narrow down the bug if you post the code where k is declared (and whatever other variables are declared nearby in the same scope). For example if clocklength is declared right before k then you probably have a bug in using the pointer value &clocklength that leads to writing past the end of clocklength and corrupting k. But it's hard to know for sure without having the actual layout of variables you're using.
valgrind doesn't catch this because if, say, clocklength and k are right next to each other on the stack, valgrind can't tell if you have a perfectly valid access to k or a buggy access past the end of clocklength, since all it checks is what memory you actually access.
If the x and y parameter receive data from untrusted user would this piece of code pose some security threat?
char *p = malloc(x * y);
while (x > 0)
while (y > 0)
*p++ = 0;
Update:
Most people seems to comment on that it is an infinite loop and that this code piece will crash the program eventually when it write over its allocated memory.
However except for that problem. Isn't there possibly some issue with how malloc is used? E.g. heap overflow since no upper bound check for x and y?
You will write memory infinitely until the program craps out if x and y are positive, which I would expect. Not a good idea.
Receiving that code from a TRUSTED user would be a problem.
x and y never change. Assuming one of them is positive, the while loops will always evaluate to the same thing, and result in an infinite loop. If both are positive, you will keep writing memory until your program crashes.
Not a good piece of code.
If y and x are greater than 0, this will cause undefined behavior since you enter an infinite loop and assigning 0 to a pointer that points to memory you don't own.
Yes, that will write into memory that's not allocated, and the program will segfault.
Use memset if you want to empty a block of memory, the prototype looks like this:
void * memset(void *dest, int c, size_t count);
so the code would look something like this:
char *p = malloc(x * y);
memset(p, 0, x * y);
I don't see a security threat. Either you get values larger than 0, which will put you in an infinite loop and overwrite your process' memory until a segmentation fault occurs and your process dies. If one of the parameters is zero, you have a call to malloc(0), which might result in a memory leak.
The code is completely mad anyway, so I asume your question was academic.
Yes,there is an infinite loop and there can be a stack overflow, in your while loops.
Also Not sure how it is going to pose security threat, but it is a potential threat to the system, as it can cause memory issues.
There is no check of boundaries for "x" and "y", so user can send in a huge amount of data and you might get segmentation fault error.
There is missing cast of address returned by the malloc.
Also the coding style(*p++) confuses people so, it is difficult to maintain such a code.
This code will surely fail the application in real world.
As others have pointed out the code you've posted contains an infinite loop. You probably meant to do the following:
char *p = malloc( sizeof(x) * x * y );
if( p != NULL ) {
memset( p, 0, sizeof(x) * x * y );
} else {
// error allocating memory, handle it somehow
}
I found some code and I am baffled as to how the loop exits, and how it works. Does the program produce a deterministic output?
The reason I am baffled is:
1. `someArray` is of size 2, but clearly, the loop goes till size 3,
2. The value is deterministic and it always exits `someNumber` reaches 4
Can someone please explain how this is happening?
The code was not printing correctly when I put angle brackets <> around include's library names.
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
int main() {
int someNumber = 97;
int someArray[2] = {0,1};
int findTheValue;
for (findTheValue=0; (someNumber -= someArray[findTheValue]) >0; findTheValue++) {
}
printf("The crazy value is %d", findTheValue);
return EXIT_SUCCESS;
}
Accessing an array element beyond its bounds is undefined behavior. That is, the program is allowed to do anything it pleases, reply 42, eat your hard disk or spend all your money. Said in other words what is happening in such cases is entirely platform dependent. It may look "deterministic" but this is just because you are lucky, and also probably because you are only reading from that place and not writing to it.
This kind of code is just bad. Don't do that.
Depending on your compiler, someArray[2] is a pointer to findTheValue!
Because these variables are declared one-after-another, it's entirely possible that they would be positioned consecutively in memory (I believe on the stack). C doesn't really do any memory management or errorchecking, so someArray[2] just means the memory at someArray[0] + 2 * sizeof(int).
So when findTheValue is 0, we subtract, then when findTheValue is 1, we subtract 1. When findTheValue is 2, we subtract someNumber (which is now 94) and exit.
This behavior is by no means guaranteed. Don't rely on it!
EDIT: It is probably more likely that someArray[2] just points to garbage (unspecified) values in your RAM. These values are likely more than 93 and will cause the loop to exit.
EDIT2: Or maybe someArray[2] and someArray[3] are large negative numbers, and subtracting both causes someNumber to roll over to negative.
The loop exits because (someNumber -= someArray[findTheValue]) doesnt set.
Adding a debug line, you can see
value 0 number 97 array 0
value 1 number 96 array 1
value 2 number 1208148276 array -1208148180
that is printing out findTheValue, someNumber, someArray[findTheValue]
Its not the answer I would have expected at first glance.
Checking addresses:
printf("&someNumber = %p\n", &someNumber);
printf("&someArray[0] = %p\n", &someArray[0]);
printf("&someArray[1] = %p\n", &someArray[1]);
printf("&findTheValue = %p\n", &findTheValue);
gave this output:
&someNumber = 0xbfc78e5c
&someArray[0] = 0xbfc78e50
&someArray[1] = 0xbfc78e54
&findTheValue = 0xbfc78e58
It seems that for some reason the compiler puts the array in the beginning of the stack area, then the variables that are declared below and then those that are above in the order they are declared. So someArray[3] effectively points at someNumber.
I really do not know the reason, but I tried gcc on Ubuntu 32 bit and Visual Studio with and without optimisation and the results were always similar.