I have written a program and I have created this structure
struct position_found
{
int row;
int column;
struct position_found *next;
};
typedef struct position_found position_found, *position_found_ptr;
and then i use this function to create a new node type position_found
position_found_ptr new_position_found_node(int row, int column)
{
position_found_ptr x;
x=(position_found_ptr)malloc(sizeof(position_found));
if(x==NULL)
{
printf("out of memory");
exit(2);
}
x->row=row;
x->column=column;
x->next=NULL;
return x;
}
The problem is that x=(position_found_ptr)malloc(sizeof(position_found)); presents seg fault, but if i print something right before this, for example printf("k");, malloc will work properly and my program will continiue. I've tried using the function on her own in a test programm and it works perfectly. Do you have any idea what is happening?
if you want , put your whole code so i can debug it with gdb (or you can do it yourself ) :D
but the answer for your second question :
the reason is that when you run a program , in has some memory size (except your variables and other things ) its about OS !
if you have a problem with working with memory (like your code) you get segmentation fault !
but when you add some line(s) of code ,this changes the data order writing in memory cells so that your remaining code doesn't write on illegal memory cells ! :D
for example :
if before adding printf("k"); you were on x1234 which is illegal and because of that you've got seg fault , after adding that , you went on x4323 so this is legal and everything is ok :D
you can use "gdb" to "disassemble" to check what i said :D !!
Related
I am trying to create a simple top utility xv6. To do this, I have created a system call that will allow me to to access the kernel space. I have followed many guides on how to create system calls and my code compiles without issues.
My problem exists when I try running top in qemu. I will get a trap 14 error whenever I try to access my struct array whether it be in kernel or user space.
To break things down a little, I have a top.c file:
...
int main(){
struct uproc table[MAX];//where MAX is defined as 10
if(!getprocs(MAX, table))
printf("YAY");
...
in sysproc.c:
...
int
sys_getprocs(int max, struct uproc table[]){
return gettable(table);
}
and then in procs.c
....
int gettable(struct uproc table[]){
struct uproc u;
struct proc *p;
int i = 0;
aquire(&ptable.lock);
for(p->state.proc; p < &ptable.proc[NPROC];p++){
if(//p->state is valid){
u.state = p->state;
...
table[i] = u;//where I get the trap 14 error
}
}
}
Again, my assumption is that when I pass table around from user to kernel it's getting corrupted, but with that said I'm not sure how I could properly pass it.
All xv6 sys_* functions are parameterless.
Read the argint, argstr, and argptr functions in order to figure our how to pass parameters to the kernel from user mode,
Here is a C function that segfaults:
void compileShaders(OGL_STATE_T *state) {
// First testing to see if I can access object properly. Correctly outputs:
// nsHandle: 6
state->nsHandle = 6;
printf("nsHandle: %d\n", state->nsHandle);
// Next testing if glCreateProgram() returns proper value. Correctly outputs:
// glCreateProgram: 1
printf("glCreateProgram: %d\n", glCreateProgram());
// Then the program segfaults on the following line according to gdb
state->nsHandle = glCreateProgram();
}
For the record state->nsHandle is of type GLuint and glCreateProgram() returns a GLuint so that shouldn't be my problem.
gdb says that my program segfaults on line 303 which is actually the comment line before that line. I don't know if that actually matters.
Is gdb lying to me? How do I debug this?
EDIT:
Turned off optimizations (-O3) and now it's working. If somebody could explain why that would be great though.
EDIT 2:
For the purpose of the comments, here's a watered down version of the important components:
typedef struct {
GLuint nsHandle;
} OGL_STATE_T;
int main (int argc, char *argv[]) {
OGL_STATE_T _state, *state=&_state;
compileShaders(state);
}
EDIT 3:
Here's a test I did:
int main(int argc, char *argv[]) {
OGL_STATE_T _state, *state=&_state;
// Assign value and try to print it in other function
state->nsHandle = 5;
compileShaders(state);
}
void compileShaders(OGL_STATE_T *state) {
// Test to see if the first call to state is getting optimized out
// Correctly outputs:
// nsHandle (At entry): 5
printf("nsHandle (At entry): %d\n", state->nsHandle);
}
Not sure if that helps anything or if the compiler would actually optimize the value from the main function.
EDIT 4:
Printed out pointer address in main and compileShaders and everything matches. So I'm gonna assume it's segfaulting somewhere else and gdb is lying to me about which line is actually causing it.
This is going to be guesswork based on what you have, but with optimization on this line:
state->nsHandle = 6;
printf("nsHandle: %d\n", state->nsHandle);
is probably optimized to just
printf("nsHandle: 6\n");
So the first access to state is where the segfault is. With optimization on GDB can report odd line numbers for where the issue is because the running code may no longer map cleanly to source code lines as you can see from the example above.
As mentioned in the comments, state is almost certainly not initialized. Some other difference in the optimized code is causing it to point to an invalid memory area whereas the non-optimized code it's pointing somewhere valid.
This might happen if you're doing something with pointers directly that prevents the optimizer from 'seeing' that a given variable is used.
A sanity check would be useful to check that state != 0 but it'll not help if it's non-zero but invalid.
You'd need to post the calling code for anyone to tell you more. However, you asked how to debug it -- I would print (or use GDB to view) the value of state when that function is entered, I imagine it will be vastly different in optimized and non-optimized versions. Then track back to the function call to work out why that's the case.
EDIT
You posted the calling code -- that should be fine. Are you getting warnings when compiling (turn all the warnings on with -Wall). In any case my advice about printing the value of state in different scenarios still stands.
(removed comment about adding & since you edited the question again)
When you optimize your program, there is no more 1:1 mapping between source lines and emmitted code.
Typically, the compiler will reorder the code to be more efficient for your CPU, or will inline function call, etc...
This code is wrong:
*state=_state
It should be:
*state=&_state
Well, you edited your post, so ignore the above fix.
Check for the NULL condition before de-referencing the pointer or reading it. If the values you pass are NULL or if the values stored are NULL then you will hit segfault without performing any checks.
FYI: GDB Can't Lie !
I ended up starting a new thread with more relevant information and somebody found the answer. New thread is here:
GCC: Segmentation fault and debugging program that only crashes when optimized
I am trying to print out the contents of a 2 dimensional array starting from a certain location in the array (since not all elements of the array are filled). The array contains pointers to a data structure I created called a node. Here is the print code:
void repository_print(int print_elements){
node *travTemp;
travTemp = main_list[highest_level][0];
while((travTemp->down)!=NULL){
while((travTemp->next)!=NULL){
printf(" {%d, %d}", travTemp->key, travTemp->d);
travTemp = travTemp->next;
}
travTemp = travTemp->down;
printf("\n");
}
}
Basically the array holds pointers to node elements in a sorted fashion. Each node contains a "key" attribute and a "d" attribute and I am just trying to go level by level and print out the {key, d} records cleanly. I keep getting a segfault when I call the print command in my main. I tried using gdb to debug it but it won't give me an actual line. It just says:
#0 0x0000000000400b2e in repository_print ()
#1 0x0000000000400722 in main ()
Does anyone how I can find the seg fault or why the seg fault is occurring? Thanks.
EDIT:
I did try compiling with -g and found that the error is occurring at the line "while((travTemp->next)!=NULL)". This is confusing to me because this attribute should not be NULL. I'll have to check the rest of my code. The main_list declaration is as follows in case anyone needs to know:
node *main_list[MAX_HEIGHT][MAX_LEVEL];
EDIT:
So following Felipe's advice I changed my print function to the following:
node *travTemp;
travTemp = main_list[highest_level][0];
while(travTemp!=NULL && (travTemp->down)!=NULL){
printf(" {%d, %d}", travTemp->next->key, travTemp->next->d);
travTemp = travTemp->next;
}
travTemp = main_list[highest_level+1][0];
printf("\n");
However, now, I'm getting a seg fault at the print statement line. If travTemp->next does not equal NULL what's the problem with travTemp->next->key? I have no idea why since these values should exist in the repository.
If main_list[highest_level][0] is NULL, then your initial attempt to test travTemp->next will fail. #Filipe has addressed getting more debugging info in the comments.
Update: if it isn't NULL but following travTemp seems to be the problem, perhaps it is some other illegal value. Not seeing how main_list was filled, can't say more than that.
I'm pretty new to C. When I run the following code for a hash table under Valgrind:
table *insertObject (table *h, int pref, char ch)
{
struct node x;
int i;
if (ch < 0)
{
ch=256-ch;
}
x.chr=ch;
x.pref=pref;
i = hash(pref, ch, h->size);
while (h->hash[i].pref!=0)
{
i++;
}
h->hash[i]=x;
h->size++;
return h;
}
I get the following error:
==9243==
==9243== Process terminating with default action of signal 11 (SIGSEGV)
==9243== Bad permissions for mapped region at address 0x6018A4
==9243== at 0x4009CD: insertObject (encode.c:119)
==9243== by 0x4008E3: main (encode.c:55)
Line 119 is the line
h->hash[i]=x;
The funny thing is, when I run the whole code through a debugger, it works fine 90% of the time. However, for some special cases, the code segfaults, and the debugger tells me this is also the culprit. What's wrong?
The error is due to an incorrect memory access, basically your application is trying to access a memory area which is not mapped in its memory space.
Quite likely the value of i exceeds the limits of the hash array. I cannot be more precise because I do not how the hash function works and what perf stands for.
However, you should verify the value of i with a debugger, in the 10% of case where the application does not work.
P.S. a program should work fine 100% of time.
I am kinda new to C and I am trying to write a simple snake remake.
You can view the source on github: https://github.com/blackwolf12333/Snake
When building there are no warnings or errors in the output. But when I run the executable and hit enter it exit's with "Segmentation fault(core dumped)".
I am not a pro yet with pointers, I come from java, and when googling I found that it probably is a problem with pointers.
I have no idea of where it is going wrong because for as far as I know I am doing things right. The problem is when I try to loop through my snake's body_part's.
void print_snake() {
int i;
body_part *next = main_snake.head.next;
move(main_snake.head.pos.x, main_snake.head.pos.y);
addch('$');
for(i = 0; i < main_snake.length; i++) { //TODO: segfaults when 'main_snake.length'(should be this) instead of 'main_snake.length - 1'
printf("1 part");
print_body_part(next);
next = next->next;
}
}
That's from the snake.c file in the repository.
I hope you guys can help me,
greetings blackwolf12333
Before going deep through the code it is obvious that when next becomes null and next->next causes segmentation fault.
In the loop you are starting at a node next to head(main_snake.head.next). Therefore in a list of 4 objects you are processing only 3 objects. In that case iterations should be 3 instead of 4 because main_snake.length counts the head also as shown in the function initialize_snake. That is why you are getting segmentation fault.
If you want to iterate over a chained list, don't use a seperate stop condition. Your i variable and main_snake.length are not necessary. You can replace
for(i = 0; i < main_snake.length; i++)
with
body_part *next;
for(next = main_snake.head.next; next->next != NULL; next=next->next){
...
}