Обсуждение: why was the VAR 'optind' never changed in initdb?

Поиск
Список
Период
Сортировка

why was the VAR 'optind' never changed in initdb?

От
Clover White
Дата:
Hi,<br />  I'm debugging initdb using gdb.<br />  I found that I could not step in the function getopt_long in line
2572in initdb.c.<br />  I also found that the value of VAR optind never be changed. VAR optind is always equal to 1 but
howcould optind be larger than the value of argc(the value of argc is 6) in line 2648 and 2654.<br /><br />I was so
confused.Could someone give me some help? Thank you~<br /><br />here is my configure:<br />./configure CFLAGS=-O0
--enable-debug--enable-depend --enable-cassert --prefix=/home/pgsql/pgsql<br /><br />follows is my debug log by gdb:<br
/><br/>[pgsql@vmlinux postgresql-9.1.2]$ gdb initdb<br />GNU gdb Red Hat Linux (6.3.0.0-1.63rh)<br />Copyright 2004
FreeSoftware Foundation, Inc.<br />GDB is free software, covered by the GNU General Public License, and you are<br />
welcometo change it and/or distribute copies of it under certain conditions.<br />Type "show copying" to see the
conditions.<br/>There is absolutely no warranty for GDB.  Type "show warranty" for details.<br /> This GDB was
configuredas "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".<br /><br />(gdb)
setargs -U pgsql -W -D /home/pgsql/pg_data<br />(gdb) b main<br />Breakpoint 1 at 0x804d133: file initdb.c, line
2553.<br/> (gdb) b 2572<br />Breakpoint 2 at 0x804d20c: file initdb.c, line 2572.<br />(gdb) run<br />Starting program:
/home/pgsql/pgsql/bin/initdb-U pgsql -W -D /home/pgsql/pg_data<br /><br />Breakpoint 1, main (argc=6, argv=0xbfec0ad4)
atinitdb.c:2553<br /> 2553            progname = get_progname(argv[0]);<br />(gdb) c<br />Continuing.<br /><br
/>Breakpoint2, main (argc=6, argv=0xbfec0ad4) at initdb.c:2572<br />2572            while ((c = getopt_long(argc, argv,
"dD:E:L:nU:WA:sT:X:",long_options, &option_index)) != -1)<br /> (gdb) p optind<br />$1 = 1<br />(gdb) s<br
/>2574                   switch (c)<br />(gdb) n<br />2589                                    username =
xstrdup(optarg);<br/>(gdb) <br />2590                                    break;<br />(gdb) p optind<br /> $2 = 1<br
/>(gdb)n<br /><br />Breakpoint 2, main (argc=6, argv=0xbfec0ad4) at initdb.c:2572<br />2572            while ((c =
getopt_long(argc,argv, "dD:E:L:nU:WA:sT:X:", long_options, &option_index)) != -1)<br />(gdb) p optind<br /> $3 =
1<br/>(gdb) n<br />2574                    switch (c)<br />(gdb) p optind<br />$4 = 1<br />(gdb) n<br
/>2586                                   pwprompt = true;<br />(gdb) <br />2587                                   
break;<br/>(gdb) <br /><br />Breakpoint 2, main (argc=6, argv=0xbfec0ad4) at initdb.c:2572<br />2572            while
((c= getopt_long(argc, argv, "dD:E:L:nU:WA:sT:X:", long_options, &option_index)) != -1)<br />(gdb) p optind<br />$5
=1<br /> (gdb) n<br />2574                    switch (c)<br />(gdb) <br />2580                                   
pg_data= xstrdup(optarg);<br />(gdb) p optarg<br />$6 = 0x0<br />(gdb) n<br />2581                                   
break;<br/> (gdb) p optarg<br /> $7 = 0x0<br />(gdb) n<br /><br />Breakpoint 2, main (argc=6, argv=0xbfec0ad4) at
initdb.c:2572<br/>2572            while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:sT:X:", long_options,
&option_index))!= -1)<br /> (gdb) p pg_data<br /> $8 = 0x9d328e8 "/home/pgsql/pg_data"<br />(gdb) n<br
/>2648           if (optind < argc)<br />(gdb) p optind<br />$9 = 1<br />(gdb) p argc<br />$10 = 6<br />(gdb) n<br
/>2654           if (optind < argc)<br />(gdb) p optind<br /> $11 = 1<br />(gdb) p argc<br />$12 = 6<br />(gdb) n<br
/>2663           if (pwprompt && pwfilename)<br />(gdb) <br clear="all" /><br />-- <br />Clover White<br /><br
/>

Re: why was the VAR 'optind' never changed in initdb?

От
Andrew Dunstan
Дата:

On 04/09/2012 07:38 AM, Clover White wrote:
> Hi,
>   I'm debugging initdb using gdb.
>   I found that I could not step in the function getopt_long in line 
> 2572 in initdb.c.
>   I also found that the value of VAR optind never be changed. VAR 
> optind is always equal to 1 but how could optind be larger than the 
> value of argc(the value of argc is 6) in line 2648 and 2654.
>
> I was so confused. Could someone give me some help? Thank you~
>
>

Why do you expect it to be? Perhaps if you tell us what problem you're 
actually trying to solve we can help you better.

cheers

andrew


Re: why was the VAR 'optind' never changed in initdb?

От
Robert Haas
Дата:
On Mon, Apr 9, 2012 at 7:38 AM, Clover White <mywhiteclover@gmail.com> wrote:
> Hi,
>   I'm debugging initdb using gdb.
>   I found that I could not step in the function getopt_long in line 2572 in
> initdb.c.
>   I also found that the value of VAR optind never be changed. VAR optind is
> always equal to 1 but how could optind be larger than the value of argc(the
> value of argc is 6) in line 2648 and 2654.

