Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Newbie needing some help with segmentation fault

Reply
Thread Tools

Newbie needing some help with segmentation fault

 
 
Hendrik Maryns
Guest
Posts: n/a
 
      12-04-2007
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-----

 
Reply With Quote
 
 
 
 
Walter Roberson
Guest
Posts: n/a
 
      12-04-2007
In article <fj4637$ur9$>,
Hendrik Maryns <> 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
 
Reply With Quote
 
 
 
 
jacob navia
Guest
Posts: n/a
 
      12-04-2007
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
 
Reply With Quote
 
Martin Ambuhl
Guest
Posts: n/a
 
      12-04-2007
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.
 
Reply With Quote
 
John Gordon
Guest
Posts: n/a
 
      12-04-2007
In <fj4637$ur9$> Hendrik Maryns <> 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
B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

 
Reply With Quote
 
EventHelix.com
Guest
Posts: n/a
 
      12-05-2007
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
 
Reply With Quote
 
Hendrik Maryns
Guest
Posts: n/a
 
      12-05-2007
Walter Roberson schreef:
> In article <fj4637$ur9$>,
> Hendrik Maryns <> 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-----

 
Reply With Quote
 
Hendrik Maryns
Guest
Posts: n/a
 
      12-05-2007
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-----

 
Reply With Quote
 
santosh
Guest
Posts: n/a
 
      12-05-2007
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>

 
Reply With Quote
 
Hendrik Maryns
Guest
Posts: n/a
 
      12-05-2007
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-----

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Core Dump - Segmentation Fault -Newbie johnericaturnbull@yahoo.com Python 5 07-18-2008 09:57 PM
When I call malloc() to get some space, I get Segmentation fault Zheng Da C Programming 3 06-02-2005 08:54 PM
XML Newbie needing some serious help.. rh0dium Python 2 05-20-2005 12:20 PM
newbie Q, segmentation fault Elinore C Programming 4 03-04-2005 03:42 PM
segmentation fault on delete object (which belongs to some class under a hierarchy) Joel C++ 4 10-11-2004 05:07 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57