From 043cc962321ee2ee371896fa0879562601c55ae1 Mon Sep 17 00:00:00 2001 From: Ranger Date: Tue, 13 Oct 2020 07:59:48 +0800 Subject: [PATCH] Init commit --- .gitignore | 16 + LICENSE | 427 ++++++++++++++++++++++++ README.md | 12 + SUMMARY.md | 15 + src/README.md | 11 + src/ch0/00-01-why-SPA.assets/PL.png | Bin 0 -> 88651 bytes src/ch0/00-01-why-SPA.md | 35 ++ src/ch0/00-02-why-this-book.md | 39 +++ src/ch0/00-03-sources-and-license.md | 13 + src/ch0/README.md | 3 + src/ch1/01-01-whats-spa.md | 107 ++++++ src/ch1/01-02-ir.md | 51 +++ src/ch1/README.md | 4 + src/ch2/02-00-dataflow-analysis.md | 4 + src/ch2/02-01-reaching-def-analysis.md | 4 + src/ch2/02-02-live-var-analysis.md | 4 + src/ch2/02-03-available-exp-analysis.md | 18 + src/ch2/README.md | 1 + src/ch3/03-00-dataflow-analysis.md | 4 + src/ch3/03-03-available-exp-analysis.md | 18 + src/ch3/README.md | 1 + 21 files changed, 787 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 SUMMARY.md create mode 100644 src/README.md create mode 100644 src/ch0/00-01-why-SPA.assets/PL.png create mode 100644 src/ch0/00-01-why-SPA.md create mode 100644 src/ch0/00-02-why-this-book.md create mode 100644 src/ch0/00-03-sources-and-license.md create mode 100644 src/ch0/README.md create mode 100644 src/ch1/01-01-whats-spa.md create mode 100644 src/ch1/01-02-ir.md create mode 100644 src/ch1/README.md create mode 100644 src/ch2/02-00-dataflow-analysis.md create mode 100644 src/ch2/02-01-reaching-def-analysis.md create mode 100644 src/ch2/02-02-live-var-analysis.md create mode 100644 src/ch2/02-03-available-exp-analysis.md create mode 100644 src/ch2/README.md create mode 100644 src/ch3/03-00-dataflow-analysis.md create mode 100644 src/ch3/03-03-available-exp-analysis.md create mode 100644 src/ch3/README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4cb12d8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# Node rules: +## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +## Dependency directory +## Commenting this out is preferred by some people, see +## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git +node_modules + +# Book build output +_book + +# eBook build output +*.epub +*.mobi +*.pdf diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e5ac700 --- /dev/null +++ b/LICENSE @@ -0,0 +1,427 @@ +Attribution-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-ShareAlike 4.0 International Public +License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-ShareAlike 4.0 International Public License ("Public +License"). To the extent this Public License may be interpreted as a +contract, You are granted the Licensed Rights in consideration of Your +acceptance of these terms and conditions, and the Licensor grants You +such rights in consideration of benefits the Licensor receives from +making the Licensed Material available under these terms and +conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + l. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + m. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + + including for purposes of Section 3(b); and + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..469baf1 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# Static-Program-Analysis-Book + +[Gitbook在线阅读地址](https://ranger-nju.gitbook.io/static-program-analysis-book/) + +[GitHub项目地址](https://github.com/RangerNJU/Static-Program-Analysis-Book) + +---- + +Getting started with static program analysis. Read this and start writing your first static program analyzer! + +静态程序分析入门。阅读此书并着手编写你的第一个静态程序分析器吧! + diff --git a/SUMMARY.md b/SUMMARY.md new file mode 100644 index 0000000..2870901 --- /dev/null +++ b/SUMMARY.md @@ -0,0 +1,15 @@ +# Table of contents + +* [第零章-写在前面](src/ch0/README.md) + * [静态程序分析是啥玩应啊](src/ch0/00-01-why-SPA.md) + * [为什么是这本书?](src/ch0/00-02-why-this-book.md) + * [来源与版权信息](src/ch0/00-03-sources-and-license.md) +* [第一章-静态程序分析简介](src/ch1/README.md) + * [初见——静态分析是什么?](src/ch1/01-01-whats-spa.md) + * [中间表示——静态分析器的输入](src/ch1/01-02-ir.md) +* [第二章-数据流分析的理论与应用](src/ch2/README.md) + * [数据流分析](src/ch2/02-00-dataflow-analysis.md) + * [到达定值分析](src/ch2/02-01-reaching-def-analysis.md) + * [活跃变量分析](src/ch2/02-02-live-var-analysis.md) + * [可用表达式分析](src/ch2/02-03-available-exp-analysis.md) + diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000..f409dc2 --- /dev/null +++ b/src/README.md @@ -0,0 +1,11 @@ +# Static-Program-Analysis-Book + +[Gitbook在线阅读地址](https://ranger-nju.gitbook.io/static-program-analysis-book/) + +[GitHub项目地址](https://github.com/RangerNJU/Static-Program-Analysis-Book) + +---- + +Getting started with static program analysis. Read this and start writing your first static program analyzer! + +静态程序分析入门。阅读此书并着手编写你的第一个静态程序分析器吧! diff --git a/src/ch0/00-01-why-SPA.assets/PL.png b/src/ch0/00-01-why-SPA.assets/PL.png new file mode 100644 index 0000000000000000000000000000000000000000..88cbf646c680c5289c2863bcecd60f502e53c7a5 GIT binary patch literal 88651 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

