首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >出口分段故障(EXIT_FAILURE),但没有错误(EXIT_FAILURE,.)

出口分段故障(EXIT_FAILURE),但没有错误(EXIT_FAILURE,.)
EN

Stack Overflow用户
提问于 2013-12-18 21:14:19
回答 1查看 1.7K关注 0票数 0

我在程序(来源在这里)中使用来源在这里,在给出无效的长选项(--stack-overflow)时测试它的行为时,我得到:

代码语言:javascript
复制
[marcoms@baguette16 btcwatch]$ ./btcwatch --stack-overflow
Segmentation fault (core dumped)

对于上下文,它在getopt_long()循环中,即:

代码语言:javascript
复制
while((opt = getopt_long(argc,
                         argv,
                         OPTSTRING,
                         long_options,
                         &longopt_i)) != -1)
{

    ...

    default:
        exit(EXIT_FAILURE);
        break;

而不是:

代码语言:javascript
复制
error(EXIT_FAILURE, 0, "unknown option !?");

( exit()代码SIGSEGVs)

最疯狂的是,default 不应该是(根据gdb),也不应该被执行。

gdb显示它在getopt_long()调用时立即崩溃,

代码语言:javascript
复制
(gdb) start --stack-overflow    
Temporary breakpoint 1, main (argc=2, argv=0x7fffffffe598) at src/main.c:96
96      btcdbg("main()");
(gdb) s
btcdbg (fmt=0x403260 "main()") at src/btcutil.c:50
50  }
(gdb) 
main (argc=2, argv=0x7fffffffe598) at src/main.c:118
118     const struct option long_options[] = {
(gdb) 
211     api_err.err = false;
(gdb) 
212     colour = false;
(gdb) 
213     found_path = false;
(gdb) 
214     fp = NULL;
(gdb) 
215     n = 1.0;
(gdb) 
216     newlp = NULL;
(gdb) 
217     pn = argv[0];
(gdb) 
218     reverse = false;
(gdb) 
219     verbose = false;
(gdb) 
221     strcpy(currcy, "USD");
(gdb) 
223     setlocale(LC_ALL, "");  // sets the locale to the system's default
(gdb) 
225     while((opt = getopt_long(
(gdb) 

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7643e2c in __strncmp_sse2 () from /usr/lib/libc.so.6

但是,当它使用error()而不是exit()运行时,它通常进行如下操作:

代码语言:javascript
复制
(gdb) start --stack-overflow
Temporary breakpoint 1, main (argc=2, argv=0x7fffffffe598) at src/main.c:96
96      btcdbg("main()");
(gdb) s
btcdbg (fmt=0x4032a0 "main()") at src/btcutil.c:50
50  }
(gdb) 
main (argc=2, argv=0x7fffffffe598) at src/main.c:118
118     const struct option long_options[] = {
(gdb) 
211     api_err.err = false;
(gdb) 
212     colour = false;
(gdb) 
213     found_path = false;
(gdb) 
214     fp = NULL;
(gdb) 
215     n = 1.0;
(gdb) 
216     newlp = NULL;
(gdb) 
217     pn = argv[0];
(gdb) 
218     reverse = false;
(gdb) 
219     verbose = false;
(gdb) 
221     strcpy(currcy, "USD");
(gdb) 
223     setlocale(LC_ALL, "");  // sets the locale to the system's default
(gdb) 
225     while((opt = getopt_long(
(gdb) 
/home/marcoms/code/btcwatch/./btcwatch: unrecognized option '--stack-overflow'
232         btcdbg("got option '%c'", opt);
(gdb) 
btcdbg (fmt=0x4032a8 "got option '%c'") at src/btcutil.c:50
50  }
(gdb) 
main (argc=2, argv=0x7fffffffe598) at src/main.c:233
233         switch(opt) {
(gdb) 
236                 help(pn, optarg);
(gdb) 
help (prog_nm=0x7fffffffe8d8 "/home/marcoms/code/btcwatch/./btcwatch", topic=0x0) at src/btcutil.c:69
69      btcdbg("help()");
(gdb) 
btcdbg (fmt=0x403bfc "help()") at src/btcutil.c:50
50  }
(gdb) 
help (prog_nm=0x7fffffffe8d8 "/home/marcoms/code/btcwatch/./btcwatch", topic=0x0) at src/btcutil.c:71
71      char currcies[][3 + 1] = {
(gdb) 
101     char topics[][16] = {
(gdb) 
117     if(!topic) {
(gdb) 
118         bputs("Usage: "); bputs(prog_nm); bputs(" [OPTION]\n");
(gdb) 
Usage: /home/marcoms/code/btcwatch/./btcwatch [OPTION]
119         bputs(
(gdb) 
Get and monitor Bitcoin trade information

Options:       Long options:
  -C             --compare              comare current price with stored price
  -S             --store                store current price
  -a             --all                  equivalent to -pbs
  -b             --buy                  print buy price
  -c CURRENCY    --currency=CURRENCY    set conversion currency
  -n AMOUNT      --amount=AMOUNT        set the amount to convert
  -o             --colour, --color      enable use of colour
  -p             --ping                 check for a successful JSON response
  -r             --reverse              convert currency to Bitcoin
  -s             --sell                 print sell price
  -v             --verbose              increase verbosity

  -h [topic]     --help[=topic]         print this help, or help designated by topic
                                        use --help=topics for available topics
  -V             --version              print version number

Report bugs to marco@scannadinari.co.uk
btcwatch home page: <https://github.com/marcoms/btcwatch>
142         exit(EXIT_SUCCESS);
(gdb) 
[Inferior 1 (process 25752) exited normally]

在这一点上,我真的很困惑。是什么导致了分段故障?当然,我可以使用error()代替退出,但这是令人难以置信的不满意。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-18 22:10:32

问题是,您的选项数组没有正确终止:

代码语言:javascript
复制
    const struct option long_options[] = {
            // ...
            // This is the last element
            {
                    .name = "verbose",
                    .has_arg = no_argument,
                    .flag = NULL,
                    .val = 'v'
            }
    };

getopt_long(3)要求选项数组以所有零结尾,以便它知道数组有多大--请注意,您从未实际将数组大小传递给getopt_long。所以现在发生的是,它走过数组的尽头,寻找终结者,然后它开始读取超出范围的内存,这正是瓦伦所抱怨的。未定义的行为结果。

修复方法很简单:

代码语言:javascript
复制
const struct option long_options[] = {
            // ...
            {
                    .name = "verbose",
                    .has_arg = no_argument,
                    .flag = NULL,
                    .val = 'v'
            },

            // Array terminator
            {0, 0, 0, 0}
};
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20668530

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档