SIGSEGV problem on config reload: patch to test
2004-05-31 by manu@netbsd.org
Hi everyone
Here is a patch for milter-greylist-1.3.6 that spawns a new thread,
requesting enough stack for reloading the config file.
This should fix the SIGSEGV on config reload problem for everyone.
Before integrating it I'd like to be sure it does what we look for
(i.e.: fix the problem). Can people that still have a SIGSEGV problem
test it?
Reminder about patches: save it (without turning tabs into space, so
beware with copy/paste in a confbugfix.patch file, and in
milter-greylist build directory, issue:
patch < confbugfix.patch
Then rebuild and reinstall.
Index: conf.c
===================================================================
RCS file: /cvsroot/milter-greylist/conf.c,v
retrieving revision 1.20
diff -U4 -r1.20 conf.c
--- conf.c 2004/05/26 09:14:29 1.20
+++ conf.c 2004/05/31 11:39:29
@@ -82,8 +82,10 @@
void
conf_load(void) /* exceptlist must be write-locked */
{
FILE *stream;
+ pthread_t tid;
+ pthread_attr_t attr;
/*
* Reset the configuration to its default
* (This includes command line flags)
@@ -99,10 +101,51 @@
fprintf(stderr, "continuing with no exception list\n");
return;
}
+ /*
+ * On some platforms, the thread stack limit is too low and
+ * conf_parse will get a SIGSEGV because it overflows the
+ * stack.
+ *
+ * In order to fix this, we spawn a new thread just for
+ * parsing the config file, and we request a stack big
+ * enough to hold the parser data. 2 MB seems okay.
+ */
conf_in = stream;
- conf_parse();
+
+ if (pthread_attr_init(&attr) != 0) {
+ syslog(LOG_ERR, "pthread_attr_init failed: %s",
+ strerror(errno));
+ exit(EX_OSERR);
+ }
+
+ if (pthread_attr_setstacksize(&attr, 2 * 1024 * 1024) != 0) {
+ syslog(LOG_ERR, "pthread_attr_setstacksize failed: %s",
+ strerror(errno));
+ exit(EX_OSERR);
+ }
+
+ if (pthread_create(&tid, &attr,
+ (void *(*)(void *))conf_parse, NULL) != 0) {
+ syslog(LOG_ERR, "pthread_create failed: %s",
+ strerror(errno));
+ exit(EX_OSERR);
+ }
+
+ if (pthread_join(tid, NULL) != 0) {
+ syslog(LOG_ERR, "pthread_join failed: %s",
+ strerror(errno));
+ exit(EX_OSERR);
+ }
+
+ if (pthread_attr_destroy(&attr) != 0) {
+ syslog(LOG_ERR, "pthread_attr_destroy failed: %s",
+ strerror(errno));
+ exit(EX_OSERR);
+ }
+
+
fclose(stream);
(void)gettimeofday(&conffile_modified, NULL);
--
Emmanuel Dreyfus
Il y a 10 sortes de personnes dans le monde: ceux qui comprennent
le binaire et ceux qui ne le comprennent pas.
manu@...