rabbit-slide-okkez-sprk2012 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/.rabbit +2 -0
  2. data/README.rd +34 -0
  3. data/Rakefile +7 -0
  4. data/config.yaml +17 -0
  5. data/pdf/sprk2012-slide.pdf +0 -0
  6. data/slide.rab +292 -0
  7. metadata +68 -0
data/.rabbit ADDED
@@ -0,0 +1,2 @@
1
+ slide.rab
2
+
@@ -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
+
@@ -0,0 +1,7 @@
1
+ require "rabbit/task/slide"
2
+
3
+ # Edit ./config.yaml to customize meta data
4
+
5
+ Rabbit::Task::Slide.new do |task|
6
+ # task.spec.add_runtime_dependency("YOUR THEME")
7
+ end
@@ -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
@@ -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: []