Andre Noll wrote:
On 11:37, Lorenzo Bettini wrote:
while (read line from client(line)) {
if (first word of line is "first_cmd")
if (test_first_cmdline_cmd_parser_string(line +
strlen("first_cmd"),
&first_args_info, "first_cmd") == 0) {
do_work(&first_args_info);
continue;
}
}
This does not work for me because glibc's getopt internally keeps
a pointer to the command line during the first call and uses this
pointer during the second call. At that time the pointer is either
mhh..., no this should not happen: in the string parser generated by
gengetopt, the line you pass (i.e., its memory) is NOT passed to
getopt_long: the string parser allocates brand new memory (just to avoid
problems with this behavior of getopt_long, so your line is not touched
(you can even free it if you want).
Well, that doesn't change much because in that case getopt() keeps
a pointer to the _copy_ which was made during the previuos run, so
this only shifts the problem. Even if this memory is still available,
at the time of the second call, getopt shows random behaviour.
And yes, it _is_ happening: Here's the output of valgrind with the
current (rc2) gengetopt using the string parser:
==18153== Invalid read of size 1
==18153== at 0x412322E: (within /lib/libc-2.3.6.so.stripped)
==18153== by 0x4124410: (within /lib/libc-2.3.6.so.stripped)
==18153== by 0x41244CE: getopt_long (in /lib/libc-2.3.6.so.stripped)
==18153== by 0x804C319: grab_client_cmdline_parser_internal (in
/home/maan/para_git/para_audiod)
==18153== by 0x804CA72: grab_client_cmdline_parser_string2 (in
/home/maan/para_git/para_audiod)
==18153== by 0x804CAA6: grab_client_cmdline_parser_string (in
/home/maan/para_git/para_audiod)
==18153== by 0x8052B22: grab_client_new (grab_client.c:244)
==18153== by 0x804F3EC: com_grab (audiod.c:1346)
==18153== by 0x805051A: audiod_mainloop (audiod.c:1471)
==18153== by 0x8050DFB: main (audiod.c:1693)
==18153== Address 0x424DC92 is 2 bytes inside a block of size 3 free'd
==18153== at 0x401C431: free (vg_replace_malloc.c:235)
==18153== by 0x804C19F: grab_client_cmdline_parser_free (in
/home/maan/para_git/para_audiod)
==18153== by 0x804C43B: grab_client_cmdline_parser_internal (in
/home/maan/para_git/para_audiod)
==18153== by 0x804CA72: grab_client_cmdline_parser_string2 (in
/home/maan/para_git/para_audiod)
==18153== by 0x804CAA6: grab_client_cmdline_parser_string (in
/home/maan/para_git/para_audiod)
==18153== by 0x8052B22: grab_client_new (grab_client.c:244)
==18153== by 0x804F3EC: com_grab (audiod.c:1346)
==18153== by 0x805051A: audiod_mainloop (audiod.c:1471)
==18153== by 0x8050DFB: main (audiod.c:1693)
The same kind of invalid access happens also without the string parser.
==18054== Invalid read of size 1
==18054== at 0x412322E: (within /lib/libc-2.3.6.so.stripped)
==18054== by 0x4124410: (within /lib/libc-2.3.6.so.stripped)
==18054== by 0x41244CE: getopt_long (in /lib/libc-2.3.6.so.stripped)
==18054== by 0x804C2D4: grab_client_cmdline_parser2 (in
/home/maan/para_git/para_audiod)
==18054== by 0x804C816: grab_client_cmdline_parser (in
/home/maan/para_git/para_audiod)
==18054== by 0x80528AB: grab_client_new (grab_client.c:250)
==18054== by 0x804F164: com_grab (audiod.c:1345)
==18054== by 0x80508D6: main (audiod.c:1454)
==18054== Address 0x424993A is 2 bytes inside a block of size 3 free'd
==18054== at 0x401C431: free (vg_replace_malloc.c:235)
==18054== by 0x8052719: gc_close (grab_client.c:133)
==18054== by 0x8052B1F: close_filter_callback (filter_chain.c:55)
==18054== by 0x8052C20: filter_io (filter_chain.c:91)
==18054== by 0x80506A3: main (audiod.c:1031)
And optind = 0 makes it go away.
I'm really sad to hear this :-(
this optind = 0 would be the solution but only for the implementation of
getopt.c in this version of the glibc library and thus it is not safe
(even because it is not documented, you have to look in the sources; on
the contrary in the documentation it is explicitly stated that it must
be initialized to 1, thus we definitely cannot rely on this: future
releases may not have this).
what I would like to do first is to try your program in this valgrind
situation problem... it might be a problem in the dynamic list
allocation performed by the code produced by gengetopt. In order to do
this I'd need the command line to reproduce exactly this behavior (and
be sure we use the same version of paraslash).
If the problem still exists I see no other solution than to pass to
getopt_long ONLY static memory (of course this would be handled entirely
within the code generated by gengetopt thus it would be transparent to
the user).
I still believe it's only a matter of using dynamic memory (that might
be deallocated on the next run of getopt_long). If the memory is static
the problem should not come up.
Notice that also the code of the confparser relies on dynamic memory and
this problem never showed up... that gives me some hope.
I hope to hear from you soon
Lorenzo
--
+-----------------------------------------------------+
| Lorenzo Bettini ICQ# lbetto, 16080134 |
| PhD in Computer Science |
| Dip. Sistemi e Informatica, Univ. di Firenze |
| Florence - Italy (GNU/Linux User # 158233) |
| Home Page : http://www.lorenzobettini.it |
| http://music.dsi.unifi.it XKlaim language |
| http://www.purplesucker.com Deep Purple Cover Band |
| http://www.gnu.org/software/src-highlite |
| http://www.gnu.org/software/gengetopt |
| http://www.lorenzobettini.it/software/gengen |
| http://www.lorenzobettini.it/software/doublecpp |
+-----------------------------------------------------+
_______________________________________________
Help-gengetopt mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/help-gengetopt