rabbit-slide-okkez-sprk2012 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rabbit +2 -0
- data/README.rd +34 -0
- data/Rakefile +7 -0
- data/config.yaml +17 -0
- data/pdf/sprk2012-slide.pdf +0 -0
- data/slide.rab +292 -0
- metadata +68 -0
data/.rabbit
ADDED
data/README.rd
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
= バグの直し方
|
2
|
+
|
3
|
+
札幌Ruby会議2012で発表した内容にデモで話す予定だったことを追加しました。
|
4
|
+
|
5
|
+
== For author
|
6
|
+
|
7
|
+
=== Show
|
8
|
+
|
9
|
+
rake
|
10
|
+
|
11
|
+
=== Publish
|
12
|
+
|
13
|
+
rake publish
|
14
|
+
|
15
|
+
== For viewers
|
16
|
+
|
17
|
+
=== Install
|
18
|
+
|
19
|
+
gem install rabbit-slide-okkez-sprk2012
|
20
|
+
|
21
|
+
=== Show
|
22
|
+
|
23
|
+
rabbit rabbit-slide-okkez-sprk2012.gem
|
24
|
+
|
25
|
+
== ライセンス - License
|
26
|
+
|
27
|
+
=== スライド
|
28
|
+
|
29
|
+
CC BY 3.0
|
30
|
+
|
31
|
+
原著作者 - Author:
|
32
|
+
|
33
|
+
* Kenji Okimoto
|
34
|
+
|
data/Rakefile
ADDED
data/config.yaml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
id: sprk2012
|
3
|
+
base_name: slide
|
4
|
+
tags:
|
5
|
+
- sprk2012
|
6
|
+
- clear code
|
7
|
+
presentation_date: 2012-09-16
|
8
|
+
version: 1.0.0
|
9
|
+
licenses:
|
10
|
+
- CC-BY-SA 3.0
|
11
|
+
author:
|
12
|
+
markup_language: RD
|
13
|
+
name: Kenji Okimoto
|
14
|
+
email: okimoto@clear-code.com
|
15
|
+
rubygems_user: okkez
|
16
|
+
slideshare_user:
|
17
|
+
speaker_deck_user:
|
Binary file
|
data/slide.rab
ADDED
@@ -0,0 +1,292 @@
|
|
1
|
+
= バグの直し方
|
2
|
+
|
3
|
+
: subtitle
|
4
|
+
実例を添えて
|
5
|
+
: author
|
6
|
+
Kenji Okimoto
|
7
|
+
: institution
|
8
|
+
株式会社クリアコード
|
9
|
+
: date
|
10
|
+
2012-09-16
|
11
|
+
: theme
|
12
|
+
rabbit-theme-clear-code
|
13
|
+
: allotted-time
|
14
|
+
30m
|
15
|
+
|
16
|
+
= 自己紹介
|
17
|
+
|
18
|
+
* okkez (おっきーと読みます)
|
19
|
+
* Ruby 歴8年くらい
|
20
|
+
* るりま (2006-11から)
|
21
|
+
* Hiki (2008-09から)
|
22
|
+
* CRuby コミッタ (2011-12から)
|
23
|
+
|
24
|
+
= 自己紹介
|
25
|
+
|
26
|
+
* クリアコード (2010-11から)
|
27
|
+
* 大規模メールシステム \n(milter manager)
|
28
|
+
* GLib, GTK+ アプリケーション
|
29
|
+
* Ruby, C/C++, etc.
|
30
|
+
|
31
|
+
= お品書き
|
32
|
+
|
33
|
+
* (('note:よく知らないプログラムの'))バグの直し方
|
34
|
+
* 実例紹介
|
35
|
+
|
36
|
+
= バグの直し方
|
37
|
+
|
38
|
+
* バグに気付く
|
39
|
+
* 再現方法を記録する
|
40
|
+
* 問題箇所を絞り込む
|
41
|
+
* (('tag:x-small:問題を修正する'))
|
42
|
+
* (('tag:x-small:修正できたことを確認する'))
|
43
|
+
* 壊していないことを確認する
|
44
|
+
|
45
|
+
= 再現方法を記録する
|
46
|
+
|
47
|
+
* 問題を再現できる
|
48
|
+
* テストプログラムを作成する
|
49
|
+
* 操作をメモする
|
50
|
+
* データを作成する
|
51
|
+
|
52
|
+
= 問題箇所を絞り込む
|
53
|
+
|
54
|
+
対象のプログラムを
|
55
|
+
|
56
|
+
* よく知っている場合
|
57
|
+
* 怪しい部分の目星を付ける
|
58
|
+
* ((*よく知らない場合*))
|
59
|
+
* ((*地道に作業して問題箇所を特定する*))
|
60
|
+
|
61
|
+
= 問題箇所を絞り込む
|
62
|
+
|
63
|
+
# image
|
64
|
+
# src = flow.dia
|
65
|
+
# relative_height = 100
|
66
|
+
|
67
|
+
== property
|
68
|
+
|
69
|
+
: enable-title-on-image
|
70
|
+
false
|
71
|
+
|
72
|
+
= ポイント!!
|
73
|
+
|
74
|
+
# blockquote
|
75
|
+
プログラムの変更を少しずつ行うことによって、一歩ずつ着実に問題の解決に
|
76
|
+
向かっていく
|
77
|
+
|
78
|
+
= ポイント!!
|
79
|
+
|
80
|
+
# blockquote
|
81
|
+
プログラムの変更を行うたびに、「今回の変更では何を調べたいのか」を意識
|
82
|
+
して作業する
|
83
|
+
|
84
|
+
= 問題箇所を特定できたら
|
85
|
+
|
86
|
+
* 問題を修正する
|
87
|
+
|
88
|
+
= 修正できたことを確認
|
89
|
+
|
90
|
+
* 再現方法を実行
|
91
|
+
* 問題が再現しないことを確認
|
92
|
+
* ((*修正できた!!*))
|
93
|
+
|
94
|
+
= 実例紹介
|
95
|
+
|
96
|
+
* Ruby のメモリリーク
|
97
|
+
* http://bugs.ruby-lang.org/issues/5688
|
98
|
+
* http://www.clear-code.com/blog/2011/12/6.html
|
99
|
+
|
100
|
+
= デモ
|
101
|
+
|
102
|
+
* (('note:バグに気付く'))
|
103
|
+
* (('note:再現方法を記録する'))
|
104
|
+
* ((*問題箇所を絞り込む*))
|
105
|
+
* 問題を修正する
|
106
|
+
* (('note:修正できたことを確認する'))
|
107
|
+
* (('note:壊していないことを確認する'))
|
108
|
+
|
109
|
+
= 事前情報
|
110
|
+
|
111
|
+
* Solaris10 で発生
|
112
|
+
* Ruby 1.9.2-p180 で発生
|
113
|
+
* mtrace や valgrind が使えない
|
114
|
+
* spawn だけでなく fork でも発生
|
115
|
+
* 慣れている Debian では発生しない
|
116
|
+
|
117
|
+
= 再現コード
|
118
|
+
|
119
|
+
# coderay ruby
|
120
|
+
ARGV[0].to_i.times do |n|
|
121
|
+
fork{ exit! }
|
122
|
+
#spawn{ exit! }
|
123
|
+
GC.start if n % 100 == 0
|
124
|
+
end
|
125
|
+
|
126
|
+
(('note:fork()でもspawn()でもメモリリークする'))
|
127
|
+
|
128
|
+
= 便利スクリプト
|
129
|
+
|
130
|
+
# coderay bash
|
131
|
+
#!/bin/bash
|
132
|
+
/tmp/a/bin/ruby ./fork-exit.rb 300000 &
|
133
|
+
pid=$!
|
134
|
+
echo fork-exit:$pid
|
135
|
+
trap "kill $pid; exit" INT TERM
|
136
|
+
count=0
|
137
|
+
ps -o pid,ppid,vsz,rss,args | head -1
|
138
|
+
prev=""
|
139
|
+
while true; do
|
140
|
+
current=`ps -p ${pid} -o pid,ppid,vsz,rss,args | grep fork-exit.rb`
|
141
|
+
if test "$current" != "$prev"; then
|
142
|
+
echo "$current"
|
143
|
+
fi
|
144
|
+
prev=$current
|
145
|
+
sleep 1
|
146
|
+
done
|
147
|
+
|
148
|
+
(('note:便利スクリプトがあると便利!!'))
|
149
|
+
|
150
|
+
= Step 1
|
151
|
+
|
152
|
+
spawn のコールグラフ
|
153
|
+
|
154
|
+
spawn
|
155
|
+
-> rb_f_spawn
|
156
|
+
-> rb_spawn_process
|
157
|
+
-> rb_fork_err
|
158
|
+
|
159
|
+
= Step 1
|
160
|
+
|
161
|
+
fork のコールグラフ
|
162
|
+
|
163
|
+
fork
|
164
|
+
-> rb_f_fork
|
165
|
+
-> rb_fork
|
166
|
+
-> rb_fork_err
|
167
|
+
|
168
|
+
= Step 2
|
169
|
+
|
170
|
+
spawn でも fork でも ((*rb_fork_err*))\nを呼んでいる
|
171
|
+
|
172
|
+
= Step 3 - 処理を確認する
|
173
|
+
|
174
|
+
rb_fork_err の中身を確認
|
175
|
+
|
176
|
+
before_fork()
|
177
|
+
fork()
|
178
|
+
if (!pid) { ... }
|
179
|
+
after_fork()
|
180
|
+
|
181
|
+
(('note:if(!pid){...}は子プロセスの処理なので無視する'))
|
182
|
+
|
183
|
+
= Step 3 - 処理を変更する
|
184
|
+
|
185
|
+
* before_fork() の前で return -1
|
186
|
+
* before_fork() の後で return -1
|
187
|
+
* fork() の後で return pid
|
188
|
+
* after_fork() の後で return pid
|
189
|
+
* 修正前と同じ
|
190
|
+
|
191
|
+
= Step 4
|
192
|
+
|
193
|
+
* (('tag:x-small:before_fork() の前')) ... ビルドエラー
|
194
|
+
* (('tag:x-small:before_fork() の後')) ... ビルドエラー
|
195
|
+
* (('tag:x-small:fork() の後で')) ... メモリリークしない!
|
196
|
+
|
197
|
+
((*after_fork()*)) に問題があることがわかった!!
|
198
|
+
|
199
|
+
= Step 5 - after_fork()
|
200
|
+
|
201
|
+
* GET_THREAD()->thrown_errinfo = 0
|
202
|
+
* 値をセットしているだけ
|
203
|
+
* rb_thread_reset_timer_thread()
|
204
|
+
* 値をセットしてるだけ
|
205
|
+
|
206
|
+
= Step 5 - after_fork()
|
207
|
+
|
208
|
+
* rb_thread_start_timer_thread()
|
209
|
+
* rb_thread_create_timer_thread()
|
210
|
+
* forked_child = 0
|
211
|
+
* 値をセットしてるだけ
|
212
|
+
* rb_disable_interrupt()
|
213
|
+
* 値をセットしてるだけ
|
214
|
+
|
215
|
+
= Step 6
|
216
|
+
|
217
|
+
* pthread_attr_init(3) を読む
|
218
|
+
* pthread_attr_destroy() もある
|
219
|
+
* pthread_create(3) を読む
|
220
|
+
* pthread_create()の引数がわかる
|
221
|
+
|
222
|
+
= Step 7
|
223
|
+
|
224
|
+
pthread_create\n
|
225
|
+
の第2引数を\n
|
226
|
+
((*NULL*))にすると...
|
227
|
+
|
228
|
+
= Step 7
|
229
|
+
|
230
|
+
メモリリーク\nしなくなる!!
|
231
|
+
|
232
|
+
= Step 8
|
233
|
+
|
234
|
+
((*pthread_attr_init*))\n
|
235
|
+
してるけど\n
|
236
|
+
((*pthread_attr_destroy*))\n
|
237
|
+
してないことに気付く
|
238
|
+
|
239
|
+
= Step 9
|
240
|
+
|
241
|
+
((*pthread_attr_destroy*))\n
|
242
|
+
を追加して\n試すと...
|
243
|
+
|
244
|
+
= Step 10
|
245
|
+
|
246
|
+
((*メモリリーク*))\n
|
247
|
+
((*しなくなる*))
|
248
|
+
|
249
|
+
= パッチ
|
250
|
+
|
251
|
+
# coderay diff
|
252
|
+
diff --git a/thread_pthread.c b/thread_pthread.c
|
253
|
+
index 4746aaa..ab7bdf9 100644
|
254
|
+
--- a/thread_pthread.c
|
255
|
+
+++ b/thread_pthread.c
|
256
|
+
@@ -835,6 +835,7 @@ rb_thread_create_timer_thread(void)
|
257
|
+
}
|
258
|
+
native_cond_wait(&timer_thread_cond, &timer_thread_lock);
|
259
|
+
native_mutex_unlock(&timer_thread_lock);
|
260
|
+
+ pthread_attr_destroy(&attr);
|
261
|
+
}
|
262
|
+
rb_disable_interrupt(); /* only timer thread recieve signal */
|
263
|
+
}
|
264
|
+
|
265
|
+
= Step 11
|
266
|
+
|
267
|
+
# blockquote
|
268
|
+
パッチを作ったら\nmake test-all\nを流してE,Fが増えていないことを確認する
|
269
|
+
|
270
|
+
= まとめ
|
271
|
+
|
272
|
+
* バグに気付く
|
273
|
+
* ((*再現方法を記録する*))
|
274
|
+
* ((*問題箇所を絞り込む*))
|
275
|
+
* (('tag:x-small:問題を修正する'))
|
276
|
+
* (('tag:x-small:修正できたことを確認する'))
|
277
|
+
* 壊していないことを確認する
|
278
|
+
|
279
|
+
= ポイント!!
|
280
|
+
|
281
|
+
問題箇所は\n((*一歩ずつ着実に*))\n絞り込む
|
282
|
+
|
283
|
+
= ポイント!!
|
284
|
+
|
285
|
+
# blockquote
|
286
|
+
問題箇所を特定できたらバグの修正は((*八割以上*))できたも同然です
|
287
|
+
|
288
|
+
= 次の一歩
|
289
|
+
|
290
|
+
* 水平展開
|
291
|
+
* 似たようなバグがあるかも。。。
|
292
|
+
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rabbit-slide-okkez-sprk2012
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Kenji Okimoto
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rabbit
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.0.2
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.0.2
|
30
|
+
description: 札幌Ruby会議2012で発表した内容にデモで話す予定だったことを追加しました。
|
31
|
+
email:
|
32
|
+
- okimoto@clear-code.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- .rabbit
|
38
|
+
- config.yaml
|
39
|
+
- Rakefile
|
40
|
+
- README.rd
|
41
|
+
- slide.rab
|
42
|
+
- pdf/sprk2012-slide.pdf
|
43
|
+
homepage: http://slide.rabbit-shocker.org/authors/okkez/sprk2012/
|
44
|
+
licenses:
|
45
|
+
- CC-BY-SA 3.0
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirements: []
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 1.8.24
|
65
|
+
signing_key:
|
66
|
+
specification_version: 3
|
67
|
+
summary: バグの直し方
|
68
|
+
test_files: []
|