Thread: Trouble with execve

  1. #1
    Registered User
    Join Date
    Feb 2008
    Posts
    13

    Trouble with execve

    Hi,

    I'm writing a basic shell, and having some issues. I've searched the manpages, google, and this forum, but with no luck, so here's my problem.

    execve is working fine for commands that have no arguments, but when it requires arguments, I get a bad address error (returned by perror).

    This is how I'm initializing my parameter array:

    char (*params)[MAX_CHAR];
    params = malloc(MAX_PARAM * sizeof *params);

    I have MAX_CHAR set to 64, MAX_PARAM set to 16.

    Now, my program sets a simple char array called command to "/bin/mkdir", and copies the characters to params[0]. I set params[1][0] to 'a' and params[1][1] to 'a'. I've confirmed that this is exactly what's happened. I've printed each individual character in command, identifying null characters. I did the same thing with params[0] and params[1]. commands[10] == NULL, params[0][10] == NULL, params[1][2] == NULL, and params[2][0] == NULL. As far as I can tell I've met all the conditions for this to work, but it still will not... still getting a "bad address" error.

    Hopefully I've explained my problem sufficiently. Any ideas?

    Thanks.

  2. #2
    Registered User
    Join Date
    Nov 2006
    Location
    japan
    Posts
    126
    it would be better to show us your code
    Mac OS 10.6 Snow Leopard : Darwin

  3. #3
    Registered User
    Join Date
    Feb 2008
    Posts
    13
    Understood .

    I thought it might be a little more confusing than anything though, as it's not currently properly commented, and in general a little messy. Also, I'm coding remotely... so I've taken a screenshot. Here:

    http://img245.imageshack.us/my.php?image=codezn0.jpg

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Why don't you make a small, compilable, example of the problem [cut down your code to use a constant string as "input"].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Feb 2008
    Posts
    13
    Like this?

    Named minishell.c

    Sorry for the crudeness of the string naming.

    Code:
    main (int argc, char **argv)
    {
    	char *command = malloc(64);
    	char (*params)[64];
    	params = malloc(16 * sizeof *params);
    
    	printf("> ");
    	
    	command[0] = '/';
    	command[1] = 'b';
    	command[2] = 'i';
    	command[3] = 'n';
    	command[4] = '/';
    	command[5] = 'm';
    	command[6] = 'k';
    	command[7] = 'd';
    	command[8] = 'i';
    	command[9] = 'r';
    
    	params[0][0] = '/';
    	params[0][1] = 'b';
    	params[0][2] = 'i';
    	params[0][3] = 'n';
    	params[0][4] = '/';
    	params[0][5] = 'm';
    	params[0][6] = 'k';
    	params[0][7] = 'd';
    	params[0][8] = 'i';
    	params[0][9] = 'r';
    
    	params[1][0] = 'a';
    	params[1][1] = 'a';
    
    
    	execve(command, params, 0);
    	perror("minishell error");
    	
    }

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Perhaps you should null-terminate your strings?

    I also don't think you have an array or pointers, but you are passing the address of a 2D array, rather than an array of pointers or arrays of char.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Feb 2008
    Posts
    13
    Doesn't malloc set all values to null for me? Or are you saying I need to manually set command[10] = NULL, params[0][10] = NULL, etc.?

    Isn't that what I should be passing? How should I initialize it if that's not right? Note that I won't always know the size of each argument.

    Thanks for the response so far.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    No, malloc just gives you some memory with whatever content that bit of memory happens to have - it may be zero in one case, and non-zero at another time [for example if you get a "fresh" page from the kernel, it's probably cleared to some value, and zero is as good as any other - better in some cases - on the other hand, you may get a "recycled" page that is non-zero].

    As to passing an array of pointers or a 2D array, you should pass the address of a pointer to a pointer to char. A 2D array isn't that.

    Code:
    char *arr[10];
    for(i = 0; i < 10; i++)
        arr[i] = malloc(100);
    would be more suitable.

    Of course 10 and 100 may not be the right numbers, but you get the idea.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    Feb 2008
    Posts
    13
    Oh ok, I see what you mean. Thanks, I'll give it a shot.

    EDIT: Still not working. I've made the changes you suggested, so I now have:

    Code:
    main (int argc, char **argv)
    {
    	char *command = malloc(64);
    	char *params[16];
            int i;
            for (i = 0; i < 16; i++)
            {
                   params[i] = malloc(64); 
            }
    
    	printf("> ");
    	
    	command[0] = '/';
    	command[1] = 'b';
    	command[2] = 'i';
    	command[3] = 'n';
    	command[4] = '/';
    	command[5] = 'm';
    	command[6] = 'k';
    	command[7] = 'd';
    	command[8] = 'i';
    	command[9] = 'r';
            command[10] = NULL;
    
    	params[0][0] = '/';
    	params[0][1] = 'b';
    	params[0][2] = 'i';
    	params[0][3] = 'n';
    	params[0][4] = '/';
    	params[0][5] = 'm';
    	params[0][6] = 'k';
    	params[0][7] = 'd';
    	params[0][8] = 'i';
    	params[0][9] = 'r';
            params[0][10] = NULL;
    
    	params[1][0] = 'a';
    	params[1][1] = 'a';
            params[1][2] = NULL;
    
            params[2][0] = NULL;
    
    
    	execve(command, params, 0);
    	perror("minishell error");
    	
    }
    I still get the same old "bad address" returned by perror.
    Last edited by Nositi; 02-04-2008 at 10:15 AM.

  10. #10
    Registered User
    Join Date
    Nov 2006
    Location
    japan
    Posts
    126
    i tried to compile it and is says
    warning : assignment makes integer from pointer without a cast
    at every NULL line...
    Mac OS 10.6 Snow Leopard : Darwin

  11. #11
    Registered User
    Join Date
    Nov 2006
    Location
    japan
    Posts
    126
    I included:

    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>

    and changed to
    Code:
    int main
    and added
    Code:
    return 0
    and when compiling :

    Code:
    3:Desktop nacho$ gcc test.c -o test -Wall
    test.c:26: warning: assignment makes integer from pointer without a cast
    test.c:38: warning: assignment makes integer from pointer without a cast
    test.c:42: warning: assignment makes integer from pointer without a cast
    test.c:44: warning: assignment makes integer from pointer without a cast
    3:Desktop nacho$
    Im I the only one?
    It seems to be the NULL right?
    Last edited by nacho4d; 02-04-2008 at 10:29 AM.
    Mac OS 10.6 Snow Leopard : Darwin

  12. #12
    Registered User
    Join Date
    Feb 2008
    Posts
    13
    My mistake, yes that's right. I changed NULL to 0, though, and no longer get the warning. It still gives me the error though.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, "NULL" in C (as opposed to C++) is commonly declared as "(void *)0" - which means that NULL is really a pointer.

    You probably should set params[2] = NULL to indicate the end of the list. [To be really nice to the system, you should free it first - but for the purpose of testing, just ignore that - you are not freeing memory anyways at the end of main, so who cares.]

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Registered User
    Join Date
    Feb 2008
    Posts
    13
    Ahah! I feel like such an idiot! I was setting params[2][0] instead of params[2] to null. THANK YOU.

  15. #15
    Registered User
    Join Date
    Nov 2006
    Location
    japan
    Posts
    126
    I have posted something likely like a week ago but nobody could answer it... It seems that my problem is different
    Mac OS 10.6 Snow Leopard : Darwin

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 01-03-2007, 03:02 PM
  2. Is it so trouble?
    By Yumin in forum Tech Board
    Replies: 4
    Last Post: 01-30-2006, 04:10 PM
  3. trouble scanning in... and link listing
    By panfilero in forum C Programming
    Replies: 14
    Last Post: 11-21-2005, 12:58 PM
  4. problems with fork() and execve()
    By kristy in forum C Programming
    Replies: 4
    Last Post: 12-21-2003, 08:18 AM
  5. C++ program trouble
    By senrab in forum C++ Programming
    Replies: 7
    Last Post: 04-29-2003, 11:55 PM