← Documents Documentation/dev-tools/coccinelle.rst GitHub 원문 ↗

Linux 6.18.37 · Dev Tools

Coccinelle

Coccinelle과 coccicheck로 Linux 커널 semantic patch를 실행하고 범위·병렬도·출력 mode·디버깅·index 옵션을 제어하는 방법을 설명합니다.

Source pathDocumentation/dev-tools/coccinelle.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

coccinelle.rst:1-511

Coccinelle은 SmPL semantic patch로 커널 코드의 구조적 패턴을 찾아 보고하거나 일괄 변환합니다. 커널의 `make coccicheck` 프런트엔드는 `report`, `patch`, `context`, `org` mode와 COCCI, M, C, J 같은 변수를 조합해 검사 종류와 범위를 제어합니다.

정적 분석 결과에는 false positive가 있을 수 있으므로 생성된 보고서와 patch를 사람이 검토해야 합니다. 재현성과 성능을 위해 Coccinelle 버전, `.cocciconfig` 우선순위, SPFLAGS, index database 및 병렬 실행의 오류 반환도 함께 확인하는 것이 중요합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. Copyright 2010 Nicolas Palix <npalix@diku.dk>
2 .. Copyright 2010 Julia Lawall <julia@diku.dk>
3 .. Copyright 2010 Gilles Muller <Gilles.Muller@lip6.fr>
4
5 .. highlight:: none
6
7 .. _devtools_coccinelle:
8
9 Coccinelle
10 ==========
11
12 Coccinelle is a tool for pattern matching and text transformation that has
13 many uses in kernel development, including the application of complex,
14 tree-wide patches and detection of problematic programming patterns.
15
16 Getting Coccinelle
17 ------------------
18
19 The semantic patches included in the kernel use features and options
20 which are provided by Coccinelle version 1.0.0-rc11 and above.
21 Using earlier versions will fail as the option names used by
22 the Coccinelle files and coccicheck have been updated.
23
24 Coccinelle is available through the package manager
25 of many distributions, e.g. :
26
27 - Debian
28 - Fedora
29 - Ubuntu
30 - OpenSUSE
31 - Arch Linux
32 - NetBSD
33 - FreeBSD
34
35 Some distribution packages are obsolete and it is recommended
36 to use the latest version released from the Coccinelle homepage at
37 http://coccinelle.lip6.fr/
38
39 Or from Github at:
40
41 https://github.com/coccinelle/coccinelle
42
43 Once you have it, run the following commands::
44
45 ./autogen
46 ./configure
47 make
48
49 as a regular user, and install it with::
50
51 sudo make install
52
53 More detailed installation instructions to build from source can be
54 found at:
55
56 https://github.com/coccinelle/coccinelle/blob/master/install.txt
57
58 Supplemental documentation
59 --------------------------
60
61 For supplemental documentation refer to the wiki:
62
63 https://bottest.wiki.kernel.org/coccicheck
64
65 The wiki documentation always refers to the linux-next version of the script.
66
67 For Semantic Patch Language(SmPL) grammar documentation refer to:
68
69 https://coccinelle.gitlabpages.inria.fr/website/docs/main_grammar.html
70
71 Using Coccinelle on the Linux kernel
72 ------------------------------------
73
74 A Coccinelle-specific target is defined in the top level
75 Makefile. This target is named ``coccicheck`` and calls the ``coccicheck``
76 front-end in the ``scripts`` directory.
77
78 Four basic modes are defined: ``patch``, ``report``, ``context``, and
79 ``org``. The mode to use is specified by setting the MODE variable with
80 ``MODE=<mode>``.
81
82 - ``patch`` proposes a fix, when possible.
83
84 - ``report`` generates a list in the following format:
85 file:line:column-column: message
86
87 - ``context`` highlights lines of interest and their context in a
88 diff-like style. Lines of interest are indicated with ``-``.
89
90 - ``org`` generates a report in the Org mode format of Emacs.
91
92 Note that not all semantic patches implement all modes. For easy use
93 of Coccinelle, the default mode is "report".
94
95 Two other modes provide some common combinations of these modes.
96
97 - ``chain`` tries the previous modes in the order above until one succeeds.
98
99 - ``rep+ctxt`` runs successively the report mode and the context mode.
100 It should be used with the C option (described later)
101 which checks the code on a file basis.
102
103 Examples
104 ~~~~~~~~
105
106 To make a report for every semantic patch, run the following command::
107
108 make coccicheck MODE=report
109
110 To produce patches, run::
111
112 make coccicheck MODE=patch
113
114
115 The coccicheck target applies every semantic patch available in the
116 sub-directories of ``scripts/coccinelle`` to the entire Linux kernel.
117
118 For each semantic patch, a commit message is proposed. It gives a
119 description of the problem being checked by the semantic patch, and
120 includes a reference to Coccinelle.
121
122 As with any static code analyzer, Coccinelle produces false
123 positives. Thus, reports must be carefully checked, and patches
124 reviewed.
125
126 To enable verbose messages set the V= variable, for example::
127
128 make coccicheck MODE=report V=1
129
130 Coccinelle parallelization
131 --------------------------
132
133 By default, coccicheck tries to run as parallel as possible. To change
134 the parallelism, set the J= variable. For example, to run across 4 CPUs::
135
136 make coccicheck MODE=report J=4
137
138 As of Coccinelle 1.0.2 Coccinelle uses Ocaml parmap for parallelization;
139 if support for this is detected you will benefit from parmap parallelization.
140
141 When parmap is enabled coccicheck will enable dynamic load balancing by using
142 ``--chunksize 1`` argument. This ensures we keep feeding threads with work
143 one by one, so that we avoid the situation where most work gets done by only
144 a few threads. With dynamic load balancing, if a thread finishes early we keep
145 feeding it more work.
146
147 When parmap is enabled, if an error occurs in Coccinelle, this error
148 value is propagated back, and the return value of the ``make coccicheck``
149 command captures this return value.
150
151 Using Coccinelle with a single semantic patch
152 ---------------------------------------------
153
154 The optional make variable COCCI can be used to check a single
155 semantic patch. In that case, the variable must be initialized with
156 the name of the semantic patch to apply.
157
158 For instance::
159
160 make coccicheck COCCI=<my_SP.cocci> MODE=patch
161
162 or::
163
164 make coccicheck COCCI=<my_SP.cocci> MODE=report
165
166
167 Controlling Which Files are Processed by Coccinelle
168 ---------------------------------------------------
169
170 By default the entire kernel source tree is checked.
171
172 To apply Coccinelle to a specific directory, ``M=`` can be used.
173 For example, to check drivers/net/wireless/ one may write::
174
175 make coccicheck M=drivers/net/wireless/
176
177 To apply Coccinelle on a file basis, instead of a directory basis, the
178 C variable is used by the makefile to select which files to work with.
179 This variable can be used to run scripts for the entire kernel, a
180 specific directory, or for a single file.
181
182 For example, to check drivers/bluetooth/bfusb.c, the value 1 is
183 passed to the C variable to check files that make considers
184 need to be compiled.::
185
186 make C=1 CHECK=scripts/coccicheck drivers/bluetooth/bfusb.o
187
188 The value 2 is passed to the C variable to check files regardless of
189 whether they need to be compiled or not.::
190
191 make C=2 CHECK=scripts/coccicheck drivers/bluetooth/bfusb.o
192
193 In these modes, which work on a file basis, there is no information
194 about semantic patches displayed, and no commit message proposed.
195
196 This runs every semantic patch in scripts/coccinelle by default. The
197 COCCI variable may additionally be used to only apply a single
198 semantic patch as shown in the previous section.
199
200 The "report" mode is the default. You can select another one with the
201 MODE variable explained above.
202
203 Debugging Coccinelle SmPL patches
204 ---------------------------------
205
206 Using coccicheck is best as it provides in the spatch command line
207 include options matching the options used when we compile the kernel.
208 You can learn what these options are by using V=1; you could then
209 manually run Coccinelle with debug options added.
210
211 Alternatively you can debug running Coccinelle against SmPL patches
212 by asking for stderr to be redirected to stderr. By default stderr
213 is redirected to /dev/null; if you'd like to capture stderr you
214 can specify the ``DEBUG_FILE="file.txt"`` option to coccicheck. For
215 instance::
216
217 rm -f cocci.err
218 make coccicheck COCCI=scripts/coccinelle/free/kfree.cocci MODE=report DEBUG_FILE=cocci.err
219 cat cocci.err
220
221 You can use SPFLAGS to add debugging flags; for instance you may want to
222 add both ``--profile --show-trying`` to SPFLAGS when debugging. For example
223 you may want to use::
224
225 rm -f err.log
226 export COCCI=scripts/coccinelle/misc/irqf_oneshot.cocci
227 make coccicheck DEBUG_FILE="err.log" MODE=report SPFLAGS="--profile --show-trying" M=./drivers/mfd
228
229 err.log will now have the profiling information, while stdout will
230 provide some progress information as Coccinelle moves forward with
231 work.
232
233 NOTE:
234
235 DEBUG_FILE support is only supported when using coccinelle >= 1.0.2.
236
237 Currently, DEBUG_FILE support is only available to check folders, and
238 not single files. This is because checking a single file requires spatch
239 to be called twice leading to DEBUG_FILE being set both times to the same value,
240 giving rise to an error.
241
242 .cocciconfig support
243 --------------------
244
245 Coccinelle supports reading .cocciconfig for default Coccinelle options that
246 should be used every time spatch is spawned. The order of precedence for
247 variables for .cocciconfig is as follows:
248
249 - Your current user's home directory is processed first
250 - Your directory from which spatch is called is processed next
251 - The directory provided with the ``--dir`` option is processed last, if used
252
253 ``make coccicheck`` also supports using M= targets. If you do not supply
254 any M= target, it is assumed you want to target the entire kernel.
255 The kernel coccicheck script has::
256
257 OPTIONS="--dir $srcroot $COCCIINCLUDE"
258
259 Here, $srcroot refers to the source directory of the target: it points to the
260 external module's source directory when M= used, and otherwise, to the kernel
261 source directory. The third rule ensures the spatch reads the .cocciconfig from
262 the target directory, allowing external modules to have their own .cocciconfig
263 file.
264
265 If not using the kernel's coccicheck target, keep the above precedence
266 order logic of .cocciconfig reading. If using the kernel's coccicheck target,
267 override any of the kernel's .coccicheck's settings using SPFLAGS.
268
269 We help Coccinelle when used against Linux with a set of sensible default
270 options for Linux with our own Linux .cocciconfig. This hints to coccinelle
271 that git can be used for ``git grep`` queries over coccigrep. A timeout of 200
272 seconds should suffice for now.
273
274 The options picked up by coccinelle when reading a .cocciconfig do not appear
275 as arguments to spatch processes running on your system. To confirm what
276 options will be used by Coccinelle run::
277
278 spatch --print-options-only
279
280 You can override with your own preferred index option by using SPFLAGS. Take
281 note that when there are conflicting options Coccinelle takes precedence for
282 the last options passed. Using .cocciconfig is possible to use idutils, however
283 given the order of precedence followed by Coccinelle, since the kernel now
284 carries its own .cocciconfig, you will need to use SPFLAGS to use idutils if
285 desired. See below section "Additional flags" for more details on how to use
286 idutils.
287
288 Additional flags
289 ----------------
290
291 Additional flags can be passed to spatch through the SPFLAGS
292 variable. This works as Coccinelle respects the last flags
293 given to it when options are in conflict. ::
294
295 make SPFLAGS=--use-glimpse coccicheck
296
297 Coccinelle supports idutils as well but requires coccinelle >= 1.0.6.
298 When no ID file is specified coccinelle assumes your ID database file
299 is in the file .id-utils.index on the top level of the kernel. Coccinelle
300 carries a script scripts/idutils_index.sh which creates the database with::
301
302 mkid -i C --output .id-utils.index
303
304 If you have another database filename you can also just symlink with this
305 name. ::
306
307 make SPFLAGS=--use-idutils coccicheck
308
309 Alternatively you can specify the database filename explicitly, for
310 instance::
311
312 make SPFLAGS="--use-idutils /full-path/to/ID" coccicheck
313
314 See ``spatch --help`` to learn more about spatch options.
315
316 Note that the ``--use-glimpse`` and ``--use-idutils`` options
317 require external tools for indexing the code. None of them is
318 thus active by default. However, by indexing the code with
319 one of these tools, and according to the cocci file used,
320 spatch could proceed the entire code base more quickly.
321
322 SmPL patch specific options
323 ---------------------------
324
325 SmPL patches can have their own requirements for options passed
326 to Coccinelle. SmPL patch-specific options can be provided by
327 providing them at the top of the SmPL patch, for instance::
328
329 // Options: --no-includes --include-headers
330
331 SmPL patch Coccinelle requirements
332 ----------------------------------
333
334 As Coccinelle features get added some more advanced SmPL patches
335 may require newer versions of Coccinelle. If an SmPL patch requires
336 a minimum version of Coccinelle, this can be specified as follows,
337 as an example if requiring at least Coccinelle >= 1.0.5::
338
339 // Requires: 1.0.5
340
341 Proposing new semantic patches
342 ------------------------------
343
344 New semantic patches can be proposed and submitted by kernel
345 developers. For sake of clarity, they should be organized in the
346 sub-directories of ``scripts/coccinelle/``.
347
348
349 Detailed description of the ``report`` mode
350 -------------------------------------------
351
352 ``report`` generates a list in the following format::
353
354 file:line:column-column: message
355
356 Example
357 ~~~~~~~
358
359 Running::
360
361 make coccicheck MODE=report COCCI=scripts/coccinelle/api/err_cast.cocci
362
363 will execute the following part of the SmPL script::
364
365 <smpl>
366 @r depends on !context && !patch && (org || report)@
367 expression x;
368 position p;
369 @@
370
371 ERR_PTR@p(PTR_ERR(x))
372
373 @script:python depends on report@
374 p << r.p;
375 x << r.x;
376 @@
377
378 msg="ERR_CAST can be used with %s" % (x)
379 coccilib.report.print_report(p[0], msg)
380 </smpl>
381
382 This SmPL excerpt generates entries on the standard output, as
383 illustrated below::
384
385 /home/user/linux/crypto/ctr.c:188:9-16: ERR_CAST can be used with alg
386 /home/user/linux/crypto/authenc.c:619:9-16: ERR_CAST can be used with auth
387 /home/user/linux/crypto/xts.c:227:9-16: ERR_CAST can be used with alg
388
389
390 Detailed description of the ``patch`` mode
391 ------------------------------------------
392
393 When the ``patch`` mode is available, it proposes a fix for each problem
394 identified.
395
396 Example
397 ~~~~~~~
398
399 Running::
400
401 make coccicheck MODE=patch COCCI=scripts/coccinelle/api/err_cast.cocci
402
403 will execute the following part of the SmPL script::
404
405 <smpl>
406 @ depends on !context && patch && !org && !report @
407 expression x;
408 @@
409
410 - ERR_PTR(PTR_ERR(x))
411 + ERR_CAST(x)
412 </smpl>
413
414 This SmPL excerpt generates patch hunks on the standard output, as
415 illustrated below::
416
417 diff -u -p a/crypto/ctr.c b/crypto/ctr.c
418 --- a/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
419 +++ b/crypto/ctr.c 2010-06-03 23:44:49.000000000 +0200
420 @@ -185,7 +185,7 @@ static struct crypto_instance *crypto_ct
421 alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
422 CRYPTO_ALG_TYPE_MASK);
423 if (IS_ERR(alg))
424 - return ERR_PTR(PTR_ERR(alg));
425 + return ERR_CAST(alg);
426
427 /* Block size must be >= 4 bytes. */
428 err = -EINVAL;
429
430 Detailed description of the ``context`` mode
431 --------------------------------------------
432
433 ``context`` highlights lines of interest and their context
434 in a diff-like style.
435
436 **NOTE**: The diff-like output generated is NOT an applicable patch. The
437 intent of the ``context`` mode is to highlight the important lines
438 (annotated with minus, ``-``) and gives some surrounding context
439 lines around. This output can be used with the diff mode of
440 Emacs to review the code.
441
442 Example
443 ~~~~~~~
444
445 Running::
446
447 make coccicheck MODE=context COCCI=scripts/coccinelle/api/err_cast.cocci
448
449 will execute the following part of the SmPL script::
450
451 <smpl>
452 @ depends on context && !patch && !org && !report@
453 expression x;
454 @@
455
456 * ERR_PTR(PTR_ERR(x))
457 </smpl>
458
459 This SmPL excerpt generates diff hunks on the standard output, as
460 illustrated below::
461
462 diff -u -p /home/user/linux/crypto/ctr.c /tmp/nothing
463 --- /home/user/linux/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
464 +++ /tmp/nothing
465 @@ -185,7 +185,6 @@ static struct crypto_instance *crypto_ct
466 alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
467 CRYPTO_ALG_TYPE_MASK);
468 if (IS_ERR(alg))
469 - return ERR_PTR(PTR_ERR(alg));
470
471 /* Block size must be >= 4 bytes. */
472 err = -EINVAL;
473
474 Detailed description of the ``org`` mode
475 ----------------------------------------
476
477 ``org`` generates a report in the Org mode format of Emacs.
478
479 Example
480 ~~~~~~~
481
482 Running::
483
484 make coccicheck MODE=org COCCI=scripts/coccinelle/api/err_cast.cocci
485
486 will execute the following part of the SmPL script::
487
488 <smpl>
489 @r depends on !context && !patch && (org || report)@
490 expression x;
491 position p;
492 @@
493
494 ERR_PTR@p(PTR_ERR(x))
495
496 @script:python depends on org@
497 p << r.p;
498 x << r.x;
499 @@
500
501 msg="ERR_CAST can be used with %s" % (x)
502 msg_safe=msg.replace("[","@(").replace("]",")")
503 coccilib.org.print_todo(p[0], msg_safe)
504 </smpl>
505
506 This SmPL excerpt generates Org entries on the standard output, as
507 illustrated below::
508
509 * TODO [[view:/home/user/linux/crypto/ctr.c::face=ovl-face1::linb=188::colb=9::cole=16][ERR_CAST can be used with alg]]
510 * TODO [[view:/home/user/linux/crypto/authenc.c::face=ovl-face1::linb=619::colb=9::cole=16][ERR_CAST can be used with auth]]
511 * TODO [[view:/home/user/linux/crypto/xts.c::face=ovl-face1::linb=227::colb=9::cole=16][ERR_CAST can be used with alg]]
512

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Coccinelle 소개와 설치

