Commit | Line | Data |
---|---|---|
ccf1ca4a LC |
1 | /* Copyright (C) 2008 Free Software Foundation, Inc. |
2 | * | |
3 | * This library is free software; you can redistribute it and/or | |
53befeb7 NJ |
4 | * modify it under the terms of the GNU Lesser General Public License |
5 | * as published by the Free Software Foundation; either version 3 of | |
6 | * the License, or (at your option) any later version. | |
ccf1ca4a | 7 | * |
53befeb7 NJ |
8 | * This library is distributed in the hope that it will be useful, but |
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
ccf1ca4a LC |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
11 | * Lesser General Public License for more details. | |
12 | * | |
13 | * You should have received a copy of the GNU Lesser General Public | |
14 | * License along with this library; if not, write to the Free Software | |
53befeb7 NJ |
15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
16 | * 02110-1301 USA | |
ccf1ca4a LC |
17 | */ |
18 | ||
19 | ||
20 | /* Test whether `scm_with_guile ()' can be called several times from a given | |
21 | thread, but from a different stack depth. Up to 1.8.5, `scm_with_guile | |
22 | ()' would not update the thread's `base' field, which would then confuse | |
23 | the GC. | |
24 | ||
25 | See http://lists.gnu.org/archive/html/guile-devel/2008-11/msg00037.html | |
26 | for a detailed report. */ | |
27 | ||
28 | #ifdef HAVE_CONFIG_H | |
29 | # include <config.h> | |
30 | #endif | |
31 | ||
32 | #include <libguile.h> | |
33 | ||
34 | static void * | |
35 | entry_point (void *arg) | |
36 | { | |
37 | /* Invoke the GC. If `THREAD->base' is incorrect, then Guile will just | |
38 | segfault somewhere in `scm_mark_locations ()'. */ | |
39 | scm_gc (); | |
40 | ||
41 | return NULL; | |
42 | } | |
43 | ||
44 | static void | |
45 | go_deeper_into_the_stack (unsigned level) | |
46 | { | |
47 | /* The assumption is that the compiler is not smart enough to optimize this | |
48 | out. */ | |
49 | if (level > 0) | |
50 | go_deeper_into_the_stack (level - 1); | |
51 | else | |
52 | scm_with_guile (entry_point, NULL); | |
53 | } | |
54 | ||
55 | \f | |
56 | int | |
57 | main (int argc, char *argv[]) | |
58 | { | |
59 | /* Invoke `scm_with_guile ()' from someplace deep into the stack. */ | |
60 | go_deeper_into_the_stack (100); | |
61 | ||
62 | /* Invoke it from much higher into the stack. This time, Guile is expected | |
63 | to update the `base' field of the current thread. */ | |
64 | scm_with_guile (entry_point, NULL); | |
65 | ||
66 | return 0; | |
67 | } |