Thread: why was the VAR 'optind' never changed in initdb?
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 />
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
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
<div class="gmail_quote">2012/4/9 Andrew Dunstan <span dir="ltr"><<a href="mailto:andrew@dunslane.net">andrew@dunslane.net</a>></span><br/><blockquote class="gmail_quote" style="margin:00 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br /><br /> On 04/09/2012 07:38 AM,Clover White wrote:<br /><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br /> I'm debugging initdb using gdb.<br /> I found that I could not step in the function getopt_longin line 2572 in initdb.c.<br /> I also found that the value of VAR optind never be changed. VAR optind is alwaysequal to 1 but how could 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 /><br /></blockquote><br /></div>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.<br/><br /> cheers<br /><font color="#888888"><br /> andrew<br /></font></blockquote></div><br />Hi, this is my story,it may be a little long :)<br /> I mistook the parameter -W of initdb at the first time and used it like this:<br/> initdb -U pgsql -W 12345 -D /home/pgsql/pg_data<br /> And I found the database was not created in the rightdirectory, but I could not find a log file to find out why.<br /> So, I debug initdb and found out I have mistook theparameter -W, I should use it like this:<br /> initdb -U pgsql -W -D /home/pgsql/pg_data<br /> <br /> however,when I debug initdb.c, VAR optind was supported to increased after getopt_long pasered every parameter,<br /> butit was alway equal to 1.<br /> <br /> And there is a segment of initdb.c.<br /> if (optind < argc)<br /> {<br /> do something statement<br /> } <br /> <br /> I print the value of optind and argc:<div class="im"><br/> (gdb) p optind<br /> $11 = 1<br /> (gdb) p argc<br /> $12 = 6<br /> <br /></div> optind isobvious less than argc, but the statement above do not excute at all.<br /> <br /> QUESTION:<br /> 1.why does thestatement above not excute?<br /> 2.why is optind always equal to 1? <br clear="all" /><br />-- <br />Clover White<br/><br />
<div class="gmail_quote">2012/4/9 Robert Haas <span dir="ltr"><<a href="mailto:robertmhaas@gmail.com">robertmhaas@gmail.com</a>></span><br/><blockquote class="gmail_quote" style="margin:00 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Mon, Apr 9, 2012 at 7:38 AM, CloverWhite <<a href="mailto:mywhiteclover@gmail.com">mywhiteclover@gmail.com</a>> wrote:<br /> > Hi,<br /> > I'm debugging initdb using gdb.<br /> > I found that I could not step in the function getopt_long in line 2572in<br /> > initdb.c.<br /> > I also found that the value of VAR optind never be changed. VAR optind is<br />> always equal to 1 but how could optind be larger than the value of argc(the<br /> > value of argc is 6) in line2648 and 2654.<br /><br /></div>Read the man page for getopt_long. It changes the global variable optind.<br /><br />It's a silly interface, but also a long and hallowed UNIX tradition,<br /> so we're stuck with it.<br /><font color="#888888"><br/> --<br /> Robert Haas<br /> EnterpriseDB: <a href="http://www.enterprisedb.com" target="_blank">http://www.enterprisedb.com</a><br/> The Enterprise PostgreSQL Company<br /></font></blockquote></div><br/>Thanks Robert. I have read the man page for getopt_long and optind. they are in the sameman page.<br /><br />but i still could not understand why optind always equal to 1 when I gdb initdb and print optind?<br/> Was optind supported to increased after getopt_long pasered every parameter?<br clear="all" /><br />-- <br/>Clover White<br /><br />
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
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
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 >