1-70

저작권 2010 Nicolas Palix <npalix@diku.dk>

저작권 2010 Julia Lawall <julia@diku.dk>

저작권 2010 Gilles Muller <Gilles.Muller@lip6.fr>

Coccinelle

Coccinelle은 패턴 일치와 텍스트 변환을 수행하는 도구입니다. 복잡한 트리 전체 패치 적용과 문제가 있는 프로그래밍 패턴 탐지를 비롯해 커널 개발에서 다양한 용도로 사용됩니다.

Coccinelle 구하기

커널에 포함된 semantic patch는 Coccinelle 1.0.0-rc11 이상에서 제공하는 기능과 옵션을 사용합니다. Coccinelle 파일과 coccicheck에서 사용하는 옵션 이름이 갱신되었으므로 이전 버전을 사용하면 실패합니다.

Coccinelle은 Debian, Fedora, Ubuntu, OpenSUSE, Arch Linux, NetBSD, FreeBSD 등 여러 배포판의 패키지 관리자를 통해 설치할 수 있습니다.

일부 배포판 패키지는 오래되었으므로 Coccinelle 홈페이지에서 공개한 최신 버전을 사용하는 것이 좋습니다.

http://coccinelle.lip6.fr/

또는 다음 GitHub 저장소에서 받을 수 있습니다.

