diff --git a/libguile/gc.c b/libguile/gc.c
index fc405f3..b531b85 100644
--- a/libguile/gc.c
+++ b/libguile/gc.c
@@ -617,6 +617,28 @@ scm_getenv_int (const char *var, int def)
 void
 scm_storage_prehistory ()
 {
+  /* libgc seems to obtain the stack address from the kernel on
+  linux/freebsd. this gives it valgrind's stack address, which it
+  then scans, causing a segmentation fault. this sets GC_stackbottom
+  to the address that valgrind wants the program to use */
+#if HAVE_PTHREAD_ATTR_GETSTACK && HAVE_PTHREAD_GETATTR_NP
+  size_t size;
+  void* sstart;
+  pthread_attr_t attr;
+  pthread_getattr_np(pthread_self(), &attr);
+  pthread_attr_getstack(&attr, &sstart, &size);
+  pthread_attr_destroy(&attr);
+  if(sstart) {
+    GC_stackbottom = (char*) sstart + size;
+  } else {
+    int dummy;
+    size_t stack_bottom = (size_t) & dummy;
+    stack_bottom += 4095;
+    stack_bottom &= ~4095;
+    GC_stackbottom = (char*) stack_bottom;
+  }
+#endif
+
   GC_all_interior_pointers = 0;
   GC_set_free_space_divisor (scm_getenv_int ("GC_FREE_SPACE_DIVISOR", 3));
 
@@ -813,7 +835,6 @@ scm_i_tag_name (scm_t_bits tag)
 
 
 
-
 void
 scm_init_gc ()
 {
diff --git a/libguile/threads.c b/libguile/threads.c
index 7c377d7..e052f47 100644
--- a/libguile/threads.c
+++ b/libguile/threads.c
@@ -632,6 +632,7 @@ scm_i_init_thread_for_guile (SCM_STACKITEM *base, SCM parent)
 static SCM_STACKITEM *
 get_thread_stack_base ()
 {
+  SCM_STACKITEM* ret;
   pthread_attr_t attr;
   void *start, *end;
   size_t size;
@@ -647,16 +648,18 @@ get_thread_stack_base ()
 
 #ifndef PTHREAD_ATTR_GETSTACK_WORKS
   if ((void *)&attr < start || (void *)&attr >= end)
-    return (SCM_STACKITEM *) GC_stackbottom;
+    ret = (SCM_STACKITEM*) GC_stackbottom;
   else
 #endif
     {
 #if SCM_STACK_GROWS_UP
-      return start;
+      ret = (SCM_STACKITEM*) start;
 #else
-      return end;
+      ret = (SCM_STACKITEM*) end;
 #endif
     }
+  pthread_attr_destroy(&attr);
+  return ret;
 }
 
 #elif defined HAVE_PTHREAD_GET_STACKADDR_NP
