# Stack area in blocking region with -O0

**URL:** <https://www.ruby-forum.com/t/stack-area-in-blocking-region-with-o0/178677>\
**Category:** Development\
**Created:** [November 9, 2009, 12:13pm UTC](https://www.ruby-forum.com/t/stack-area-in-blocking-region-with-o0/178677 "2009-11-09T12:13:56Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tanaka\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/c67d28/32.png) [@Tanaka\_A](https://www.ruby-forum.com/u/Tanaka_A)\
**Post date:** [November 9, 2009, 12:13pm UTC](https://www.ruby-forum.com/t/stack-area-in-blocking-region-with-o0/178677/1 "2009-11-09T12:13:56Z")

</div>

-O0 e$B$G%3%s%Q%$%k$7$?e(B ruby e$B$G0J2\<$N$h$&$K$9$k$H!“e(Bstack  
e$B$Ne(B  
mark e$B$GJQ$J$H$3$m$r%”%/%;%9$7$^$9!#e(B

% valgrind ./ruby -ve ‘Thread.new { gets }; 10.times { GC.start }’  
==4690== Memcheck, a memory error detector.  
==4690== Copyright © 2002-2007, and GNU GPL’d, by Julian Seward et al.  
==4690== Using LibVEX rev 1854, a library for dynamic binary  
translation.  
==4690== Copyright © 2004-2007, and GNU GPL’d, by OpenWorks LLP.  
==4690== Using valgrind-3.3.1-Debian, a dynamic binary instrumentation  
framework.  
==4690== Copyright © 2000-2007, and GNU GPL’d, by Julian Seward et al.  
==4690== For more details, rerun with: -v  
==4690==  
ruby 1.9.2dev (2009-11-09 trunk 25699) [i686-linux]  
==4690== Invalid read of size 4  
==4690== at 0x80643AD: mark\_locations\_array (gc.c:1313)  
==4690== by 0x8064575: gc\_mark\_locations (gc.c:1329)  
==4690== by 0x8066182: rb\_gc\_mark\_machine\_stack (gc.c:2221)  
==4690== by 0x814EC56: rb\_thread\_mark (vm.c:1630)  
==4690== by 0x8064F07: gc\_mark\_children (gc.c:1713)  
==4690== by 0x8064A11: gc\_mark (gc.c:1508)  
==4690== by 0x8064A3B: rb\_gc\_mark (gc.c:1514)  
==4690== by 0x814E66F: vm\_mark\_each\_thread\_func (vm.c:1432)  
==4690== by 0x80F3C2C: st\_foreach (st.c:747)  
==4690== by 0x814E6DC: rb\_vm\_mark (vm.c:1455)  
==4690== by 0x8064F07: gc\_mark\_children (gc.c:1713)  
==4690== by 0x8064A11: gc\_mark (gc.c:1508)  
==4690== Address 0x48d6140 is not stack’d, malloc’d or (recently)  
free’d  
==4690==  
==4690== ERROR SUMMARY: 70 errors from 1 contexts (suppressed: 29 from  
1)  
==4690== malloc/free: in use at exit: 890,874 bytes in 13,756 blocks.  
==4690== malloc/free: 15,651 allocs, 1,895 frees, 2,158,101 bytes  
allocated.  
==4690== For counts of detected errors, rerun with: -v  
==4690== searching for pointers to 13,756 not-freed blocks.  
==4690== checked 962,284 bytes.  
==4690==  
==4690== LEAK SUMMARY:  
==4690== definitely lost: 222,005 bytes in 9,073 blocks.  
==4690== possibly lost: 136 bytes in 1 blocks.  
==4690== still reachable: 668,733 bytes in 4,682 blocks.  
==4690== suppressed: 0 bytes in 0 blocks.  
==4690== Rerun with --leak-check=full to see details of leaked memory.

e$BD4$Y$F$_$k$H!"$3$NJQ$J$H$3$m$H$$$&$N$O!"%9%?%C%/$,=L$s$@$H$3e(B  
e$B$m$G$9!#$I$&$be(B rb\_thread\_t e$B$Ne(B machine\_stack\_end  
e$B$r5-O?$7$?8ee(B  
e$B$K%9%?%C%/$,=L$s$G$=$N%?%$%_%s%0$Ge(B GC e$B$,5/$-$k$H$$$&$3$H$N$he(B  
e$B$&$G$9!#e(B

machine\_stack\_end e$B$N5-O?$+$i%9%l%C%I$N%9%$%C%A$K;j$k$^$G$K%9e(B  
e$B%?%C%/$,=L$^$J$$$h$&$K$7$F=$@5$G$-$^$9!#e(B

# % svn diff --diff-cmd diff -x ‘-u -p’ Index: thread.c

— thread.c (revision 25700)  
+++ thread.c (working copy)  
@@ -97,13 +97,17 @@ static void set\_unblock\_function(rb\_thre  
struct rb\_unblock\_callback \*old);  
static void reset\_unblock\_function(rb\_thread\_t \*th, const struct  
rb\_unblock\_callback \*old);

-static inline void blocking\_region\_begin(rb\_thread\_t \*th, struct  
rb\_blocking\_region\_buffer \*region,

- 

```
      rb_unblock_function_t *func, void *arg);

```

static inline void blocking\_region\_end(rb\_thread\_t \*th, struct  
rb\_blocking\_region\_buffer \*region);

+#define RB\_GC\_SAVE\_MACHINE\_CONTEXT(th) \

- do { \
- rb\_gc\_save\_machine\_context(th); \
- SET\_MACHINE\_STACK\_END(&(th)-\>machine\_stack\_end); \
- } while (0)
- 

#define GVL\_UNLOCK\_BEGIN() do {   
rb\_thread\_t \*\_th\_stored = GET\_THREAD(); \

- rb\_gc\_save\_machine\_context(\_th\_stored); \

- RB\_GC\_SAVE\_MACHINE\_CONTEXT(\_th\_stored);   
native\_mutex\_unlock(&\_th\_stored-\>vm-\>global\_vm\_lock)

#define GVL\_UNLOCK\_END()   
@@ -960,7 +964,7 @@ rb\_thread\_schedule\_rec(int sched\_depth)

thread\_debug(“rb\_thread\_schedule/switch start\n”);

- rb\_gc\_save\_machine\_context(th);

- RB\_GC\_SAVE\_MACHINE\_CONTEXT(th);  
native\_mutex\_unlock(&th-\>vm-\>global\_vm\_lock);  
{  
native\_thread\_yield();  
@@ -983,18 +987,16 @@ rb\_thread\_schedule(void)  
}

/\* blocking region \*/  
-static inline void  
-blocking\_region\_begin(rb\_thread\_t \*th, struct rb\_blocking\_region\_buffer  
\*region,

- 

```
     rb_unblock_function_t *func, void *arg)

```

-{

- region-\>prev\_status = th-\>status;
- th-\>blocking\_region\_buffer = region;
- set\_unblock\_function(th, func, arg, &region-\>oldubf);
- th-\>status = THREAD\_STOPPED;
- thread\_debug(“enter blocking region (%p)\n”, (void \*)th);
- rb\_gc\_save\_machine\_context(th);
- native\_mutex\_unlock(&th-\>vm-\>global\_vm\_lock);  
-}  
+#define blocking\_region\_begin(th, region, func, arg) \

- do { \
- (region)-\>prev\_status = (th)-\>status; \
- (th)-\>blocking\_region\_buffer = (region); \
- set\_unblock\_function((th), (func), (arg), &(region)-\>oldubf); \
- (th)-\>status = THREAD\_STOPPED; \
- thread\_debug(“enter blocking region (%p)\n”, (void \*)(th)); \
- RB\_GC\_SAVE\_MACHINE\_CONTEXT(th); \
- native\_mutex\_unlock(&(th)-\>vm-\>global\_vm\_lock); \
- } while (0)

static inline void  
blocking\_region\_end(rb\_thread\_t \*th, struct rb\_blocking\_region\_buffer  
\*region)  
@@ -2599,7 +2601,6 @@ rb\_gc\_set\_stack\_end(VALUE \*\*stack\_end\_p)  
void  
rb\_gc\_save\_machine\_context(rb\_thread\_t \*th)  
{

- SET\_MACHINE\_STACK\_END(&th-\>machine\_stack\_end);  
FLUSH\_REGISTER\_WINDOWS;  
#ifdef \_\_ia64  
th-\>machine\_register\_stack\_end = rb\_ia64\_bsp();