https://github.com/coccinelle/coccinelle

소스를 받은 뒤 일반 사용자로 다음 명령을 실행하십시오.

./autogen
./configure
make

그런 다음 다음 명령으로 설치하십시오.

sudo make install

소스 빌드에 관한 더 자세한 설치 지침은 다음 위치에 있습니다.

https://github.com/coccinelle/coccinelle/blob/master/install.txt

보충 문서

보충 문서는 다음 wiki를 참조하십시오.

https://bottest.wiki.kernel.org/coccicheck

wiki 문서는 항상 linux-next 버전의 스크립트를 기준으로 합니다.

Semantic Patch Language(SmPL) 문법 문서는 다음을 참조하십시오.

https://coccinelle.gitlabpages.inria.fr/website/docs/main_grammar.html

Linux 커널에서 Coccinelle 사용

71-129

Linux 커널에서 Coccinelle 사용

최상위 Makefile에는 Coccinelle 전용 target이 정의되어 있습니다. 이 target의 이름은 `coccicheck`이며 `scripts` 디렉터리의 `coccicheck` 프런트엔드를 호출합니다.

네 가지 기본 mode는 `patch`, `report`, `context`, `org`입니다. 사용할 mode는 `MODE=<mode>`로 MODE 변수를 설정해 지정합니다.

