Learning Record:CS110L
date
Apr 17, 2022
slug
cs110l
tags
Course
summary
type
Post
status
Published
TL;DR CS110L:Safety in Systems Programming主要讲Rust语言,课程着重讲Rust是如何避免各种安全问题的,从单机场景下的内存安全,到多进程、多线程下的并发安全。更多的课程相关信息可以参考: - 官网:https://web.stanford.edu/class/cs110l/ - CS自学指南:https://csdiy.wiki/编程入门/CS110L/ - 公开课评价网:https://conanhujinming.github.io/comments-for-awesome-courses/编程语言/StandfordCS110L系统编程中的安全(Rust)/
程序分析
Lecture #01,Lecture #02,Week1 Exercise
这个部分主要是讲在C,C++上的程序分析,介绍了基本的程序分析方法以及工具。
动态分析主要介绍了Valgrind和Sanitizers工具。
- Valgrind主要是在二进制代码中插入代码进行跟踪
- Sanitizers是在源代码层面上插入代码进行跟踪
动态分析的局限在于只能检测出实际发生的错误。因此,动态分析需要足够大的输入数据分布来暴露出程序的问题。为了得到更多样的输入,还介绍了随机化输入技术Fuzzing。
静态分析主要介绍了数据流的静态分析方式。
Week1 Exercise是关于这一节课的练习,主要引导我们利用clang-tidy(静态分析),Valgrind(动态分析),Sanitizers(动态分析),libFuzzer(Fuzzing)工具来检测程序中出现的bug,在实践中体会程序分析。
内存安全
Lecture #03,Lecture #04,Lecture #05,Week3 Exercise
这个部分主要讲Rust的Ownership Rule和Borrow Rule,是Rust的核心。通过以一些C++和Rust的例子的对比,说明Rust是如何通过这些规则来保证内存安全的。
最后讲了Rust的错误处理,Rust的错误处理方式很大程度上帮助Rust避免了空指针和悬空指针的问题。通过对比C(返回错误代码),C++(异常),Rust(Enums),三种编程语言的错误处理方式,体现Rust错误处理的优势,我认为Rust的错误处理主要有三个特点:
- Enum类型保证了错误一定会被处理,Rust中错误和有效值一定是两种类型,错误无法被忽略
- ?语言糖帮助更方便进行错误传播
- panic直接中止程序,暴露出错误
实践中,错误应该向外传播还是直接中止,我觉得下图给了一个很好的指导原则

编程特性
Lecture #06,Lecture #07,Lecture #08,Lecture #08
这一部分主要讲Rust的一些编程特性,包括:
- 自定义类型:用Rust写单向链表做例子
- OOP
- 泛型编程
多进程
Lecture #10,Lecture #11
主要内容是分析Linux中进程,以及进程间通信方式接口的一些缺陷,比如:
- fork()是不安全的
- fork()与线程混用很容易出错
- pipe是不安全的
- pipe的表示是整形,很容易误用
- signal是不安全的
针对这些问题,Rust提供了一些更高层的接口来保证安全使用:
- Command代替fork
- Pipe类型
最后,还分析了Chrome的架构。在复杂的浏览器架构下,虽然多线程会得到更好的性能以及其他好处,但是为了安全和隔离性,Chrome还是采用多进程架构。
Project1: The DEET Debugger
该课程的第一个小项目,写一个简单的debug工具,难度不难,因为框架都搭好了,ptrace的使用接口也封装好了,逻辑也不难。主要是体验一下Rust还有浅层的了解一下debug工具是如何通过ptrace实现的。
多线程
Lecture #12,Lecture #13
主要介绍Rust是如何进行多线程编程的,以及是如何是如何避免并发问题:
- Ownership Rule,Borrow Rule在多线程上的作用
- multiple ownership
- safety type
有趣的是,Rust这些保证内存安全的规则竟也能有效地用于解决并发问题。除此之外,在Rust的高层抽象下,个人认为Rust的多线程编程模型也相当简洁易懂。