diff --git a/changes/bug15245 b/changes/bug15245
new file mode 100644
index 0000000000..520a370eeb
--- /dev/null
+++ b/changes/bug15245
@@ -0,0 +1,5 @@
+ o Major bugfixes:
+ - Avoid crashing when making certain configuration option changes
+ on clients. Fixes bug 15245; bugfix on 0.2.6.3-alpha. Reported
+ by "anonym".
+
diff --git a/changes/bug9495_redux b/changes/bug9495_redux
new file mode 100644
index 0000000000..74b0cdf2a8
--- /dev/null
+++ b/changes/bug9495_redux
@@ -0,0 +1,4 @@
+ o Major bugfixes (portability):
+ - Do not crash on startup when running on Solaris. Fixes a bug
+ related to our fix for 9495; bugfix on 0.2.6.1-alpha. Reported
+ by "ruebezahl".
diff --git a/src/common/compat_pthreads.c b/src/common/compat_pthreads.c
index f4a6cad154..246076b276 100644
--- a/src/common/compat_pthreads.c
+++ b/src/common/compat_pthreads.c
@@ -279,7 +279,11 @@ tor_threads_init(void)
pthread_mutexattr_init(&attr_recursive);
pthread_mutexattr_settype(&attr_recursive, PTHREAD_MUTEX_RECURSIVE);
tor_assert(0==pthread_attr_init(&attr_detached));
- tor_assert(0==pthread_attr_setdetachstate(&attr_detached, 1));
+#ifndef PTHREAD_CREATE_DETACHED
+#define PTHREAD_CREATE_DETACHED 1
+#endif
+ tor_assert(0==pthread_attr_setdetachstate(&attr_detached,
+ PTHREAD_CREATE_DETACHED));
threads_initialized = 1;
set_main_thread();
}
diff --git a/src/common/container.h b/src/common/container.h
index d07697f019..457b5e4ea0 100644
--- a/src/common/container.h
+++ b/src/common/container.h
@@ -256,7 +256,6 @@ char *smartlist_join_strings2(smartlist_t *sl, const char *join,
--var ## _sl_len; \
STMT_END
-
/** Helper: While in a SMARTLIST_FOREACH loop over the list sl indexed
* with the variable var, replace the current element with val.
* Does not deallocate the current value of var.
diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c
index 09ffdb81d1..d511ecf84c 100644
--- a/src/or/cpuworker.c
+++ b/src/or/cpuworker.c
@@ -178,6 +178,12 @@ update_state_threadfn(void *state_, void *work_)
void
cpuworkers_rotate_keyinfo(void)
{
+ if (!threadpool) {
+ /* If we're a client, then we won't have cpuworkers, and we won't need
+ * to tell them to rotate their state.
+ */
+ return;
+ }
if (threadpool_queue_update(threadpool,
worker_state_new,
update_state_threadfn,
@@ -486,6 +492,8 @@ assign_onionskin_to_cpuworker(or_circuit_t *circ,
cpuworker_request_t req;
int should_time;
+ tor_assert(threadpool);
+
if (!circ->p_chan) {
log_info(LD_OR,"circ->p_chan gone. Failing circ.");
tor_free(onionskin);
diff --git a/src/test/test_status.c b/src/test/test_status.c
index 0aa82ca087..cb3b4f64c7 100644
--- a/src/test/test_status.c
+++ b/src/test/test_status.c
@@ -878,7 +878,8 @@ NS(logv)(int severity, log_domain_mask_t domain, const char *funcname,
tt_ptr_op(strstr(funcname, "log_heartbeat"), OP_NE, NULL);
tt_ptr_op(suffix, OP_EQ, NULL);
tt_str_op(format, OP_EQ,
- "Average packaged cell fullness: %2.3f%%. TLS write overhead: %.f%%");
+ "Average packaged cell fullness: %2.3f%%. "
+ "TLS write overhead: %.f%%");
tt_double_op(fabs(va_arg(ap, double) - 50.0), <=, DBL_EPSILON);
tt_double_op(fabs(va_arg(ap, double) - 0.0), <=, DBL_EPSILON);
break;
@@ -1026,7 +1027,8 @@ NS(logv)(int severity, log_domain_mask_t domain,
tt_ptr_op(strstr(funcname, "log_heartbeat"), OP_NE, NULL);
tt_ptr_op(suffix, OP_EQ, NULL);
tt_str_op(format, OP_EQ,
- "Average packaged cell fullness: %2.3f%%. TLS write overhead: %.f%%");
+ "Average packaged cell fullness: %2.3f%%. "
+ "TLS write overhead: %.f%%");
tt_int_op(fabs(va_arg(ap, double) - 100.0) <= DBL_EPSILON, OP_EQ, 1);
tt_double_op(fabs(va_arg(ap, double) - 100.0), <=, DBL_EPSILON);
break;