`patch`는 가능할 때 수정안을 제안합니다.

`report`는 `file:line:column-column: message` 형식의 목록을 생성합니다.

`context`는 관심 있는 줄과 그 주변을 diff와 비슷한 스타일로 강조합니다. 관심 있는 줄은 `-`로 표시합니다.

`org`는 Emacs의 Org mode 형식으로 보고서를 생성합니다.

모든 semantic patch가 모든 mode를 구현하는 것은 아닙니다. Coccinelle을 쉽게 사용할 수 있도록 기본 mode는 `report`입니다.

그 밖의 두 mode는 앞선 mode들의 일반적인 조합을 제공합니다.

`chain`은 앞의 mode들을 위 순서대로 시도해 하나가 성공할 때까지 진행합니다.

`rep+ctxt`는 report mode와 context mode를 차례로 실행합니다. 파일 단위로 코드를 검사하는 C 옵션과 함께 사용해야 합니다. C 옵션은 뒤에서 설명합니다.

예제

모든 semantic patch에 대해 보고서를 만들려면 다음 명령을 실행하십시오.

make coccicheck MODE=report

패치를 생성하려면 다음을 실행하십시오.

make coccicheck MODE=patch

coccicheck target은 `scripts/coccinelle`의 하위 디렉터리에 있는 모든 semantic patch를 전체 Linux 커널에 적용합니다.

