#include #include #include #include #include #include #include #include #include #include #include #include #include #define BACKTRACE 0 #define SYSLOG 1 #define SIGACTION 0 #if BACKTRACE void inline z_dump_backtrace(unsigned long eip, unsigned long first_ebp) { /* NOTE: this is i386 specific */ unsigned long *ebp; fprintf(stderr, "retaddr=0x%lx, ebp=0x%lx\n", eip, first_ebp); ebp = (unsigned long *) first_ebp; while (ebp > (unsigned long *) &ebp && *ebp) { fprintf(stderr, "retaddr=0x%lx, ebp=0x%lx\n", *(ebp+1), *ebp); ebp = (unsigned long *) *ebp; } } void z_fatal_signal_handler(int signo) { struct sigcontext *p = (struct sigcontext *) (((char *) &p) + 16); fprintf(stderr, "Signal (%d) received, stackdump follows; eax='%08lx', ebx='%08lx', ecx='%08lx', edx='%08lx', eip='%08lx'\n", signo, p->eax, p->ebx, p->ecx, p->edx, p->eip); z_dump_backtrace(p->eip, p->ebp); exit(1); } #endif pthread_mutex_t syslog_mutex = PTHREAD_MUTEX_INITIALIZER; void *thread_func(void *arg) { int fd = *(int *) arg; int i; char buf[1024]; #if SYSLOG /* this shows the problem */ pthread_mutex_lock(&syslog_mutex); syslog(LOG_DEBUG, "thread started...%p\n", pthread_self()); pthread_mutex_unlock(&syslog_mutex); #endif #if SIGACTION /* this is not enough, the crash doesn't occur */ struct sigaction sa, oldsa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, &oldsa); for (i = 0; i < 102400; ) i++; sigaction(SIGPIPE, &oldsa, NULL); #endif memset(buf, 'a', sizeof(buf)); for (i = 0; i < 1024; i++) { write(fd, buf, sizeof(buf)); } close(fd); //syslog(LOG_DEBUG, "thread stopped...%p\n", pthread_self()); free(arg); return NULL; } int main() { int fd; struct sockaddr_in sin; int tmp = 1; #if BACKTRACE signal(SIGSEGV, z_fatal_signal_handler); #endif signal(SIGPIPE, SIG_IGN); fd = socket(AF_INET, SOCK_STREAM, 0); sin.sin_family = AF_INET; sin.sin_port = htons(10000); sin.sin_addr.s_addr = INADDR_ANY; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)); if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) { perror("bind"); return 0; } listen(fd, 255); while (1) { int newfd; int tmplen; pthread_t t; tmplen = sizeof(sin); newfd = accept(fd, (struct sockaddr *) &sin, &tmplen); if (newfd == -1) { perror("accept"); } else { int *state = (int *) malloc(sizeof(int)); *state = newfd; pthread_create(&t, NULL, thread_func, state); } } }