~ubuntu-branches/ubuntu/maverick/uim/maverick

« back to all changes in this revision

Viewing changes to sigscheme/doc/gc-protection.txt

  • Committer: Bazaar Package Importer
  • Author(s): Masahito Omote
  • Date: 2008-05-18 22:18:10 UTC
  • mfrom: (1.1.8 upstream)
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20080518221810-4d2rd0ca18xnu8kc
Tags: 1:1.5.1-1
* New upstream release
* uim-qt3: Add uim inputcontext plugin for Qt3. And due to uim-*-qt are
  not supported in Qt4 for now officially, uim-*-qt are contained in
  this package.
* uim-qt: Depends uim-qt3 because of described above.
* libuim6: New package for syncing with upstream upgrade soversion.
* 05_qmake_bug_workaround.dpatch: patch for the workaround that qmake does
  not add link option against other libraries(e.g. -lX11) by default.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
GC protection for on-stack objects
2
 
==================================
3
 
 
4
 
FIXME: obsolete
5
 
 
6
 
 
7
 
About
8
 
-----
9
 
 
10
 
This document describes GC protection for on-stack objects safe against an
11
 
irregular stack layout such as stack-smashing protection performs.
12
 
 
13
 
 
14
 
The Problem
15
 
-----------
16
 
 
17
 
Working on the previous stack protection strategy, following problem
18
 
occurs.(the explanation is based on
19
 
http://lists.sourceforge.jp/pipermail/anthy-dev/2005-August/002272.html[Anthy-dev 2273]
20
 
by Jun Inoue, and assumes that the stack grows downward).
21
 
 
22
 
Take a look in following code fragment.
23
 
 
24
 
[C]
25
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26
 
{
27
 
    ...
28
 
    exp = "(number->string (* 32 1024))";
29
 
    {
30
 
        ScmObj stack_start;
31
 
        ScmObj str_port;
32
 
        ScmObj obj;
33
 
    
34
 
        scm_gc_protect_stack(&stack_start);
35
 
    
36
 
        str_port = scm_make_string_port(exp);
37
 
        obj = scm_read(str_port);
38
 
        obj = SCM_EVAL(obj, SCM_INTERACTION_ENV);
39
 
    
40
 
        scm_gc_unprotect_stack(stack_start);
41
 
    }
42
 
 
43
 
    return SCM_STRING_STR(obj);
44
 
}
45
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46
 
 
47
 
The previous strategy assumes that `stack_start` is certainly located at lower
48
 
than `str_port` and `obj` to cover them on the mark-and-sweep stage. But the
49
 
actual layout breaks the assumption as follows.
50
 
 
51
 
At the breakpoint immediately before `scm_gc_protect_stack()` of the code
52
 
compiled with gcc4 ((GCC) 4.0.1 20050617 (prerelease) (Debian 4.0.0-10)
53
 
(IA32)), actual stack layout had been reported as follows.
54
 
 
55
 
----------------------------------------------------------------
56
 
(gdb) p &stack_start
57
 
$6 = (ScmObj *) 0xbfffe7d8
58
 
(gdb) p &str_port
59
 
$7 = (ScmObj *) 0xbfffe7dc
60
 
(gdb) p $sp
61
 
$12 = (void *) 0xbfffe7d0
62
 
----------------------------------------------------------------
63
 
 
64
 
This result indicates the storage location order inversion:
65
 
 
66
 
  expected: %esp < &str_port < &stack_start
67
 
  actual:   %esp < &stack_start < &str_port
68
 
 
69
 
So `str_port` is not protected in the case.
70
 
 
71
 
 
72
 
Solution
73
 
--------
74
 
 
75
 
  - Allocate the `stack_start` dummy variable in a separated frame
76
 
 
77
 
  - Ensure that a code fragment that its stack must be protected is certainly
78
 
    executed on the stack grown over the frame containing `stack_start`
79
 
 
80
 
To accomplish it, a series of macros which turns a function into
81
 
stack-protected. See following steps to know how to use it.
82
 
 
83
 
1) Split the code fragment off into a function. No stack protection handling is
84
 
needed here.
85
 
 
86
 
[C]
87
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
88
 
static const char *
89
 
eval_str(const char *exp)
90
 
{
91
 
    ScmObj str_port;
92
 
    ScmObj obj;
93
 
 
94
 
    str_port = scm_make_string_port(exp);
95
 
    obj = scm_read(str_port);
96
 
    obj = SCM_EVAL(obj, SCM_INTERACTION_ENV);
97
 
    return SCM_STRING_STR(obj);
98
 
}
99
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
100
 
 
101
 
 
102
 
2) Call the function prepared in 1) with the macro `SCM_GC_PROTECTED_CALL()` as
103
 
follows. The macro handles all of the GC protection issues. Once the function
104
 
returned, the stack protection is disabled again. To protect another function
105
 
call, apply the macro to the call.
106
 
 
107
 
Use `SCM_GC_PROTECTED_CALL_VOID()` instead if the calee function returns
108
 
`void`.
109
 
 
110
 
[C]
111
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
112
 
{
113
 
    const char *exp, *ret;
114
 
    ...
115
 
    exp = "(number->string (* 32 1024))";
116
 
    SCM_GC_PROTECTED_CALL(ret, const char *, eval_str, (exp));
117
 
    return ret;
118
 
}
119
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~