각 semantic patch마다 commit message를 제안합니다. 이 메시지는 semantic patch가 검사하는 문제를 설명하고 Coccinelle 참조를 포함합니다.

다른 정적 코드 분석기와 마찬가지로 Coccinelle도 false positive를 생성합니다. 따라서 보고서는 주의 깊게 확인하고 패치는 검토해야 합니다.

상세 메시지를 활성화하려면 V= 변수를 설정하십시오. 예를 들면 다음과 같습니다.

make coccicheck MODE=report V=1

Coccinelle 병렬화

130-150

Coccinelle 병렬화

기본적으로 coccicheck는 가능한 한 병렬로 실행하려고 합니다. 병렬도를 바꾸려면 J= 변수를 설정하십시오. 예를 들어 CPU 4개에서 실행하려면 다음과 같이 합니다.

make coccicheck MODE=report J=4

Coccinelle 1.0.2부터 Coccinelle은 병렬화에 OCaml parmap을 사용합니다. 이 지원이 감지되면 parmap 병렬화의 이점을 얻을 수 있습니다.

parmap이 활성화되면 coccicheck는 `--chunksize 1` 인수를 사용해 동적 부하 분산을 활성화합니다. 작업을 thread에 하나씩 계속 공급하므로 대부분의 작업이 소수 thread에서만 처리되는 상황을 피합니다. 동적 부하 분산에서는 thread가 일찍 끝나면 더 많은 작업을 계속 공급합니다.

