I'm trying to use the GNU getopt
function parse some command line arguments in my C program. Say I make the following call:
./my_program -E 16 -t path/to/file
My current expectation is that if I have the following code:
long arg;
int e_val;
char *t_str;
while ((arg = getopt(argc, argv, "E:t:")) != -1) {
switch(arg) {
case 'E':
e_val = *optarg; // e_val = 16
break;
case 't':
t_str = optarg;
break;
}
}
then e_val
will equal 16
and t_str
will point to path/to/file
.
However, I can't seem to figure out how to access the actual value for these arguments. By the time I get to assigning e_val
in case 'E'
, optarg
is still a null pointer:
Starting program: /stack/overflow/example -E 16 -t stackoverflow
Breakpoint 1, get_arguments (argc=5, argv=0x7fffffffe318) at stack_overflow.c:233
233 while ((arg = getopt(argc, argv, "E:t:")) != -1)
(gdb) n
235 switch (arg)
(gdb)
254 e_val = *optarg;
(gdb) p optarg
$6 = 0x0
(gdb) x/1xw optarg
0x0: Cannot access memory at address 0x0
(gdb) p /x arg
$7 = 0x45 // ASCII for 'E'
Why is optarg not getting set? And if optarg
isn't the value I'm supposed to be using to get the 16
following E
, then what should I be using?
As a final note, I briefly stepped through getopt
with gdb and it looks like it isn't setting the extern optarg
variable for some reason.
Backtrace:
#0 _getopt_internal (argc=<value optimized out>, argv=<value optimized out>, optstring=<value optimized out>,
longopts=<value optimized out>, longind=<value optimized out>, long_only=<value optimized out>, posixly_correct=0)
at getopt.c:1135
#1 0x00007ffff7894138 in getopt (argc=<value optimized out>, argv=<value optimized out>, optstring=<value optimized out>)
at getopt.c:1145
#2 0x0000000000400cd6 in get_arguments (argc=5, argv=0x7fffffffe318) at stackoverflow.c:233
#3 0x0000000000400875 in main (argc=5, argv=0x7fffffffe318) at stackoverflow.c:82
Code being executed:
(gdb) l
1130
1131 result = _getopt_internal_r (argc, argv, optstring, longopts,
1132 longind, long_only, &getopt_data,
1133 posixly_correct);
1134
1135 optind = getopt_data.optind;
1136 optarg = getopt_data.optarg;
1137 optopt = getopt_data.optopt;
1138
1139 return result;
optarg
not getting set:
(gdb) n
1136 optarg = getopt_data.optarg;
(gdb)
1135 optind = getopt_data.optind;
(gdb) p optarg
$10 = 0x0
(gdb) p getopt_data.optarg
$11 = 0x7fffffffe60d "16"
Note that optarg
not being set here is not due to compiler optimization. I can step all the way through back to my function and it stays null.
This isn't truly an answer, but it is too big to be a comment.
This code compiles cleanly under stringent compilation options:
Compile and run:
Testing on an Ubuntu 14.04 LTS derivative with GCC 5.1.0. So, on the face of it, the code is approximately correct. That in turn suggests that the problem is in the surrounding code. Is there any chance that something you're linking with is also defining
optarg
?What do you get if you take the code I've just shown and run it? If it works but your much bigger program doesn't, then there's something in your bigger program that is causing the trouble, somehow.