hi, know this is a sort of an inactive list, so i'm sorry for necroposting into a void.
still, we see cscope aborts at exit due to myexit() recursive call. we have 2 cases, see backtraces in bugzillas mentioned: https://bugzilla.redhat.com/show_bug.cgi?id=2269887 - report 1 and a research https://bugzilla.redhat.com/show_bug.cgi?id=2256515 - report 2 https://src.fedoraproject.org/rpms/cscope/c/a4d105ed18317c43e41fd20934509f8f250edc68?branch=rawhide - an ugly fix so a research shows that the cscope process attempted a normal exit (by "q" or Ctrl-D) calling myexit(0). in the middle of it a signal SIGHUP handler was called, which is myexit() itself. then glibc detects a double-free condition in __GI___libc_free() while performing fclose(refsfound). then glibc aborts the process with __GI_abort() and the "free(): double free detected in tcache 2" message. backtraces we have are: main.c:847 in main(): /* normal quit */ myexit(0); -> main.c:1079 in myexit(sig=0): freefilelist(); -> dir.c:727 in in freefilelist(): free(srcfiles[--nsrcfiles]); -> malloc.c:3352 in __GI___libc_free() -> <signal handler called> -> main.c:1062 in myexit (sig=1 SIGHUP ): fclose(refsfound); -> iofclose.c:74 in _IO_new_fclose() -> ... -> malloc.c:3391 in __GI___libc_free() -> malloc_printerr("free(): double free detected in tcache 2") -> __GI_abort() main.c:847 in main(): /* normal quit */ myexit(0); -> main.c:1066 in myexit(sig=0): unlink(temp1); -> unlink.c:28 __unlink (name=<temp1> "/tmp/cscope.699047/cscope.1"); -> <signal handler called> -> main.c:1062 in myexit (sig=1 SIGHUP ): fclose(refsfound); -> iofclose.c:74 in _IO_new_fclose() -> ... -> malloc.c:3391 in __GI___libc_free() -> malloc_printerr("free(): double free detected in tcache 2") -> __GI_abort() in a short word, a process abort is caused by myexit() interrupted by a signal which handler is myexit() itself. note, free() and fclose() are NOT async-signal-safe, see "man 7 signal-safety". calling an async-signal-unsafe function from a signal handler is perfectly legal unless the signal interrupted another async-signal-unsafe function. so i'm not sure about the unlink() case, unlink() is async-signal-safe. still, the double-free condition is still there, as we can see from the backtrace. i'm not going to fix the whole signal handling in cscope, as it seems broken. 1) myexit() calls functions which are not async-signal-safe 2) signal() infrastructure (which is broken) is used instead of sigaction(). i'll ugly-fix only this specific case where myexit() is interrupted by a call to myexit() itself by resetting signal handlers to default ones. this may be not entirely correct but whatever. Best regards, Vladis --- diff -up ./src/main.c.orig ./src/main.c --- ./src/main.c.orig 2024-08-04 16:49:08.723525637 +0200 +++ ./src/main.c 2024-08-04 16:53:19.967862016 +0200 @@ -1056,11 +1056,18 @@ Please see the manpage for more informat void myexit(int sig) { + /* reset signal handlers to default ones, so myexit() is not called + * recursively as a signal handler during a normal exit */ + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGHUP, SIG_DFL); + signal(SIGTERM, SIG_DFL); + /* HBB 20010313; close file before unlinking it. Unix may not care * about that, but DOS absolutely needs it */ if (refsfound != NULL) fclose(refsfound); - + /* remove any temporary files */ if (temp1[0] != '\0') { unlink(temp1); _______________________________________________ Cscope-devel mailing list Cscope-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/cscope-devel