Msphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/dev-tools/sparsemodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/zh_TW/dev-tools/sparsemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/it_IT/dev-tools/sparsemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/ja_JP/dev-tools/sparsemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/ko_KR/dev-tools/sparsemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/pt_BR/dev-tools/sparsemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/sp_SP/dev-tools/sparsemodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageChinese (Simplified)uh1h hh _documenthsourceNlineNubh paragraph)}(hyCopyright 2004 Linus Torvalds Copyright 2004 Pavel Machek Copyright 2006 Bob Copeland h](h;Copyright 2004 Linus Torvalds Copyright 2004 Pavel Machek <}(hhhhhNhNubh reference)}(h pavel@ucw.czh]h pavel@ucw.cz}(hhhhhNhNubah}(h]h ]h"]h$]h&]refurimailto:pavel@ucw.czuh1hhhubh> Copyright 2006 Bob Copeland <}(hhhhhNhNubh)}(hme@bobcopeland.comh]hme@bobcopeland.com}(hhhhhNhNubah}(h]h ]h"]h$]h&]refurimailto:me@bobcopeland.comuh1hhhubh>}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhQ/var/lib/git/docbuild/linux/Documentation/translations/zh_CN/dev-tools/sparse.rsthKhhhhubh field_list)}(hhh]hfield)}(hhh](h field_name)}(horphanh]horphan}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhh5Documentation/translations/zh_CN/disclaimer-zh_CN.rsthKubh field_body)}(hhh]h}(h]h ]h"]h$]h&]uh1j hhubeh}(h]h ]h"]h$]h&]uh1hhj hKhhhhubah}(h]h ]h"]h$]h&]uh1hhhhhhj hKubhnote)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]h)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hKhj$ubah}(h]h ]h"]h$]h&]uh1j"hhhhhj hNubh)}(hhh](h)}(hhh](h)}(hOriginalh]hOriginal}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj?hhhKubj )}(h#Documentation/dev-tools/sparse.rst h]h)}(h"Documentation/dev-tools/sparse.rsth]h"Documentation/dev-tools/sparse.rst}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjPubah}(h]h ]h"]h$]h&]uh1j hj?ubeh}(h]h ]h"]h$]h&]uh1hhhhKhj<hhubh)}(hhh](h)}(h翻译h]h翻译}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjnhhhKubj )}(hLi Yang h]h)}(hLi Yang h](h Li Yang <}(hjhhhNhNubh)}(hleoyang.li@nxp.comh]hleoyang.li@nxp.com}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurimailto:leoyang.li@nxp.comuh1hhjubh>}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hjubah}(h]h ]h"]h$]h&]uh1j hjnubeh}(h]h ]h"]h$]h&]uh1hhhhK hj<hhubh)}(hhh](h)}(h校译h]h校译}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhKubj )}(h-司延腾 Yanteng Si h]h)}(h,司延腾 Yanteng Si h](h司延腾 Yanteng Si <}(hjhhhNhNubh)}(hsiyanteng@loongson.cnh]hsiyanteng@loongson.cn}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurimailto:siyanteng@loongson.cnuh1hhjubh>}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1hhhhK hj<hhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhtarget)}(h.. _cn_sparse:h]h}(h]h ]h"]h$]h&]refid cn-sparseuh1jhKhhhhhhubhsection)}(hhh](htitle)}(hSparseh]hSparse}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hj hhhhhKubh)}(hXjSparse是一个C程序的语义检查器;它可以用来发现内核代码的一些潜在问题。 关 于sparse的概述,请参见https://lwn.net/Articles/689907/;本文档包含 一些针对内核的sparse信息。 关于sparse的更多信息,主要是关于它的内部结构,可以在它的官方网页上找到: https://sparse.docs.kernel.org。h](hXISparse是一个C程序的语义检查器;它可以用来发现内核代码的一些潜在问题。 关 于sparse的概述,请参见https://lwn.net/Articles/689907/;本文档包含 一些针对内核的sparse信息。 关于sparse的更多信息,主要是关于它的内部结构,可以在它的官方网页上找到: }(hjhhhNhNubh)}(hhttps://sparse.docs.kernel.orgh]hhttps://sparse.docs.kernel.org}(hj%hhhNhNubah}(h]h ]h"]h$]h&]refurij'uh1hhjubh。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubj )}(hhh](j)}(h#使用 sparse 工具做类型检查h]h#使用 sparse 工具做类型检查}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1j hj>hhhhhKubh)}(hD"__bitwise" 是一种类型属性,所以你应该这样使用它::h]hG“__bitwise” 是一种类型属性,所以你应该这样使用它:}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj>hhubh literal_block)}(htypedef int __bitwise pm_request_t; enum pm_request { PM_SUSPEND = (__force pm_request_t) 1, PM_RESUME = (__force pm_request_t) 2 };h]htypedef int __bitwise pm_request_t; enum pm_request { PM_SUSPEND = (__force pm_request_t) 1, PM_RESUME = (__force pm_request_t) 2 };}hj_sbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1j]hhhK!hj>hhubh)}(hXM这样会使 PM_SUSPEND 和 PM_RESUME 成为位方式(bitwise)整数(使用"__force" 是因为 sparse 会抱怨改变位方式的类型转换,但是这里我们确实需要强制进行转 换)。而且因为所有枚举值都使用了相同的类型,这里的"enum pm_request"也将 会使用那个类型做为底层实现。h]hXU这样会使 PM_SUSPEND 和 PM_RESUME 成为位方式(bitwise)整数(使用”__force” 是因为 sparse 会抱怨改变位方式的类型转换,但是这里我们确实需要强制进行转 换)。而且因为所有枚举值都使用了相同的类型,这里的”enum pm_request”也将 会使用那个类型做为底层实现。}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK(hj>hhubh)}(h而且使用 gcc 编译的时候,所有的 __bitwise/__force 都会消失,最后在 gcc 看来它们只不过是普通的整数。h]h而且使用 gcc 编译的时候,所有的 __bitwise/__force 都会消失,最后在 gcc 看来它们只不过是普通的整数。}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK-hj>hhubh)}(h~坦白来说,你并不需要使用枚举类型。上面那些实际都可以浓缩成一个特殊的"int __bitwise"类型。h]h坦白来说,你并不需要使用枚举类型。上面那些实际都可以浓缩成一个特殊的”int __bitwise”类型。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK0hj>hhubh)}(h)所以更简单的办法只要这样做::h]h(所以更简单的办法只要这样做:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK3hj>hhubj^)}(htypedef int __bitwise pm_request_t; #define PM_SUSPEND ((__force pm_request_t) 1) #define PM_RESUME ((__force pm_request_t) 2)h]htypedef int __bitwise pm_request_t; #define PM_SUSPEND ((__force pm_request_t) 1) #define PM_RESUME ((__force pm_request_t) 2)}hjsbah}(h]h ]h"]h$]h&]jmjnuh1j]hhhK5hj>hhubh)}(hH现在你就有了严格的类型检查所需要的所有基础架构。h]hH现在你就有了严格的类型检查所需要的所有基础架构。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK:hj>hhubh)}(hX[一个小提醒:常数整数"0"是特殊的。你可以直接把常数零当作位方式整数使用而 不用担心 sparse 会抱怨。这是因为"bitwise"(恰如其名)是用来确保不同位方 式类型不会被弄混(小尾模式,大尾模式,cpu尾模式,或者其他),对他们来说 常数"0"确实 **是** 特殊的。h](hXS一个小提醒:常数整数”0”是特殊的。你可以直接把常数零当作位方式整数使用而 不用担心 sparse 会抱怨。这是因为”bitwise”(恰如其名)是用来确保不同位方 式类型不会被弄混(小尾模式,大尾模式,cpu尾模式,或者其他),对他们来说 常数”0”确实 }(hjhhhNhNubhstrong)}(h**是**h]h是}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 特殊的。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhubj )}(hhh](j)}(h使用sparse进行锁检查h]h使用sparse进行锁检查}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjhhhhhKBubh)}(h下面的宏对于 gcc 来说是未定义的,在 sparse 运行时定义,以使用sparse的“上下文” 跟踪功能,应用于锁定。 这些注释告诉 sparse 什么时候有锁,以及注释的函数的进入和 退出。h]h下面的宏对于 gcc 来说是未定义的,在 sparse 运行时定义,以使用sparse的“上下文” 跟踪功能,应用于锁定。 这些注释告诉 sparse 什么时候有锁,以及注释的函数的进入和 退出。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKDhjhhubh)}(hA__must_hold - 指定的锁在函数进入和退出时被持有。h]hA__must_hold - 指定的锁在函数进入和退出时被持有。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKHhjhhubh)}(hV__acquires - 指定的锁在函数退出时被持有,但在进入时不被持有。h]hV__acquires - 指定的锁在函数退出时被持有,但在进入时不被持有。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKJhjhhubh)}(hV__releases - 指定的锁在函数进入时被持有,但在退出时不被持有。h]hV__releases - 指定的锁在函数进入时被持有,但在退出时不被持有。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKLhjhhubh)}(h如果函数在不持有锁的情况下进入和退出,在函数内部以平衡的方式获取和释放锁,则不 需要注释。 上面的三个注释是针对sparse否则会报告上下文不平衡的情况。h]h如果函数在不持有锁的情况下进入和退出,在函数内部以平衡的方式获取和释放锁,则不 需要注释。 上面的三个注释是针对sparse否则会报告上下文不平衡的情况。}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKNhjhhubeh}(h]id2ah ]h"]使用sparse进行锁检查ah$]h&]uh1jhj>hhhhhKBubeh}(h]id1ah ]h"]#使用 sparse 工具做类型检查ah$]h&]uh1jhj hhhhhKubj )}(hhh](j)}(h获取 sparse 工具h]h获取 sparse 工具}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjLhhhhhKSubh)}(h;你可以从 Sparse 的主页获取最新的发布版本:h]h;你可以从 Sparse 的主页获取最新的发布版本:}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKUhjLhhubh block_quote)}(h7https://www.kernel.org/pub/software/devel/sparse/dist/ h]h)}(h6https://www.kernel.org/pub/software/devel/sparse/dist/h]h)}(hjsh]h6https://www.kernel.org/pub/software/devel/sparse/dist/}(hjuhhhNhNubah}(h]h ]h"]h$]h&]refurijsuh1hhjqubah}(h]h ]h"]h$]h&]uh1hhhhKWhjmubah}(h]h ]h"]h$]h&]uh1jkhhhKWhjLhhubh)}(hF或者,你也可以使用 git 克隆最新的 sparse 开发版本:h]hF或者,你也可以使用 git 克隆最新的 sparse 开发版本:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKYhjLhhubjl)}(h5git://git.kernel.org/pub/scm/devel/sparse/sparse.git h]h)}(h4git://git.kernel.org/pub/scm/devel/sparse/sparse.gith]h4git://git.kernel.org/pub/scm/devel/sparse/sparse.git}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK[hjubah}(h]h ]h"]h$]h&]uh1jkhhhK[hjLhhubh)}(h?一旦你下载了源码,只要以普通用户身份运行:h]h?一旦你下载了源码,只要以普通用户身份运行:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK]hjLhhubjl)}(hmake make install h]h)}(hmake make installh]hmake make install}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK_hjubah}(h]h ]h"]h$]h&]uh1jkhhhK_hjLhhubh)}(hM如果是标准的用户,它将会被自动安装到你的~/bin目录下。h]hM如果是标准的用户,它将会被自动安装到你的~/bin目录下。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKbhjLhhubeh}(h]id3ah ]h"]获取 sparse 工具ah$]h&]uh1jhj hhhhhKSubj )}(hhh](j)}(h使用 sparse 工具h]h使用 sparse 工具}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjhhhhhKeubh)}(hX用"make C=1"命令来编译内核,会对所有重新编译的 C 文件使用 sparse 工具。 或者使用"make C=2"命令,无论文件是否被重新编译都会对其使用 sparse 工具。 如果你已经编译了内核,用后一种方式可以很快地检查整个源码树。h]hX'用”make C=1”命令来编译内核,会对所有重新编译的 C 文件使用 sparse 工具。 或者使用”make C=2”命令,无论文件是否被重新编译都会对其使用 sparse 工具。 如果你已经编译了内核,用后一种方式可以很快地检查整个源码树。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKghjhhubh)}(hmake 的可选变量 CHECKFLAGS 可以用来向 sparse 工具传递参数。编译系统会自 动向 sparse 工具传递 -Wbitwise 参数。h]hmake 的可选变量 CHECKFLAGS 可以用来向 sparse 工具传递参数。编译系统会自 动向 sparse 工具传递 -Wbitwise 参数。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKkhjhhubh)}(h5注意sparse定义了__CHECKER__预处理器符号。h]h5注意sparse定义了__CHECKER__预处理器符号。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKnhjhhubeh}(h]id4ah ]h"]使用 sparse 工具ah$]h&]uh1jhj hhhhhKeubeh}(h](sparsejeh ]h"](sparse cn_sparseeh$]h&]uh1jhhhhhhhKexpect_referenced_by_name}j:jsexpect_referenced_by_id}jjsubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(j N generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjderror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}j]jasnameids}(j:jj9j6jIjFjAj>jjj1j.u nametypes}(j:j9jIjAjj1uh}(jj j6j jFj>j>jjjLj.ju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jrKsRparse_messages]transform_messages]hsystem_message)}(hhh]h)}(hhh]h/Hyperlink target "cn-sparse" is not referenced.}hjsbah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcehlineKuh1juba transformerN include_log]5Documentation/translations/zh_CN/dev-tools/sparse.rst(NNNNta decorationNhhub.