Hi, Please see the following. If someone sets CCACHE_DIR to an empty / null string, ccache -s results in a segmentation fault. It seems create_parent_dirs() is called infinite times since it seems to create a parent of "/" infinite times and stack overflows, or something. This happens with git trunk (don't be misled by the directory name below in the shell prompt.) ishikawa@ip030:/home/ishikawa/repos/ccache-gsplit-dwarf-support$ export CCACHE_DIR= ishikawa@ip030:/home/ishikawa/repos/ccache-gsplit-dwarf-support$ ./ccache -s Segmentation fault ishikawa@ip030:/home/ishikawa/repos/ccache-gsplit-dwarf-support$ gdb ./ccache GNU gdb (Debian 7.7.1+dfsg-3) 7.7.1 Copyright (C) 2014 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./ccache...done. (gdb) run -s Starting program: /home/ishikawa/repos/ccache-gsplit-dwarf-support/ccache -s Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7591ca5 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 (gdb) where #0 0x00007ffff7591ca5 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 #1 0x00007ffff7593e20 in malloc () from /lib/x86_64-linux-gnu/libc.so.6 #2 0x00007ffff759978a in strdup () from /lib/x86_64-linux-gnu/libc.so.6 #3 0x0000000000409019 in x_strdup (s=s@entry=0x5a1d30 "/ccache.conf") at util.c:620 #4 0x0000000000409376 in dirname (path=path@entry=0x5a1d30 "/ccache.conf") at util.c:809 #5 0x00000000004093d0 in create_parent_dirs ( path=path@entry=0x5a1d30 "/ccache.conf") at util.c:473 #6 0x000000000040941d in create_parent_dirs ( path=path@entry=0x5a1d10 "/ccache.conf") at util.c:483 #7 0x000000000040941d in create_parent_dirs ( path=path@entry=0x5a1cf0 "/ccache.conf") at util.c:483 #8 0x000000000040941d in create_parent_dirs ( path=path@entry=0x5a1cd0 "/ccache.conf") at util.c:483 #9 0x000000000040941d in create_parent_dirs ( path=path@entry=0x5a1cb0 "/ccache.conf") at util.c:483 #10 0x000000000040941d in create_parent_dirs ( path=path@entry=0x5a1c90 "/ccache.conf") at util.c:483 ... well, no end in sight: I had to suspend gdb and killed it. ... I set a break point and tried again. Type "apropos word" to search for commands related to "word". Command name abbreviations are allowed if unambiguous. (gdb) help set environment Set environment variable value to give the program. Arguments are VAR VALUE where VAR is variable name and VALUE is value. VALUES of environment variables are uninterpreted strings. This does not affect the program until the next "run" command. (gdb) break create_parent_dirs Breakpoint 1 at 0x409460: file util.c, line 470. (gdb) set CCACHE_DIR No symbol "CCACHE_DIR" in current context. (gdb) set environment CCACHE_DIR Undefined command: "setenvironment". Try "help". (gdb) set environment CCACHE_DIR Setting environment variable "CCACHE_DIR" to null value. (gdb) run -s Starting program: /home/ishikawa/repos/ccache-gsplit-dwarf-support/ccache -s Breakpoint 1, create_parent_dirs (path=path@entry=0x41f410 "/ccache.conf") at util.c:470 470 { (gdb) list 465 } 466 467 /* Create directories leading to path. Returns 0 on success, otherwise -1. */ 468 int 469 create_parent_dirs(const char *path) 470 { 471 struct stat st; 472 int res; 473 char *parent = dirname(path); 474 (gdb) where #0 create_parent_dirs (path=path@entry=0x41f410 "/ccache.conf") at util.c:470 #1 0x0000000000404115 in create_initial_config_file ( path=0x41f410 "/ccache.conf", conf=0x41f030) at ccache.c:2973 #2 initialize () at ccache.c:3058 #3 0x0000000000407625 in ccache_main_options (argv=<optimized out>, argc=<optimized out>) at ccache.c:3448 #4 ccache_main (argc=2, argv=0x7fffffffd9b8) at ccache.c:3484 #5 0x00007ffff7539b45 in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6 #6 0x0000000000403eee in _start () (gdb) up #1 0x0000000000404115 in create_initial_config_file ( path=0x41f410 "/ccache.conf", conf=0x41f030) at ccache.c:2973 2973 if (create_parent_dirs(path) != 0) { (gdb) list 2968 uint64_t max_size; 2969 char *stats_dir; 2970 FILE *f; 2971 struct stat st; 2972 2973 if (create_parent_dirs(path) != 0) { 2974 return; 2975 } 2976 2977 stats_dir = format("%s/0", conf->cache_dir); (gdb) print path $1 = 0x41f410 "/ccache.conf" (gdb) quit A debugging session is active. I think special handling of cases - where the directory is "/", or - where the directory is write protected may be required to here. (I hate to think what would have happened if I run ccache with null CCACHE_DIR in superuser account by mistake ...) Or simply barfing out "CCACHE_DIR is null. Set it to a proper value." and bailing out is a way to go. TIA
Fixed in 136d76854c93a36491a0906e835490ad6927cf47 on master.
Included in v3.2.