0
votes

As per K&R, his explanation of echo program: echo hello world "By convention, argv[0] is the name by which the program was invoked, so argc is at least 1. If the argc is 1, there are no command-line arguments after the program name. In the example above, argc is 3, and argv[0], argv[1], and argv[2] are "echo", "hello", and "world" respectively. The first optional argument is argv[1] and the last is argv[argc-1]."

But, when debugging the program, using gdb, I can see the following:

(gdb) p argv[0]
$2 = 0x7efff85a "/home/pi/new/a.out"
(gdb) p argv[1]
$3 = 0x0
(gdb) p argv[2]
$4 = 0x7efff86d "LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc"...
(gdb) p *argv[0]
    $5 = 47 '/'

Ex 1:

#include <stdio.h>
int main(int argc, char *argv[])
{
    int i;
    while (--argc>0)
        printf("%s%s",*++argv,(argc>1)?" ":"");
    printf("\n");
    return 0;
}

For the code example above, when compiling and executing as the below:

pi@readonly:~/new$ cc -g echo.c
pi@readonly:~/new$ a.out hello world
hello world

Debug using gdb:

Snippet 1:

(gdb) p &*argv
$11 = (char **) 0x7efff744
(gdb) p &**argv
$12 = 0x7efff85a "/home/pi/new/a.out"
(gdb) p argv
$13 = (char **) 0x7efff744
(gdb) p &argv
$14 = (char ***) 0x7efff5e0
(gdb) p &argv[0]
$15 = (char **) 0x7efff744
(gdb) p argv[0]
$16 = 0x7efff85a "/home/pi/new/a.out"

Snippet 2:

(gdb) p argv[3]
$22 = 0x7efffe5a "_=/usr/bin/gdb"
(gdb) p argv[4]
$23 = 0x7efffe69 "LANG=en_GB.UTF-8"
(gdb) p &argv[3]
$24 = (char **) 0x7efff754

Questions:

• Snippet 1:

  1. Am I understand it correctly, that 0x7efff85a is the hexadecimal value of the string "/home/pi/new/a.out"? If yes, how it has been obtained? In other words, has it been obtained by using, for instance, atoi() function?

• Snippet 3:

  1. Am I understand it correctly, that, _=/usr/bin/gdb is converted into 0x7efffe5a?

  2. Also, there is some predefined values being set to the array argv, because, in case, nothing has been input, it is there. Where can I read about this predefined values? Is it implementation-defined? For instance, on windows, using Eclipse, or other IDEs, would it give different but, predefined values set as well for argv[] array?

3
No, they are addresses (pointers). Look at the type you're trying to print. - Sourav Ghosh
You need to use the set args command within GDB to set the program's command-line arguments. - Ian Abbott
or specify them when you "run" it ie "run hello world" - Chris Turner
That argv[0] is /home/pi/new/a.out is because you did not rename your program to echo. Although I must confess that K&R don't mention the path, or maybe that got added later in the definition of argv[0]. - Paul Ogilvie
You cannot access argv[2] and beyond if argc is 1. You cannot access argv[3] if argc is 2, etc. Any such value you obtain from the debugger is meaningless. - n. 1.8e9-where's-my-share m.

3 Answers

0
votes

Snippet 1) 0x7efff85a is a pointer to the string "/home/pi/new/a.out" for this instance of the program.

Snippet 2) 0x7efffe5a is a pointer to the string "_=/usr/bin/gdb" for this particular instance, but you shouldn't rely on argv[argc+1] onwards pointing to anything in particular.

0
votes

Note that the full definition of main is:

int main(int argc, char *argv[], char *envp[])

This means that following the last argv[] follow the environment variables.

0
votes

You are modifying argv in the loop:

while (--argc>0)
        printf("%s%s",*++argv,(argc>1)?" ":"");

so that observing it after don't give you what you think! You are overflowing the array and access the environment array...

Either observe argv before the loop or at least store its original value somewhere to observe it after... As you didn't tell us what was the exact (all commands!) gdb session you made, we cannot help you further.