parmap이 활성화된 상태에서 Coccinelle 오류가 발생하면 그 오류 값이 다시 전달되며, `make coccicheck` 명령의 반환값이 이 값을 담습니다.

단일 semantic patch 사용

151-166

단일 semantic patch로 Coccinelle 사용

선택적 make 변수 COCCI를 사용하면 semantic patch 하나만 검사할 수 있습니다. 이때 변수는 적용할 semantic patch의 이름으로 초기화해야 합니다.

예를 들면 다음과 같습니다.

make coccicheck COCCI=<my_SP.cocci> MODE=patch

또는 다음과 같이 실행합니다.

make coccicheck COCCI=<my_SP.cocci> MODE=report

Coccinelle 처리 파일 제어

167-202

Coccinelle이 처리할 파일 제어

기본적으로 전체 커널 소스 트리를 검사합니다.

특정 디렉터리에 Coccinelle을 적용하려면 `M=`을 사용할 수 있습니다. 예를 들어 `drivers/net/wireless/`를 검사하려면 다음과 같이 작성할 수 있습니다.

make coccicheck M=drivers/net/wireless/

디렉터리 단위가 아니라 파일 단위로 Coccinelle을 적용하려면 Makefile이 C 변수를 사용해 작업할 파일을 선택합니다. 이 변수로 전체 커널, 특정 디렉터리 또는 단일 파일에 스크립트를 실행할 수 있습니다.

예를 들어 `drivers/bluetooth/bfusb.c`를 검사할 때 make가 컴파일해야 한다고 판단한 파일을 검사하려면 C 변수에 값 1을 전달합니다.

make C=1 CHECK=scripts/coccicheck drivers/bluetooth/bfusb.o

컴파일 필요 여부와 관계없이 파일을 검사하려면 C 변수에 값 2를 전달합니다.

make C=2 CHECK=scripts/coccicheck drivers/bluetooth/bfusb.o

파일 단위로 동작하는 이 mode들에서는 semantic patch 정보가 표시되지 않고 commit message도 제안되지 않습니다.

기본적으로 `scripts/coccinelle`의 모든 semantic patch를 실행합니다. 앞 절에서 보인 것처럼 COCCI 변수를 추가로 사용하면 semantic patch 하나만 적용할 수 있습니다.

`report` mode가 기본값입니다. 앞서 설명한 MODE 변수로 다른 mode를 선택할 수 있습니다.

Coccinelle SmPL patch 디버깅

203-241

Coccinelle SmPL patch 디버깅

coccicheck는 커널을 컴파일할 때 쓰는 옵션과 일치하는 include 옵션을 spatch 명령행에 제공하므로 이를 사용하는 것이 가장 좋습니다. V=1을 사용하면 이 옵션들을 확인할 수 있고, 이후 debug 옵션을 추가해 Coccinelle을 직접 실행할 수 있습니다.

또는 stderr를 지정한 파일로 보내도록 요청해 SmPL patch에 대한 Coccinelle 실행을 디버깅할 수 있습니다. 기본적으로 stderr는 `/dev/null`로 리디렉션됩니다. stderr를 기록하려면 coccicheck에 `DEBUG_FILE="file.txt"` 옵션을 지정할 수 있습니다. 예를 들면 다음과 같습니다.

rm -f cocci.err
make coccicheck COCCI=scripts/coccinelle/free/kfree.cocci MODE=report DEBUG_FILE=cocci.err
cat cocci.err

SPFLAGS로 디버깅 flag를 추가할 수 있습니다. 디버깅할 때 SPFLAGS에 `--profile --show-trying`을 함께 추가할 수 있습니다. 예를 들면 다음과 같습니다.

rm -f err.log
export COCCI=scripts/coccinelle/misc/irqf_oneshot.cocci
make coccicheck DEBUG_FILE="err.log" MODE=report SPFLAGS="--profile --show-trying" M=./drivers/mfd

이제 err.log에는 profiling 정보가 기록되고, stdout에는 Coccinelle이 작업을 진행하는 동안의 일부 진행 정보가 출력됩니다.

참고:

DEBUG_FILE은 Coccinelle 1.0.2 이상에서만 지원됩니다.

현재 DEBUG_FILE은 폴더 검사에만 사용할 수 있고 단일 파일 검사에는 사용할 수 없습니다. 단일 파일을 검사하려면 spatch를 두 번 호출해야 하며, 두 호출에서 DEBUG_FILE이 같은 값으로 설정되어 오류가 발생하기 때문입니다.

.cocciconfig 지원

242-287

.cocciconfig 지원

Coccinelle은 spatch를 실행할 때마다 사용할 기본 Coccinelle 옵션을 `.cocciconfig`에서 읽을 수 있습니다. `.cocciconfig` 변수의 우선순위는 다음과 같습니다.

현재 사용자의 home directory를 먼저 처리합니다.

spatch를 호출한 directory를 그다음 처리합니다.

