C: Segmentation error (Core dumped) when searching for function names

I would like to write C code to find all the functions in the C file and print the corresponding function names.

My code is:

#include <stdio.h> #include <string.h> #define SIZE 1024 void ffname(char *line) { int i=1,j=0; char *dt; char *name; strtok(line,"("); dt = strchr(line,' '); if(dt[i] == '*') i++; while(dt[i] != '\0') { name[j]=dt[i]; i++; j++; } name[j] ='\0'; printf("Function name is: %s\n", name); } int main(int argc, char **argv) { if(argc < 2) { printf("Give the filename \n"); printf("Usage: %s filename\n", argv[0]); return -1; } int i, lines =0, funlines =0,count =0, fn =0, flag =0; char c[100],b[100]; FILE *fd; fd = fopen(argv[1],"r"); while(fgets(c,SIZE,fd)) { lines++; i=0; for(i=0;i<strlen(c);i++) { while( c[i] =='\t' || c[i] == ' ') { i++; } if( c[i] == '{') { count++; if(flag) { funlines++; } if(count == 1) { fn++; printf("Function %d is Started..............\n", fn); flag = 1; ffname(b); } break; } else if( c[i] == '}') { count--; if(!count) { flag = 0; printf("No of lines in the function %d is: %d\n", fn, funlines); printf("Function %d is finished..........\n", fn); funlines = 0; } else { funlines++; } break; } else if(flag) { funlines++; break; } } strcpy(b,c); } printf("Total no of fucnion%d\n",fn); printf("Total no of lines%d\n",lines); return 0; } 

When I provide the following C file as input,

 #include<stdio.h> void add() { int a=5,b=7; printf("Addition is:%d\n", a+b); } void sub() { int a=20,b=8; printf("Subtraction is:%d\n", ab); } void main() { char *name="dhahira dhasneem"; char *line; line=strchr(name,' '); printf("Line:%s\n",line); printf("Name:%s\n",name); add(); sub(); } 

I get the following output.

 Function 1 is Started.............. Segmentation fault (core dumped) 

I am using valgrind , but I do not know how to determine the error with this. Please guide me. Thanks.

Update:

I got the result when I used the suggested answer. After that, I would like to expand my previous code to store function details (function name and function depth) in the structure. I was getting output when I used to store function information for a simple program. But I get the following output for my program when I run it in gdb .

 (gdb) b 87 Breakpoint 1 at 0x804885e: file fun_printstruct.c, line 87. (gdb) r dat.c Starting program: /home/dhahira/dhas/Project/a.out dat.c Function 1 is Started.............. Program received signal SIGSEGV, Segmentation fault. 0x080485d4 in ffname (line=0xbfffe71c "/*struct *dhahira", name=0x0) at fun_printstruct.c:21 21 name[j]=dt[i]; (gdb) s Program terminated with signal SIGSEGV, Segmentation fault. The program no longer exists. 

My code: (extended to store function information in the structure)

 #include <stdio.h> #include <string.h> #define SIZE 1024 void ffname(char *line) { int i=1,j=0; char *dt; char name[SIZE]; strtok(line,"("); dt = strchr(line,' '); if(dt[i] == '*') i++; while(dt[i] != '\0') { name[j]=dt[i]; i++; j++; } name[j] ='\0'; printf("Function name is: %s\n", name); } int main(int argc, char **argv) { if(argc < 2) { printf("Give the filename \n"); printf("Usage: %s filename\n", argv[0]); return -1; } int i, lines =0, funlines =0,count =0, fn =0, flag =0, fg=0,size=0,emptyflag=0,commandflag=0; char c[SIZE],b[SIZE],st[SIZE],d[SIZE]; int command[]={}; FILE *fd; fd = fopen(argv[1],"r"); while(fgets(c,SIZE,fd)) { emptyflag=0; lines++; for(i=0;i<(sizeof(command)/4);i++) { if(lines == command[i]) { commandflag=1; break; } } strcpy(st,c); strtok(st," "); size = strlen(c); if(size == 1 && (strcmp(c,"\n"))== 0) emptyflag=1; if( !strcmp(st,"struct")) fg=1; for(i=0;i<size;i++) { if(commandflag) { break; } while( c[i] =='\t' || c[i] == ' ') { i++; } if( c[i] == '{') { count++; if(flag) { if(!emptyflag) funlines++; else emptyflag=0; } if(count ==1 && fg ==1) { if(b[strlen(b)-2] == ')') { fn++; printf("Function %d is Started..............\n", fn); flag = 1; ffname(b); } else { count--; } } else if(count == 1) { fn++; printf("Function %d is Started..............\n", fn); flag = 1; ffname(b); } break; } else if( c[i] == '}') { count--; if(count ==0 && fg ==1) { flag = 0; printf("No of lines in the function %d is: %d\n", fn, funlines); printf("Function %d is finished..........\n", fn); funlines = 0; fg=0; } else if(count ==0) { flag = 0; printf("No of lines in the function %d is: %d\n", fn, funlines); printf("Function %d is finished..........\n", fn); funlines = 0; } else if(count == -1) { count=0; fg=0; } else { if(!emptyflag) funlines++; else emptyflag=0; } break; } else if(flag ==1 && fg==1) { if(!emptyflag) funlines++; else emptyflag=0; break; } else if(flag) { if(!emptyflag) funlines++; else emptyflag=0; break; } break; } if(commandflag == 1) commandflag = 0; else strcpy(b,c); } printf("Total no of fucnion%d\n",fn); printf("Total no of lines%d\n",lines); return 0; } 

Please help me overcome this problem.

Is this a problem due to a code extension? (I can get the correct output separately.)

+4
source share
1 answer

You declare SIZE as 1024, and then read into an array of length 100:

 #define SIZE 1024 // ... snip .... char c[100],b[100]; FILE *fd; fd = fopen(argv[1],"r"); while(fgets(c,SIZE,fd)) 

This means that you write the boundaries of your array well, the rest of your stack, and cause corruption. In this case, this probably doesn’t actually happen, because your lines in your input file are no more than 100 characters, but this can happen if someone transferred a file with long lines.

It should be either

  char c[SIZE],b[SIZE]; 

or use sizof() in a call to fgets() :

 fgets(c,sizeof(c),fd) 

As others have indicated, it is best to include all available warnings; this will help you catch bugs faster. In GCC or Clang, I would recommend -Wall -Wextra -Werror ; this will allow you to use all common warnings and cause warnings as errors, so you cannot ignore them. If I run this in my code, I also get the following warnings:

 sf.c:16:9: error: variable 'name' is uninitialized when used here [-Werror,-Wuninitialized] name[j]=dt[i]; ^~~~ sf.c:9:15: note: initialize the variable 'name' to silence this warning char *name; ^ = NULL sf.c:40:18: error: comparison of integers of different signs: 'int' and 'size_t' (aka 'unsigned long') [-Werror,-Wsign-compare] for(i=0;i<strlen(c);i++) ~^~~~~~~~~~ 

The second problem is not a serious problem, just do it or declare i unsigned; The first thing you should fix. You need to allocate a buffer for the name, either on the stack ( char name[SIZE]; or similarly), or dynamically ( char *name = malloc(strlen(line)); or something like that). Be that as it may, name is an uninitialized pointer; it can point anywhere in memory, and as soon as you try to dereference it by storing something in name[j] , you write to an invalid memory area and get segfault.

Finally, as soon as you fix these problems, if you have additional problems, I would recommend running it under the debugger and see where the problems arise. If you are using an IDE, it probably has a built-in debugger interface; if not, compile with -g and run gdb executable arguments .

+4
source

All Articles