[Beowulf] Seg Fault with pvm_upkstr() and Linux.

Robert G. Brown rgb at phy.duke.edu
Wed Mar 16 13:23:09 PST 2005


On Wed, 16 Mar 2005, Josh Zamor wrote:

> --strPVM.c--
> 
> #include <pvm3.h>
> #include <stdio.h>
> 
> int main(int argc, char** argv) {
>      int info, mytid, myparent, child[2];

Add

       char buf[3];

> 
>      if(mytid = pvm_mytid() < 0) {
> 	pvm_perror("Could not get mytid");
> 	return -1;
>      }
> 
>      myparent = pvm_parent();
>      if((myparent < 0) && (myparent != PvmNoParent)) {
> 	pvm_perror("Some odd errr for my parent");
> 	pvm_exit();
> 	return -1;
>      }
> 
>      /* I am parent */
>      if(myparent == PvmNoParent) {
> 	info = pvm_spawn(argv[0], NULL, PvmTaskDefault, NULL, 2, child);
> 
> 	for(int i = 0; i < 2; ++i) {
> 	    if(child[i] < 0)
> 		printf(" %d", child[i]);
> 	    else
> 		printf("t%x\t", child[i]);
> 	}
> 	putchar('\n');
> 
> 	if(info != 2) {
> 	    pvm_perror("Kids didn't all spawn!");
> 	    pvm_exit();
> 	    return -1;
> 	}
> 
> 	for(int i = 0; i < 2; ++i) {
> 	    char* retStr;

delete line ^^^^^^^^^^^^^^

> 	    info = pvm_recv(-1, 11);
> 	    info = pvm_upkstr(retStr);

change to 
 	    info = pvm_upkstr(buf);

> 	    printf("Recieved return string: %s\n", buf);
> 	}
> 
> 	pvm_exit();
> 	return 0;
>      } else { /* Child follows */
> 	char str[3];

delete, and change to

 	buf[0] = 'a';
 	buf[1] = 'b';
        buf[2] = (char)0;

(noting that:

>> 	str[3] = (char)0;

is a bug!)

Or use

        snprintf(buf,3,"ab");

Or strncpy.

> 	pvm_initsend(PvmDataDefault);
> 	pvm_pkstr(buf);

                  ^^^
> 	pvm_send(myparent, 11);
> 	pvm_exit();
> 	return 0;
>      }
> }
> 

The code you sent looks to me to be wrong.  You declare retStr to be a
char *, but there is no space associated with it and you don't
initialize it.  I believe that pvm's pvm_unpkstr COPIES the returned
string into the destination rather than sets the pointer to point to
anonymous memory somewhere, since the latter would leak sieve-like.

Malloc'ing the vector should have worked also, but depending on where
str[] was allocated, just referencing str[3] could have caused a segment
violation.  

If you want to see an example of a guaranteed-working program that sends
a simple string using pvm all packaged up neatly to use as a template
for doing actual work, you might look at

  http://www.phy.duke.edu/~rgb/General/project_pvm.php

I put this up as an example PVM program template for a CWM column last
year sometime.  It keeps the master and slave code separate (and builds
them separately).  I can't see any good reason that your "fork/exec"
style code shouldn't work, though.  Declaring the local variables inside
conditional segments might cause their location to be relatively likely
to cause segment violation problems when you access the string beyond
its allocated length, although I confess that USUALLY this will "work".
That's probably why it worked on the mac, and why it might work on linux
if you move things around a bit but leave things otherwise the same.

SO, two definite bugs -- must allocate the target memory block one way
or another and must not reference an allocated vector past the end.
We'll have to see if these are "the" bugs -- there may be others.
Either one would cause a segment violation in particular, though.

In a minute I'll try to compile your program and test the fixes I
suggest above (I know, should probably have done this FIRST, right?:-).

  HTH,

    rgb

> Also, for the character array "str" in the child segment above, I have 
> tried using malloc to create the memory, and using const char arrays as 
> well. While all of these methods give seg faults on the linux machine, 
> the above way was the only way that I tried that worked and didn't give 
> a bus error on Mac OSX.
> 
> Thanks again.
> 

-- 
Robert G. Brown	                       http://www.phy.duke.edu/~rgb/
Duke University Dept. of Physics, Box 90305
Durham, N.C. 27708-0305
Phone: 1-919-660-2567  Fax: 919-660-2525     email:rgb at phy.duke.edu





More information about the Beowulf mailing list