Safety in Systems Programming

The gets() function cannot be used securely. Because of its lack of bounds checking, and the inability of the calling program to reliably determine the length of the next incoming line, the use of this function enables malicious users to arbitrarily change a running program’s functionality through a buffer overflow attack. It is strongly suggested that the fgets() function be used in all cases. How can we find and/or prevent problems like this? ...

Feb 19, 2022 · 1 min · Chasing1020

Go(6) Network

Part6. Network 1. IO/Polling select 操作的不足之处: 监听能力有限 — 最多只能监听 1024 个文件描述符; 内存拷贝开销大 — 需要维护一个较大的数据结构存储文件描述符,该结构需要拷贝到内核中; 时间复杂度 O(n)O(n) — 返回准备就绪的事件个数后,需要遍历所有的文件描述符; 为了提高 I/O 多路复用的性能,不同的操作系统也都实现了自己的 I/O 多路复用函数,例如:epoll、kqueue 和 evport 等。Go 语言为了提高在不同操作系统上的 I/O 操作性能,使用平台的特定的函数实现了多个版本的网络轮询模块: ...

Oct 26, 2021 · 6 min · Chasing1020

Go(5) Concurrency

Part5. Concurrency 1. Channel 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 type hchan struct { qcount uint // total data in the queue dataqsiz uint // size of the circular queue buf unsafe.Pointer // points to an array of dataqsiz elements elemsize uint16 closed uint32 elemtype *_type // element type sendx uint // send index recvx uint // receive index recvq waitq // list of recv waiters sendq waitq // list of send waiters // lock protects all fields in hchan, as well as several // fields in sudogs blocked on this channel. // // Do not change another G's status while holding this lock // (in particular, do not ready a G), as this can deadlock // with stack shrinking. lock mutex } type waitq struct { first *sudog last *sudog } // sudog represents a g in a wait list, such as for sending/receiving // on a channel. // sudog is necessary because the g ↔ synchronization object relation // is many-to-many. A g can be on many wait lists, so there may be // many sudogs for one g; and many gs may be waiting on the same // synchronization object, so there may be many sudogs for one object. // 如果目标 Channel 没有被关闭并且已经有处于读等待的 Goroutine,那么 runtime.chansend 会从接收队列 recvq 中取出最先陷入等待的 Goroutine 并直接向它发送数据: ...

Oct 13, 2021 · 14 min · Chasing1020

Go(4) Runtime

Part4. Runtime 1. GMP 1.1. Implement 1.1.1. Data Structure 创建、销毁、调度 G 都需要每个 M 获取锁,这就形成了激烈的锁竞争。 M 转移 G 会造成延迟和额外的系统负载。比如当 G 中包含创建新协程的时候,M 创建了 G’,为了继续执行 G,需要把 G’交给 M’执行,也造成了很差的局部性,因为 G’和 G 是相关的,最好放在 M 上执行,而不是其他 M’。 系统调用 (CPU 在 M 之间的切换) 导致频繁的线程阻塞和取消阻塞操作增加了系统开销。 ...

Sep 28, 2021 · 36 min · Chasing1020

Go(3) Common Keywords

Part3. Common Keyword 1. For And Range 对于所有的 range 循环,Go 语言都会在编译期将原切片或者数组赋值给一个新变量 ha,在赋值的过程中就发生了拷贝,而我们又通过 len 关键字预先获取了切片的长度,所以在循环中追加新的元素也不会改变循环执行的次数,这也就解释了循环永动机一节提到的现象。 ...

Sep 20, 2021 · 10 min · Chasing1020