Read the man page for getopt_long.  It changes the global variable optind.

It's a silly interface, but also a long and hallowed UNIX tradition,
so we're stuck with it.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


Re: why was the VAR 'optind' never changed in initdb?

От
Clover White
Дата:
2012/4/9 Andrew Dunstan <andrew@dunslane.net>


On 04/09/2012 07:38 AM, Clover White wrote:
Hi,
 I'm debugging initdb using gdb.
 I found that I could not step in the function getopt_long in line 2572 in initdb.c.
 I also found that the value of VAR optind never be changed. VAR optind is always equal to 1 but how could optind be larger than the value of argc(the value of argc is 6) in line 2648 and 2654.

I was so confused. Could someone give me some help? Thank you~



Why do you expect it to be? Perhaps if you tell us what problem you're actually trying to solve we can help you better.

cheers

andrew

Hi, this is my story, it may be a little long :)
  I mistook the parameter -W of initdb at the first time and used it like this:
    initdb -U pgsql -W 12345 -D /home/pgsql/pg_data
  And I found the database was not created in the right directory, but I could not find a log file to find out why.
  So, I debug initdb and found out I have mistook the parameter -W, I should use it like this:
    initdb -U pgsql -W -D /home/pgsql/pg_data
   
  however, when I debug initdb.c, VAR optind was supported to increased after getopt_long pasered every parameter,
  but it was alway equal to 1.
 
  And there is a segment of initdb.c.
    if (optind < argc)
      {
          do something statement
      } 
 
  I print the value of optind and argc:

    (gdb) p optind
    $11 = 1
    (gdb) p argc
    $12 = 6
 
  optind is obvious less than argc, but the statement above do not excute at all.
 
  QUESTION:
    1.why does the statement above not excute?
    2.why is optind always equal to 1?

--
Clover White

Re: why was the VAR 'optind' never changed in initdb?

От
Clover White
Дата:
2012/4/9 Robert Haas <robertmhaas@gmail.com>
On Mon, Apr 9, 2012 at 7:38 AM, Clover White <mywhiteclover@gmail.com> wrote:
> Hi,
>   I'm debugging initdb using gdb.
>   I found that I could not step in the function getopt_long in line 2572 in
> initdb.c.
>   I also found that the value of VAR optind never be changed. VAR optind is
> always equal to 1 but how could optind be larger than the value of argc(the
> value of argc is 6) in line 2648 and 2654.

Read the man page for getopt_long.  It changes the global variable optind.

It's a silly interface, but also a long and hallowed UNIX tradition,
so we're stuck with it.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

Thanks Robert. I have read the man page for getopt_long and optind. they are in the same man page.

but i still could not understand why optind always equal to 1 when I gdb initdb and print optind?
Was optind  supported to increased after getopt_long pasered every parameter?

--
Clover White

Re: why was the VAR 'optind' never changed in initdb?

От
Andrew Dunstan
Дата:

On 04/09/2012 12:36 PM, Clover White wrote:
> 2012/4/9 Andrew Dunstan <andrew@dunslane.net <mailto:andrew@dunslane.net>>
>
>
>
>     On 04/09/2012 07:38 AM, Clover White wrote:
>
>         Hi,
>          I'm debugging initdb using gdb.
>          I found that I could not step in the function getopt_long in
>         line 2572 in initdb.c.
>          I also found that the value of VAR optind never be changed.
>         VAR optind is always equal to 1 but how could optind be larger
>         than the value of argc(the value of argc is 6) in line 2648
>         and 2654.
>
>         I was so confused. Could someone give me some help? Thank you~
>
>
>
>     Why do you expect it to be? Perhaps if you tell us what problem
>     you're actually trying to solve we can help you better.
>
>     cheers
>
>     andrew
>
>
> Hi, this is my story, it may be a little long :)
>   I mistook the parameter -W of initdb at the first time and used it 
> like this:
>     initdb -U pgsql -W 12345 -D /home/pgsql/pg_data
>   And I found the database was not created in the right directory, but 
> I could not find a log file to find out why.
>   So, I debug initdb and found out I have mistook the parameter -W, I 
> should use it like this:
>     initdb -U pgsql -W -D /home/pgsql/pg_data


This is arguably a bug. Maybe we should change this:
     if (optind < argc)     {         pg_data = xstrdup(argv[optind]);         optind++;     }

to
     if (optind < argc && strlen(pg_data) == 0)     {         pg_data = xstrdup(argv[optind]);         optind++;     }

i.e. we'd forbid:
    initdb -D foo bar


which the OP's error more or less devolves to.


cheers

andrew


Re: why was the VAR 'optind' never changed in initdb?

От
Tom Lane
Дата:
Andrew Dunstan <andrew@dunslane.net> writes:
> i.e. we'd forbid:
>      initdb -D foo bar
> which the OP's error more or less devolves to.

Makes sense.  Don't we have a similar issue with psql, pg_dump, etc?
        regards, tom lane


Re: why was the VAR 'optind' never changed in initdb?

От
Andrew Dunstan
Дата:

On 04/09/2012 01:38 PM, Tom Lane wrote:
> Andrew Dunstan<andrew@dunslane.net>  writes:
>> i.e. we'd forbid:
>>       initdb -D foo bar
>> which the OP's error more or less devolves to.
> Makes sense.  Don't we have a similar issue with psql, pg_dump, etc?

From a quick survey:

psql won't override a dbname or username set explicitly with an option 
argument.

pg_dump doesn't have an option argument to set the dbname.

pg_restore doesn't have an option argument to set the input file name.

vacuumdb, clusterdb, reindexdb, createlang and droplang all need 
remediation. createuser and dropuser look ok.

pg_ctl seems a mess :-( I'll need to look at it closer.


cheers

andrew




>             regards, tom lane
>