사용했다면 `--dir` 옵션으로 지정한 directory를 마지막에 처리합니다.

`make coccicheck`는 M= target도 지원합니다. M= target을 지정하지 않으면 전체 커널을 대상으로 한다고 간주합니다. 커널 coccicheck 스크립트에는 다음 설정이 있습니다.

OPTIONS="--dir $srcroot $COCCIINCLUDE"

여기서 `$srcroot`는 target의 source directory를 가리킵니다. M=을 사용하면 external module의 source directory를, 그렇지 않으면 kernel source directory를 가리킵니다. 세 번째 규칙은 spatch가 target directory의 `.cocciconfig`를 읽도록 보장하므로 external module이 자체 `.cocciconfig` 파일을 가질 수 있습니다.

커널의 coccicheck target을 사용하지 않는다면 위의 `.cocciconfig` 읽기 우선순위 논리를 유지하십시오. 커널의 coccicheck target을 사용한다면 SPFLAGS로 커널 `.coccicheck` 설정을 재정의하십시오.

Linux에서 Coccinelle을 사용할 때 합리적인 기본 옵션을 제공하도록 Linux 자체 `.cocciconfig`를 둡니다. 이 파일은 coccigrep 대신 `git grep` 질의에 git을 사용할 수 있음을 Coccinelle에 알려 줍니다. 현재는 200초 timeout이면 충분합니다.

Coccinelle이 `.cocciconfig`에서 읽은 옵션은 시스템에서 실행 중인 spatch process의 인수로 나타나지 않습니다. Coccinelle이 사용할 옵션을 확인하려면 다음을 실행하십시오.

spatch --print-options-only

SPFLAGS를 사용해 선호하는 index 옵션으로 재정의할 수 있습니다. 충돌하는 옵션이 있으면 Coccinelle은 마지막에 전달된 옵션을 우선한다는 점에 유의하십시오. `.cocciconfig`로 idutils를 사용할 수 있지만, Coccinelle의 우선순위와 커널 자체 `.cocciconfig` 때문에 idutils를 사용하려면 SPFLAGS가 필요합니다. 사용 방법은 아래의 '추가 flag' 절을 참조하십시오.

추가 flag와 코드 index

288-321

추가 flag

SPFLAGS 변수를 통해 spatch에 추가 flag를 전달할 수 있습니다. 옵션이 충돌하면 Coccinelle이 마지막으로 전달된 flag를 따르므로 이 방식이 동작합니다.

make SPFLAGS=--use-glimpse coccicheck

Coccinelle은 idutils도 지원하지만 Coccinelle 1.0.6 이상이 필요합니다. ID 파일을 지정하지 않으면 Coccinelle은 커널 최상위의 `.id-utils.index` 파일을 ID database로 간주합니다. Coccinelle은 다음 명령으로 database를 생성하는 `scripts/idutils_index.sh` 스크립트를 제공합니다.

mkid -i C --output .id-utils.index

database 파일 이름이 다르면 이 이름으로 symbolic link를 만들어도 됩니다.

make SPFLAGS=--use-idutils coccicheck

또는 다음 예처럼 database 파일 이름을 명시적으로 지정할 수 있습니다.

make SPFLAGS="--use-idutils /full-path/to/ID" coccicheck

spatch 옵션에 관한 자세한 내용은 `spatch --help`를 참조하십시오.

`--use-glimpse`와 `--use-idutils` 옵션은 코드를 index하는 외부 도구가 필요하므로 기본적으로 활성화되지 않습니다. 그러나 이 도구 중 하나로 코드를 index하면 사용하는 cocci 파일에 따라 spatch가 전체 code base를 더 빠르게 처리할 수 있습니다.

SmPL patch 전용 옵션과 요구 버전

322-340

SmPL patch 전용 옵션

SmPL patch는 Coccinelle에 전달할 옵션에 자체 요구 사항을 둘 수 있습니다. SmPL patch 전용 옵션은 다음 예처럼 SmPL patch 맨 위에 지정할 수 있습니다.

// Options: --no-includes --include-headers

SmPL patch의 Coccinelle 요구 사항

Coccinelle에 기능이 추가됨에 따라 더 발전된 SmPL patch는 새 버전의 Coccinelle을 요구할 수 있습니다. SmPL patch가 최소 Coccinelle 버전을 요구한다면 다음과 같이 지정할 수 있습니다. 이 예는 Coccinelle 1.0.5 이상을 요구합니다.

// Requires: 1.0.5

새 semantic patch 제안

341-348

새 semantic patch 제안

커널 개발자는 새로운 semantic patch를 제안하고 제출할 수 있습니다. 명확성을 위해 `scripts/coccinelle/`의 하위 디렉터리에 정리해야 합니다.

report mode 상세 설명

349-389

`report` mode 상세 설명

`report`는 다음 형식의 목록을 생성합니다.

file:line:column-column: message

예제

다음을 실행하면

