摘要:intro 之前看内核代码的时候,只是大致浏览了内核的主要常规流程:也就是正常情况下的正常流程,通常对于异常/边界场景并没有怎么关注。在遇到一些非常规问题时,就会主动或者被动的思考一些边界的异常问题。 内核的一个重要的作用就是进行各种调度(进程运行/阻塞)/同步(资源访问)/分配(内存/CPU)操作
阅读全文
摘要:intro 在多线程中,数据的安全性和程序的性能之间总是有一个平衡关系:并发控制需要使用锁来同步,而锁又总是可能引入性能损失。为了尽量在数据安全的前提下提高所得性能,linux用户态引入futex锁,内核引入RCU锁,C++中的shared_ptr都在尽量减少锁的损耗。 shared_ptr是C++
阅读全文
摘要:intro 在之前的测试中,如果严格限制了所有SNAT的源修改为特定IP+PORT,将所有发往本机137.0.01:8080的tcp都SNAT到127.0.0.1:40000端口。 tsecer@harry: sudo iptables -t nat -A POSTROUTING -p tcp -d
阅读全文
摘要:intro 作为一个分布式虚拟化系统,网络在k8s中有重要意义。不同node上pod如何基于网络进行通讯是一个需要解决的基本/重要问题。在k8s的Networking and Network Policy中提到了常用的网络策略。其中的列表显然是按照字典序(而不是使用频率)排列,其中提到了比较常用的f
阅读全文
摘要:intro 移动端的设备的应用被切到后台之后,可能就无法收到对方socket关闭连接的FIN。当应用从后台切回前台之后,可能还是继续通过这个socket来尝试向对方一个已经不存在的socket发送数据。 这种情况下,该应用网络层将会经历怎样的波折呢? 接收方 如果报文指定的socket不存在,流程会
阅读全文
摘要:intro 通常使用gdb调试器,希望知道某个系统调用的发生时机,直接在该系统调用打断点即可。这里有一个假设就是这里使用的glibc库的实现,但是go生成的可执行文件就是一个单独的、静态链接文件,在go生成文件中,gdb的时候并没有可以打断点监测系统调用的方法。 我想在go中大概率有对特定系统调用打
阅读全文
摘要:zero-page 操作系统给用户新分配的内容(通过mmap或者brk)都是清零过的,但是这些虚拟地址通常都是按需分配物理页面。这里的“按需”的需求可能是读取,也可能是写入。如果只是读取,只要保证读取内容是零即可,在MMU的基础上,可以让“所有”虚拟地址都映射到内容为0的物理页面中。 这样如果申请的
阅读全文
摘要:# setup中的header 在header.S结构中定义了一个使用汇编语言定义的hdr结构,这个结构是bootloader和内核setup代码之间通过boot协议约定的: 在哪个位置是什么字段,字段是什么意义都是bootloader和内核达成共识的,我们甚至可以认为:这个协议类似于tcp/ip的
阅读全文
摘要:拷贝二进制(elf)文件 在拷贝二进制文件的时候,如果文件是一个可执行文件,并且有一个进程在运行这个可执行文件,那么拷贝的时候会出现"文本忙"(ETXTBSY)的错误提示,并且拷贝失败。这还算是好的情况,如果拷贝的是一个so文件,并且此时这个so正在被某个进程使用,那么此时拷贝可以成功,但是可能会导
阅读全文
摘要:一、free命令的man手册说明 从这个描述可以看到,free命令的数据源主要是从/proc/meminfo文件读取 DESCRIPTION free displays the total amount of free and used physical and swap memory in the
阅读全文
摘要:一、C库对于fs值的分配 glibc-2.11\nptl\sysdeps\x86_64\tls.h线程创建时的逻辑,可以看到是执行的ARCH_SET_FS接口设置的/* Code to initially initialize the thread pointer. This might need
阅读全文
摘要:一、主要的问题 这里主要讨论的是C++中全局/静态局部对象析构函数的执行时机问题。我们知道:全局变量的初始化时在main函数执行之前完成,静态局部变量的初始化是在首次执行到所在函数时执行。但是这些对象的析构函数在什么时候执行,它们在多线程中的表象又是如何?下面首先看下例子:tsecer@harry:
阅读全文
摘要:一、问题 进程被OOMkill之后退出,在/var/log/messages文件中并没有发现对应的系统日志,那么日志去哪里了呢? 二、内核日志如何获得 内核相关日志相关功能主要集中在kernel\printk\printk.c,虽然功能比较简单,但是在内核代码组织结构中还是享有一个单独的文件夹,可见
阅读全文
摘要:一、收到报文对于网络地址的判断 对于刚收到的网络数据,经过了NF_IP_PRE_ROUTING过滤之后,开始到达了ip_rcv_finish函数,在该函数的开始做了一个看起来比较诡异的操作,就是判断了这个数据包中的路由dst是否已经设置过了,如果没有设置过则进行路由;这也就是反过来说,一些收到的报文
阅读全文
摘要:一、问题的引入 在客户端希望通过http协议到服务器来拉取数据时,这种交互大多就是一次性的交互,客户端从httpsvr把数据拉取回来之后,服务器会主动关闭套接口。通常来说,如果是我们通过传统的PC端来连接,这个问题不是很大,因为这些客户端通常就是专门围着这个httpsvr来转的,就等着httpsvr
阅读全文
摘要:一、udp的报文发送 udp在通常的应用中使用的比较少,可靠的协议通常使用TCP传输,对于的关注自然没有TCP多。尽管UDP具有不可靠的传输问题,和TCP相比,它有一个隐性的优点就是对于packet结构本身的完整性保持。严格意义上讲,这个属性并不是UDP协议单独完成的,而是由IP层完成,对于上层应用
阅读全文
摘要:一、当前进程current 在内核中,current绝对是一个出镜率非常高的变量,在几乎所有的系统调用中都会用到该变量。由于该变量被使用的频率比较高,所以它的实现要尽可能的快速高效。在最早的内核版本中,这个实现在内核的不同版本中一直在变化,从这个变量也可以引申出一些有意思的问题。 二、早期内核实现
阅读全文
摘要:一、现象so文件被不同的进程共享,映射入各个进程的地址空间中,这也是SO文件存在的重要原因。作为文件,它的只读部分可以供系统中任意多的进程使用,从而节省系统物理内存使用以及磁盘空间的使用。对于系统级的so文件,我们一般不会修改这些文件的内容,即使修改可能也是无意修改。但是对于一些自己编写的so文件,
阅读全文
摘要:一、直接修改内核代码段在386内核的kprobe实现过程中,其中有一个是对于代码段断点的安装,那个地方对于代码段的修改是轻松加惬意,就好象生活在新闻联播里一样,这让我们这些看惯了用户态进程各种保护的程序员来说还是比较震撼的,套用一句三俗的话来说:我和我的小伙伴们都惊呆了。386中对于kprobe调试
阅读全文
摘要:一、内核实现基础和之前的select相比,epoll是一个目标性更强的实现。在epoll等待的时候,它会把每个poll的唤醒函数注册为自己特有的函数,在该回调函数中,它将自己(被唤醒的fd)添加到readylist中,然后在poll到底是什么事件的时候只检测在readylist中的描述符即可,而不是
阅读全文