;eEfLI%6&LAnGM^(LCZ=a#h)|LM^ND0bzA#uw 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%0DsOx*gnA*laX_4`p1klWxlx2sQ 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

h@ANC0$p}GrxEU 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 literal 0 HcmV?d00001 diff --git a/src/ch0/00-01-why-SPA.md b/src/ch0/00-01-why-SPA.md new file mode 100644 index 0000000..d73eeed --- /dev/null +++ b/src/ch0/00-01-why-SPA.md @@ -0,0 +1,35 @@ +# 为什么你需要了解静态程序分析 + +## 定位 + +**静态程序分析**是**编程语言**中**应用**层面下的一个细分领域。 + +![](00-01-why-SPA.assets/PL.png) + +(TODO:举一些具体的例子) + +当今编程语言可以主要分为三大类 +- 命令式(C、C++、JAVA) +- 函数式(Scale、Haskell) +- 逻辑式(Prolog、SQL) + +*之后的内容主要关注于针对命令式语言的分析。* + +当今**编程语言**这个分支下,面临这样一条恶龙:`数十年来语言的核心没有变化,但软件的规模和复杂性增长迅速,如何保证程序的可靠性?` + +## 应用 + +静态程序分析即是屠龙的宝刀之一,掌握并应用这一技术,能够: + +1. 提高程序可靠性——Null pointer dereference, memory leak, etc.(空指针引用与内存泄漏等) +2. 提高程序安全性——Private information leak, injection attack, etc.(隐私信息泄漏与注入攻击等) +3. 为编译优化提供基础技术——Dead code elimination, code motion, etc.(死代码消除和代码向循环外移动等) +4. 有助于程序理解——IDE call hierarchy, type indication, etc.(为集成开发环境的功能提供帮助) + +## 市场 + +在学术界,静态程序分析技术几乎可以应用于所有关于程序的研究方向。 + +在工业界,国外的Google,IBM等大企业已经初步建立了自己的静态程序分析团队。国内的华为和阿里等企业也正在寻找静态程序分析方面的人才。 + +(TODO:添加更为详细的例子) \ No newline at end of file diff --git a/src/ch0/00-02-why-this-book.md b/src/ch0/00-02-why-this-book.md new file mode 100644 index 0000000..3cc75b5 --- /dev/null +++ b/src/ch0/00-02-why-this-book.md @@ -0,0 +1,39 @@ +# 为什么是这本书? + +> 你说的静态程序分析似乎有点儿用处,那么哪里可以学到呢? + +## 为什么应该读这本书? + +**1. 当前的中英文社区都缺乏这一领域的入门材料。** + +**2. 本书将带领读者,通过理论和实践的结合了解这一领域。** + +### 中文社区 + +在搜索引擎上搜索相关中文关键词,你会发现结果靠前的答案都是与某南的李老师相关的课程在B站上公开视频的笔记,其中有不少写得很好,**但并非面向一般学习者开发者的教程**。这两者有重要的区别: + +- 笔记:**面向自己**复习使用,只要自己回顾时能迅速pick up当时理解到的重点,就是一份好的笔记。 +- 教程:**面向学习者**使用,一份好教程能让学习者迅速把握领域中的重点,并且为学习者的进一步应用打下基础。 + +### 英文社区 + +在搜索引擎上搜索英文关键词,你应该能搜索到国际上的大牛们的教材式的PDF文件和相关论文,或是开源的静态分析程序。但同样**缺乏教程**。大多数材料要么艰涩难懂要么太过粗浅。根据粗略的访问,我也了解到业界认为静态程序分析技术仍不成熟。 + +### 理论与实践的结合 + +本书将同时涉及理论和实践,这主要是受到了《The Rust Programming Language》的启发。 + +### 本书写作的目标 + +能让大多数有一定编程经历,已经修过本科计算机基础课程的大四及以上学力(不是学历)的同学: + +1. 在阅读本书时能较为轻松地理解理论 +2. 能够自主完成原型实现 +3. 能在阅读过程中接触CS不同领域的小知识 + +## 为什么要写这本书? + +- 最主要的动力还是老师现场授课时我感受到的passion +- 这是一个少有人涉足的领域,写这方面的内容很符合我的性格 +- 我从开源社区中获益颇多,找到了合适的机会也希望能为开源社区(尤其是中文社区)作出自己的贡献 +- 人类发展的历史重要的两部分是传承和发展。领域先锋发展探索,亦需要有人将新的知识传播开来 diff --git a/src/ch0/00-03-sources-and-license.md b/src/ch0/00-03-sources-and-license.md new file mode 100644 index 0000000..d73168a --- /dev/null +++ b/src/ch0/00-03-sources-and-license.md @@ -0,0 +1,13 @@ +# 来源与版权信息 + +## 资料来源 + +本入门教程基于南京大学《软件分析》课程。 + +[PASCAL研究组主页](https://pascal-group.bitbucket.io/teaching.html) + +## 版权信息 + +教程文字部分遵循CC BY-NC-SA许可。 + +图片部分若无特殊说明,均为课程Slides的一部分,本书中使用这些图片已获Slides作者同意。 diff --git a/src/ch0/README.md b/src/ch0/README.md new file mode 100644 index 0000000..8d694ad --- /dev/null +++ b/src/ch0/README.md @@ -0,0 +1,3 @@ +# 写在前面 + +记录一些你在决定认真阅读本书之前需要了解的信息。 diff --git a/src/ch1/01-01-whats-spa.md b/src/ch1/01-01-whats-spa.md new file mode 100644 index 0000000..6664dc5 --- /dev/null +++ b/src/ch1/01-01-whats-spa.md @@ -0,0 +1,107 @@ +# 静态程序分析是什么 + +> 静态程序分析是指**不编译**出二进制代码通过测试用例对程序进行测试,仅通过**静态地**分析程序得到程序**不平凡**的性质的过程。 + + +## 静态程序分析的抽象定义与诠释 + +### 一句话定义(TODO:中文翻译) + +> Static analysis analyzes a program P to reason about its behaviors and determines whether it satisfies some properties befo re running P. + +### 一句话诠释(TODO:中文翻译) + +> Ensure (or get close to) soundness, while making good trade-offs between analysis precision and analysis speed. + +在分析精度和速度之间做平衡的同时,保证(或近似)soundness。 + +## 静态程序分析的具体解释 + +静态程序分析技术中最重要的两个技术,分别是Abstraction(抽象)和Over-Approximation(过近似) + +### Abstraction + +**抽象是将值从Concrete Domain(具体域)映射到Abstract Domain(抽象域)的过程。** + +举个例子:(TODO:加图) + +Concrete Domain中,变量的值可以是具体的值,也可能是某种表达式或函数的返回值。 + +Abstract Domain中,变量的值分为五类: + +- 正 +- 负 +- 零 +- unknown(未知):根据表达式或函数返回决定,程序运行时会有具体的正负零数值,但运行前只通过该表达式无法确定。如应用C语言中的三目运算符(TODO:加Link)`x = flag ? 1 : -1`中x的值就是unknown的。 +- undefined(未定):程序运行时会遇到错误,并产生未定义行为(TODO:加Link)。如许多语言中divided by zero(除数为零)通常会触发异常/硬件错误,此时如`a=b/0`中a的值就是undefined的。 + +其中unknown通常表达为正的T,读作top;undefined通常表达为上下颠倒的T,读作bottom。 + +### Over-approximation + +**过近似主要是指对抽象值进行操作时的思想。** + +继续上面的例子,具体来说操作可以分为两类:Data flow(数据流)和Control flow(控制流): + +#### Data flow + +(TODO-加图) + +- 两个正数相加为正数 +- ... +- 正数和负数相加,结果为unknown/top。**这是因为运行前只知道表达式的正负号,无法确定结果是正负零中的任何一个,但程序运行时会有具体的数值。** +- unknown/top除以0,结果为undefined。**这是因为会触发未定义行为。** + +#### Control flow + +在程序执行过程中往往会有分支结构,如果x的值在两个分支中分别被赋抽象正值和抽象负值,那么合并时x抽象值应该是五类中的哪一种呢? + +对于分支合并时的x,**运行前只知道抽象值的正负号,无法确定结果是哪一种,但程序运行时会有具体的数值**。无论是抽象为正还是负都无法准确描述x合并后的状态,所以x合并后的抽象值是unknown/top。 + + +## Rice‘s Theorem与静态程序分析目标 + +### Rice's Theorem + +> Any non-trivial property of the behavior of programs in a r.e. language is undecidable. +(TODO:加中文) + +(TODO:加中文) +这句话中有很多很难的词汇,接下来一一解释: +- non-trivial properties ~= interesting properties ~= the properties related with run-time behaviors of programs +- r.e. (recursively enumerable) 递归可枚举语⾔: recognizable by a Turing-machine +- There is no such approach to determine whether P satisfies such non-trivial properties, i.e., giving exact answer: Yes or No +- 故不存在 perfect (sound & complete) static analysis + +### 两个重要概念:Sound与Complete + +> 思考: 作为一个开发者,你使用静态分析器分析自己的代码时,哪种情况更让你觉得糟糕? +> +> - 静态分析器**没有分析出代码错误**的部分。 +> - 静态分析器**判断代码正确的部分为错**的部分。 + +Over- and under-approximations are both for safety of analysis. + +sound: 报出所有问题 may analysis: outputs information that may be true (over-approximation) (safe=over) + +complete: 报出的问题都是对的 must analysis: outputs information that must be true (under-approximation) (safe=under) + + +### 实际应用中静态分析器的设计目标 + +(TODO:加图) +**实际应用中往往没有办法做到完美。因而需要妥协。** + +需要静态分析器能在可接受的时间内给出精度满足要求的解。为此: + +妥协 soundness (false negatives 可能漏报) + +妥协 completeness (false positives 可能误报) (⼤多数情况的分析,因为 soundness 很重要) + +## 再讲五块钱的? + +### 关于未定义行为(TODO:加Link和解释) + +### 关于程序测试与分析(TODO:加程序分析的LINK和对比) + +### 关于判定问题中经常用到的术语 diff --git a/src/ch1/01-02-ir.md b/src/ch1/01-02-ir.md new file mode 100644 index 0000000..d0f9032 --- /dev/null +++ b/src/ch1/01-02-ir.md @@ -0,0 +1,51 @@ +# 中间表示——静态分析的输入 + +## 从编译器的组件谈起 + +一个典型的编译器分成一下几个部分: +- Scanner:读入源代码,借助正则表达式完成词法分析,输出Tokens或报告错误的词法输入。如`goouojd`并是一个有效的英文单词,就会被报告为错误。 +- Parser:读入Tokens,通过上下文无关文法完成语法分析,构建抽象语法树或报告错误的语法输入。如`Like your hair I`就不符合英语语法,会被报告为错误。 +- Type Checker:读入抽象语法树,以属性文法进行语义分析并检查类型兼容性等,输出Decorated AST或报告错误的语义。如`Apples eat you`在语法上正确,但不可能有苹果会吃人,这是语义上的错误。 +- Translater:读入Decorated AST,通过遍历Decorated AST将树型IR(AST)翻译为线型IR(通常是三地址码的形式)。然后可以**通过静态分析**进行机器无关的代码优化。 +- Code Generator:读入线型IR,并根据指定的CPU指令集将机器无法直接执行的IR转换为机器可直接执行的机器代码。 + +### AST与IR的比较 + +AST: +- high-level and closed to grammar structure +- usually language dependent +- suitable for fast type checking +- lack of control flow information + +即: +- 更接近于语法规定的结构 +- 通常与语言有关 +- 适于快速类型检查 +- 没有控制流信息 + +IR: +- low-level and closed to machine code +- usually language independent +- compact and uniform +- contains control flow info +- usually considered as the basis for static analysis + +即: +- 更接近于机器码 +- 通常与语言无关 +- 紧凑而通用 +- 包含控制流信息 +- 通常被视为静态分析的基础 + +**总的来说,线型IR更适合静态分析。线型IR没有固定的定义,实际使用中常用三地址码。** + +~~在计算机领域,直接用英文常常更容易将概念表达清楚,如果有读者认为有更好的翻译,可以联系作者(邮箱或github issue都可以)~~ + +### 三地址码 + +> Definition: Each 3AC contains at most 3 addresses (name, constant, temporary) + +定义:每一条三地址码最多包含3个地址(地址包括程序员显式定义的有名字变量,常量和临时变量) +一些形式 + +TBD \ No newline at end of file diff --git a/src/ch1/README.md b/src/ch1/README.md new file mode 100644 index 0000000..fa58dfb --- /dev/null +++ b/src/ch1/README.md @@ -0,0 +1,4 @@ +# 入门指南 + +在这一部分中,将介绍什么是静态程序分析(下文将简称为静态分析),这一技术有什么样的应用,为什么它值得我们去学习与研究。 + diff --git a/src/ch2/02-00-dataflow-analysis.md b/src/ch2/02-00-dataflow-analysis.md new file mode 100644 index 0000000..4d9e5c9 --- /dev/null +++ b/src/ch2/02-00-dataflow-analysis.md @@ -0,0 +1,4 @@ +# 数据流分析 + +TBD + diff --git a/src/ch2/02-01-reaching-def-analysis.md b/src/ch2/02-01-reaching-def-analysis.md new file mode 100644 index 0000000..b430fdb --- /dev/null +++ b/src/ch2/02-01-reaching-def-analysis.md @@ -0,0 +1,4 @@ +# 数据流分析之到达定值分析 + +TBD + diff --git a/src/ch2/02-02-live-var-analysis.md b/src/ch2/02-02-live-var-analysis.md new file mode 100644 index 0000000..a733705 --- /dev/null +++ b/src/ch2/02-02-live-var-analysis.md @@ -0,0 +1,4 @@ +# 数据流分析之活跃变量分析 + +TBD + diff --git a/src/ch2/02-03-available-exp-analysis.md b/src/ch2/02-03-available-exp-analysis.md new file mode 100644 index 0000000..12dd58f --- /dev/null +++ b/src/ch2/02-03-available-exp-analysis.md @@ -0,0 +1,18 @@ +# 数据流分析之可用表达式分析 + +## 定义 + +> An expression x op y is available at program point p if (1) all paths from the entry to p must pass through the evaluation of x op y, and (2) after the last evaluation of x op y, there is no redefinition of x or y. + +## 理解定义:一个tricky的例子 + +1. 按照直觉来说,c处不是,但是按照定义来说是。但是实际上运行时只会走一条分支。 + +2. 回顾: +must->under-approximation->报出来的全都是真的。不允许误报,但允许漏报 +may->不允许漏报,但允许误报 +重新理解这个例子。 + +PS. 如何记住边界条件设置谁?设置是空还是满?对余下所有块的初始化是空还是满(一个巧妙的方法是判断may/must后,如果条件汇合时是交集,一般开始时大多数块初始化为满。) + +一个经常迷惑的问题:先gen先kill?根据定义就解决所有问题2 diff --git a/src/ch2/README.md b/src/ch2/README.md new file mode 100644 index 0000000..152d806 --- /dev/null +++ b/src/ch2/README.md @@ -0,0 +1 @@ +# 数据流分析的理论与应用 diff --git a/src/ch3/03-00-dataflow-analysis.md b/src/ch3/03-00-dataflow-analysis.md new file mode 100644 index 0000000..70d2b46 --- /dev/null +++ b/src/ch3/03-00-dataflow-analysis.md @@ -0,0 +1,4 @@ +# 数据流分析例一——Reaching Definition + +TBD + diff --git a/src/ch3/03-03-available-exp-analysis.md b/src/ch3/03-03-available-exp-analysis.md new file mode 100644 index 0000000..52d0cd0 --- /dev/null +++ b/src/ch3/03-03-available-exp-analysis.md @@ -0,0 +1,18 @@ +# 可用表达式分析 + +## 定义 + +> An expression x op y is available at program point p if (1) all paths from the entry to p must pass through the evaluation of x op y, and (2) after the last evaluation of x op y, there is no redefinition of x or y. + +## 理解定义:一个tricky的例子 + +1. 按照直觉来说,c处不是,但是按照定义来说是。但是实际上运行时只会走一条分支。 + +2. 回顾: +must->under-approximation->报出来的全都是真的。不允许误报,但允许漏报 +may->不允许漏报,但允许误报 +重新理解这个例子。 + +PS. 如何记住边界条件设置谁?设置是空还是满?对余下所有块的初始化是空还是满(一个巧妙的方法是判断may/must后,如果条件汇合时是交集,一般开始时大多数块初始化为满。) + +一个经常迷惑的问题:先gen先kill?根据定义就解决所有问题2 \ No newline at end of file diff --git a/src/ch3/README.md b/src/ch3/README.md new file mode 100644 index 0000000..152d806 --- /dev/null +++ b/src/ch3/README.md @@ -0,0 +1 @@ +# 数据流分析的理论与应用