make coccicheck MODE=report COCCI=scripts/coccinelle/api/err_cast.cocci

SmPL 스크립트의 다음 부분이 실행됩니다.

<smpl>
@r depends on !context && !patch && (org || report)@
expression x;
position p;
@@

  ERR_PTR@p(PTR_ERR(x))

@script:python depends on report@
p << r.p;
x << r.x;
@@

msg="ERR_CAST can be used with %s" % (x)
coccilib.report.print_report(p[0], msg)
</smpl>

이 SmPL 발췌문은 아래와 같이 standard output에 항목을 생성합니다.

/home/user/linux/crypto/ctr.c:188:9-16: ERR_CAST can be used with alg
/home/user/linux/crypto/authenc.c:619:9-16: ERR_CAST can be used with auth
/home/user/linux/crypto/xts.c:227:9-16: ERR_CAST can be used with alg

patch mode 상세 설명

390-429

`patch` mode 상세 설명

`patch` mode를 사용할 수 있으면 식별된 각 문제에 대한 수정안을 제안합니다.

예제

다음을 실행하면

make coccicheck MODE=patch COCCI=scripts/coccinelle/api/err_cast.cocci

SmPL 스크립트의 다음 부분이 실행됩니다.

<smpl>
@ depends on !context && patch && !org && !report @
expression x;
@@

- ERR_PTR(PTR_ERR(x))
+ ERR_CAST(x)
</smpl>

이 SmPL 발췌문은 아래와 같이 standard output에 patch hunk를 생성합니다.

diff -u -p a/crypto/ctr.c b/crypto/ctr.c
--- a/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
+++ b/crypto/ctr.c 2010-06-03 23:44:49.000000000 +0200
@@ -185,7 +185,7 @@ static struct crypto_instance *crypto_ct
     alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
                               CRYPTO_ALG_TYPE_MASK);
     if (IS_ERR(alg))
-                return ERR_PTR(PTR_ERR(alg));
+                return ERR_CAST(alg);

     /* Block size must be >= 4 bytes. */
     err = -EINVAL;

context mode 상세 설명

430-473

`context` mode 상세 설명

`context`는 관심 있는 줄과 그 주변을 diff와 비슷한 스타일로 강조합니다.

참고: 생성되는 diff 형태의 출력은 적용 가능한 patch가 아닙니다. `context` mode의 목적은 중요한 줄을 빼기 표시 `-`로 주석 처리해 강조하고 주변 context 줄을 함께 제공하는 것입니다. 이 출력은 Emacs의 diff mode에서 코드를 검토하는 데 사용할 수 있습니다.

예제

다음을 실행하면

make coccicheck MODE=context COCCI=scripts/coccinelle/api/err_cast.cocci

SmPL 스크립트의 다음 부분이 실행됩니다.

<smpl>
@ depends on context && !patch && !org && !report@
expression x;
@@

* ERR_PTR(PTR_ERR(x))
</smpl>

이 SmPL 발췌문은 아래와 같이 standard output에 diff hunk를 생성합니다.

diff -u -p /home/user/linux/crypto/ctr.c /tmp/nothing
--- /home/user/linux/crypto/ctr.c        2010-05-26 10:49:38.000000000 +0200
+++ /tmp/nothing
@@ -185,7 +185,6 @@ static struct crypto_instance *crypto_ct
     alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
                               CRYPTO_ALG_TYPE_MASK);
     if (IS_ERR(alg))
-                return ERR_PTR(PTR_ERR(alg));

     /* Block size must be >= 4 bytes. */
     err = -EINVAL;

org mode 상세 설명

474-511

`org` mode 상세 설명

`org`는 Emacs의 Org mode 형식으로 보고서를 생성합니다.

예제

다음을 실행하면

make coccicheck MODE=org COCCI=scripts/coccinelle/api/err_cast.cocci

SmPL 스크립트의 다음 부분이 실행됩니다.

<smpl>
@r depends on !context && !patch && (org || report)@
expression x;
position p;
@@

  ERR_PTR@p(PTR_ERR(x))

@script:python depends on org@
p << r.p;
x << r.x;
@@

msg="ERR_CAST can be used with %s" % (x)
msg_safe=msg.replace("[","@(").replace("]",")")
coccilib.org.print_todo(p[0], msg_safe)
</smpl>

이 SmPL 발췌문은 아래와 같이 standard output에 Org 항목을 생성합니다.

* TODO [[view:/home/user/linux/crypto/ctr.c::face=ovl-face1::linb=188::colb=9::cole=16][ERR_CAST can be used with alg]]
* TODO [[view:/home/user/linux/crypto/authenc.c::face=ovl-face1::linb=619::colb=9::cole=16][ERR_CAST can be used with auth]]
* TODO [[view:/home/user/linux/crypto/xts.c::face=ovl-face1::linb=227::colb=9::cole=16][ERR_CAST can be used with alg]]