![]() |
Newbie needing some help with segmentation fault
Hi all,
I received a tiny program from a colleague. I want to use it in my Java program. I invoke it with Java’s ProcessBuilder. That not being very relevant, the problem is the following: it causes a segfault. Debugging tells me the following line is the culprit: while(fscanf(fp, "%s -> %s -> %s -> %s", name, left, right, symbol) == 4) This is the stack: Thread [0] (Suspended: Signal 'SIGSEGV' received. Description: Segmentation fault.) 4 _IO_vfscanf() 0x00002ae4d5a0565f 3 fscanf() 0x00002ae4d5a11a58 2 loadTree() /home/hendrik/workspace/ivb/ivb.c:54 0x0000000000402cbc 1 main() /home/hendrik/workspace/ivb/ivb.c:23 0x0000000000402a95 The relevant function is below. (Since the problematic line is in the beginning, you might not need all of it but I am really too new in C to be able to shorten this. Pointers to a relevant site are welcome.) What it does is it takes a file which contains a tree in some funny format and constructs the tree in way MONA [1] can handle them. Thank you very much. [1]: http://www.brics.dk/mona/ mgTreeNode *loadTree(char *file) { hcreate(MAX_NODES); char symbol[MAX_SYMBOL]; char name[MAX_NODENAME]; char left[MAX_NODENAME]; char right[MAX_NODENAME]; ENTRY node; char* cache[MAX_NODES][3]; size_t nodeCounter=0; size_t i; FILE *fp = fopen(file, "r"); while(fscanf(fp, "%s -> %s -> %s -> %s", name, left, right, symbol) == 4) { // construct the node mgTreeNode *t = tAlloc(); // convert the characters to numbers: unsigned int len = strlen(symbol); t->a = (char*)malloc(len*(sizeof(char))); // freed in freeTree for(i = 0; i < len; ++i) { t->a[i] = symbol[i] - '0'; } t->left = NULL; t->right = NULL; // insert it into the hashtable node.key = strdup(name); // this memory is freed after hdestroy node.data = t; hsearch(node, ENTER); // insert it into an array cache[nodeCounter][0] = node.key; cache[nodeCounter][1] = strdup(left); // freed after hdestroy cache[nodeCounter][2] = strdup(right); // freed after hdestroy ++nodeCounter; } fclose(fp); // loop over the array and fill in the links for(i=0; i < nodeCounter; ++i) { node.key = cache[i][0]; ENTRY *n = hsearch(node, FIND); node.key = cache[i][1]; ENTRY *l = hsearch(node, FIND); node.key = cache[i][2]; ENTRY *r = hsearch(node, FIND); if(l != NULL) ((mgTreeNode *) n->data)->left = (l->data); if(r != NULL) ((mgTreeNode *) n->data)->right = (r->data); } node.key = ROOT_NODE_NAME; ENTRY *root = hsearch(node, FIND); mgTreeNode *rootNode = NULL; if(root != NULL) rootNode = root->data; // free the hashtable hdestroy(); // free the keys for(i=0; i < nodeCounter; ++i) { int j; for(j=0; j<3; ++j) { free(cache[i][j]); } } return rootNode; } -- Hendrik Maryns http://tcl.sfs.uni-tuebingen.de/~hendrik/ ================== http://aouw.org Ask smart questions, get good answers: http://www.catb.org/~esr/faqs/smart-questions.html -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.4-svn0 (GNU/Linux) Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org iD8DBQFHVZune+7xMGD3itQRAkz/AJ4lhLapj6GsFtG08AkWNjx0ejuU7gCdFz08 Fbg3Iwrij5ykLmPcwomp24Y= =VPbd -----END PGP SIGNATURE----- |
Re: Newbie needing some help with segmentation fault
In article <fj4637$ur9$1@newsserv.zdv.uni-tuebingen.de>,
Hendrik Maryns <gtw37bn02@sneakemail.com> wrote: >the problem is the following: it causes a segfault. Debugging >tells me the following line is the culprit: > while(fscanf(fp, "%s -> %s -> %s -> %s", name, left, right, symbol) == > 4) [...] > char symbol[MAX_SYMBOL]; > char name[MAX_NODENAME]; > char left[MAX_NODENAME]; > char right[MAX_NODENAME]; > while(fscanf(fp, "%s -> %s -> %s -> %s", name, left, right, symbol) == 4) That fscanf() can cause an access violation if it encounters a line in which the length of any of the strings in the "name" or "left" or "right" positions are more than MAX_NODENAME-1 characters long, or if the string in the "symbol" position is more than MAX_SYMBOL-1 characters long. In particular watch out for cases in which the string are -exactly- MAX_NODENAME or MAX_SYMBOL long: in that case, fscanf() would need to store a trailing '\0' after the MAX_* characters had been stored in the variable. -- "Beware of bugs in the above code; I have only proved it correct, not tried it." -- Donald Knuth |
Re: Newbie needing some help with segmentation fault
Hendrik Maryns wrote:
> > [1]: http://www.brics.dk/mona/ > > mgTreeNode *loadTree(char *file) > { > hcreate(MAX_NODES); > > char symbol[MAX_SYMBOL]; > char name[MAX_NODENAME]; > char left[MAX_NODENAME]; > char right[MAX_NODENAME]; > ENTRY node; > char* cache[MAX_NODES][3]; > size_t nodeCounter=0; > size_t i; > > FILE *fp = fopen(file, "r"); WHAT HAPPENS IF fopen FAILS (the file doesn't exist, or has another name, or you have no access to it etc etc???) > while(fscanf(fp, "%s -> %s -> %s -> %s", name, left, right, symbol) == 4) > { This will trap if fp is NULL because fopen failed. -- jacob navia jacob at jacob point remcomp point fr logiciels/informatique http://www.cs.virginia.edu/~lcc-win32 |
Re: Newbie needing some help with segmentation fault
Hendrik Maryns wrote:
> Hi all, > > I received a tiny program from a colleague. I want to use it in my Java > program. I invoke it with Java’s ProcessBuilder. That not being very > relevant, the problem is the following: it causes a segfault. Debugging > tells me the following line is the culprit: > > while(fscanf(fp, "%s -> %s -> %s -> %s", name, left, right, symbol) == 4) It seems that one or more of name, left, right, symbolm is either non allocated space of is allocated too little space for the input string or fp was not properly assigned. [implementation-specific, and non-informative, stack dump removed] > mgTreeNode *loadTree(char *file) > { > hcreate(MAX_NODES); > > char symbol[MAX_SYMBOL]; > char name[MAX_NODENAME]; > char left[MAX_NODENAME]; > char right[MAX_NODENAME]; > ENTRY node; > char* cache[MAX_NODES][3]; > size_t nodeCounter=0; > size_t i; > > FILE *fp = fopen(file, "r"); Did this fopen succeed? If it did not (and you don't check) the following fscanf dereferences a null pointer. > while(fscanf(fp, "%s -> %s -> %s -> %s", name, left, right, symbol) == 4) If the fopen succeeded, one of MAX_SYMBOL or MAX_NODENAME is too small for the input data. The data itself may be munged. This is not a safe way to read these strings. |
Re: Newbie needing some help with segmentation fault
In <fj4637$ur9$1@newsserv.zdv.uni-tuebingen.de> Hendrik Maryns <gtw37bn02@sneakemail.com> writes:
> I received a tiny program from a colleague. > What it does is it takes a file which contains a tree in some funny > format and constructs the tree in way MONA [1] can handle them. > FILE *fp = fopen(file, "r"); > while(fscanf(fp, "%s -> %s -> %s -> %s", name, left, right, symbol) == 4) My first guess is that it's trying to open the tree file and failing, because it can't find it. It then tries to read from the invalid file pointer and dumps core. Do you have a copy of the tree file? Is is named correctly? Is it located in the proper subdirectory? Does it have appropriate permissions for reading? -- John Gordon A is for Amy, who fell down the stairs gordon@panix.com B is for Basil, assaulted by bears -- Edward Gorey, "The Gashlycrumb Tinies" |
Re: Newbie needing some help with segmentation fault
On Dec 4, 1:25 pm, Hendrik Maryns <gtw37b...@sneakemail.com> wrote:
> Hi all, > > signature.asc > 1KDownload > > I received a tiny program from a colleague. I want to use it in my Java > program. I invoke it with Java's ProcessBuilder. That not being very > relevant, the problem is the following: it causes a segfault. Debugging > tells me the following line is the culprit: > > while(fscanf(fp, "%s -> %s -> %s -> %s", name, left, right, symbol) == 4) > > This is the stack: > > Thread [0] (Suspended: Signal 'SIGSEGV' received. Description: > Segmentation fault.) > 4 _IO_vfscanf() 0x00002ae4d5a0565f > 3 fscanf() 0x00002ae4d5a11a58 > 2 loadTree() /home/hendrik/workspace/ivb/ivb.c:54 0x0000000000402cbc > 1 main() /home/hendrik/workspace/ivb/ivb.c:23 0x0000000000402a95 > > The relevant function is below. (Since the problematic line is in the > beginning, you might not need all of it but I am really too new in C to > be able to shorten this. Pointers to a relevant site are welcome.) > > What it does is it takes a file which contains a tree in some funny > format and constructs the tree in way MONA [1] can handle them. > > Thank you very much. > > [1]:http://www.brics.dk/mona/ > > mgTreeNode *loadTree(char *file) > { > hcreate(MAX_NODES); > > char symbol[MAX_SYMBOL]; > char name[MAX_NODENAME]; > char left[MAX_NODENAME]; > char right[MAX_NODENAME]; > ENTRY node; > char* cache[MAX_NODES][3]; > size_t nodeCounter=0; > size_t i; > > FILE *fp = fopen(file, "r"); > while(fscanf(fp, "%s -> %s -> %s -> %s", name, left, right, symbol) == 4) > { > // construct the node > mgTreeNode *t = tAlloc(); > > // convert the characters to numbers: > unsigned int len = strlen(symbol); > t->a = (char*)malloc(len*(sizeof(char))); // freed in freeTree > for(i = 0; i < len; ++i) { > t->a[i] = symbol[i] - '0'; > } > > t->left = NULL; > t->right = NULL; > > // insert it into the hashtable > node.key = strdup(name); // this memory is freed after hdestroy > node.data = t; > hsearch(node, ENTER); > > // insert it into an array > cache[nodeCounter][0] = node.key; > cache[nodeCounter][1] = strdup(left); // freed after hdestroy > cache[nodeCounter][2] = strdup(right); // freed after hdestroy > > ++nodeCounter; > } > fclose(fp); > > // loop over the array and fill in the links > for(i=0; i < nodeCounter; ++i) > { > node.key = cache[i][0]; > ENTRY *n = hsearch(node, FIND); > > node.key = cache[i][1]; > ENTRY *l = hsearch(node, FIND); > > node.key = cache[i][2]; > ENTRY *r = hsearch(node, FIND); > > if(l != NULL) ((mgTreeNode *) n->data)->left = (l->data); > if(r != NULL) ((mgTreeNode *) n->data)->right = (r->data); > } > > node.key = ROOT_NODE_NAME; > ENTRY *root = hsearch(node, FIND); > > mgTreeNode *rootNode = NULL; > if(root != NULL) rootNode = root->data; > > // free the hashtable > hdestroy(); > // free the keys > for(i=0; i < nodeCounter; ++i) > { > int j; > for(j=0; j<3; ++j) > { > free(cache[i][j]); > } > } > return rootNode;} > > -- > Hendrik Marynshttp://tcl.sfs.uni-tuebingen.de/~hendrik/ > ==================http://aouw.org > Ask smart questions, get good answers:http://www.catb.org/~esr/faqs/smart-questions.html The following links might help in the investigation: http://www.eventhelix.com/RealtimeMa...re_crashes.htm http://www.eventhelix.com/RealtimeMa..._crashes_2.htm -- EventStudio - http://www.Eventhelix.com/Eventstudio/ Sequence diagram based systems engineering tool |
Re: Newbie needing some help with segmentation fault
Walter Roberson schreef:
> In article <fj4637$ur9$1@newsserv.zdv.uni-tuebingen.de>, > Hendrik Maryns <gtw37bn02@sneakemail.com> wrote: >> the problem is the following: it causes a segfault. Debugging >> tells me the following line is the culprit: > >> while(fscanf(fp, "%s -> %s -> %s -> %s", name, left, right, symbol) == >> 4) > [...] >> char symbol[MAX_SYMBOL]; >> char name[MAX_NODENAME]; >> char left[MAX_NODENAME]; >> char right[MAX_NODENAME]; > >> while(fscanf(fp, "%s -> %s -> %s -> %s", name, left, right, symbol) == 4) > > That fscanf() can cause an access violation if it encounters > a line in which the length of any of the strings in the "name" or > "left" or "right" positions are more than MAX_NODENAME-1 characters long, > or if the string in the "symbol" position is more than MAX_SYMBOL-1 > characters long. In particular watch out for cases in which the > string are -exactly- MAX_NODENAME or MAX_SYMBOL long: in that > case, fscanf() would need to store a trailing '\0' after the MAX_* > characters had been stored in the variable. I suppose that is the reason why one shouldn’t use scanf. However, the problem was due to the file not being properly opened. Thanks, H. -- Hendrik Maryns http://tcl.sfs.uni-tuebingen.de/~hendrik/ ================== http://aouw.org Ask smart questions, get good answers: http://www.catb.org/~esr/faqs/smart-questions.html -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.4-svn0 (GNU/Linux) Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org iD8DBQFHVn71e+7xMGD3itQRAmc1AJ9qefczSKVZXtOT7uT/FrXqBih4igCcCmwP uq5bbkM6raKVEXolOPmZRsQ= =VXXH -----END PGP SIGNATURE----- |
Re: Newbie needing some help with segmentation fault
Martin Ambuhl schreef:
> Hendrik Maryns wrote: >> Hi all, >> >> I received a tiny program from a colleague. I want to use it in my Java >> program. I invoke it with Java’s ProcessBuilder. That not being very >> relevant, the problem is the following: it causes a segfault. Debugging >> tells me the following line is the culprit: >> >> while(fscanf(fp, "%s -> %s -> %s -> %s", name, left, right, symbol) >> == 4) > > It seems that one or more of name, left, right, symbolm is either non > allocated space of is allocated too little space for the input string or > fp was not properly assigned. > > [implementation-specific, and non-informative, stack dump removed] Please have some patience here. I am a regular poster to c.l.java.*, and now how annoying it can be to answer newbie questions. That’s why I stressed that twice. >> mgTreeNode *loadTree(char *file) >> { >> hcreate(MAX_NODES); >> >> char symbol[MAX_SYMBOL]; >> char name[MAX_NODENAME]; >> char left[MAX_NODENAME]; >> char right[MAX_NODENAME]; >> ENTRY node; >> char* cache[MAX_NODES][3]; >> size_t nodeCounter=0; >> size_t i; >> >> FILE *fp = fopen(file, "r"); > > Did this fopen succeed? If it did not (and you don't check) the > following fscanf dereferences a null pointer. This indeed was the problem: I gave the wrong arguments to the debug program. How do I properly check whether the open succeeded? Is if (fp == 0) exit(-2); enough? >> while(fscanf(fp, "%s -> %s -> %s -> %s", name, left, right, symbol) >> == 4) > > If the fopen succeeded, one of MAX_SYMBOL or MAX_NODENAME is too small > for the input data. The data itself may be munged. This is not a safe > way to read these strings. I suppose. Once again: I didn’t write this code, I only want to use it, for now; until I get time to write it properly. Thanks, H. -- Hendrik Maryns http://tcl.sfs.uni-tuebingen.de/~hendrik/ ================== http://aouw.org Ask smart questions, get good answers: http://www.catb.org/~esr/faqs/smart-questions.html -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.4-svn0 (GNU/Linux) Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org iD8DBQFHVn/Ee+7xMGD3itQRAgCiAJ9smijHUAnNPPXY7nxjYr7hihHvswCdH k1z EVXol1EhCkP1x+gSEQybmG8= =81gK -----END PGP SIGNATURE----- |
Re: Newbie needing some help with segmentation fault
Hendrik Maryns wrote:
> Martin Ambuhl schreef: <snip> >>> FILE *fp = fopen(file, "r"); >> >> Did this fopen succeed? If it did not (and you don't check) the >> following fscanf dereferences a null pointer. > > This indeed was the problem: I gave the wrong arguments to the debug > program. > > How do I properly check whether the open succeeded? Is > if (fp == 0) exit(-2); > enough? fopen() returns a NULL pointer if it fails. So you check like: FILE *f = fopen("file.txt" "r"); if (f == NULL) { puts("fopen() failed."); /* whatever */ } else { /* proceed */ } <snip> |
Re: Newbie needing some help with segmentation fault
santosh schreef:
> Hendrik Maryns wrote: > >> Martin Ambuhl schreef: > > <snip> > >>>> FILE *fp = fopen(file, "r"); >>> Did this fopen succeed? If it did not (and you don't check) the >>> following fscanf dereferences a null pointer. >> This indeed was the problem: I gave the wrong arguments to the debug >> program. >> >> How do I properly check whether the open succeeded? Is >> if (fp == 0) exit(-2); >> enough? > > fopen() returns a NULL pointer if it fails. So you check like: > > FILE *f = fopen("file.txt" "r"); > if (f == NULL) { puts("fopen() failed."); /* whatever */ } > else { /* proceed */ } Thanks. I’m getting the hang of this, I think. I prefer to write such stuff to stderr though, so I did the following: FILE *fp = fopen(file, "r"); if (fp == NULL) { fputs("Opening of the tree file failed. Did you enter it correctly and do you have read access?\n", stderr); exit(-2); } Cheers, H. -- Hendrik Maryns http://tcl.sfs.uni-tuebingen.de/~hendrik/ ================== http://aouw.org Ask smart questions, get good answers: http://www.catb.org/~esr/faqs/smart-questions.html -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.4-svn0 (GNU/Linux) Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org iD8DBQFHVppVe+7xMGD3itQRAm2nAJ41SxVrkMoW3iuNJpO9Sc PehSALmQCZAW/+ yagQaTQKHXM+HSzF5Dve1gY= =n2n5 -----END PGP SIGNATURE----- |
| All times are GMT. The time now is 08:25 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.