UNIX是分时系统,同时运行着多个进程,进程之间相互联系,形成了进程组、会话等进程关系,这些进程关系会影响某些函数/系统调用和信号的行为。
进程的起源
所有的进程都有一共同的起源,加电开机启动操作系统并登录(获取login shell)就是用户进程的起始1。这里介绍传统的UNIX登录机制。
Posts
UNIX是分时系统,同时运行着多个进程,进程之间相互联系,形成了进程组、会话等进程关系,这些进程关系会影响某些函数/系统调用和信号的行为。
所有的进程都有一共同的起源,加电开机启动操作系统并登录(获取login shell)就是用户进程的起始1。这里介绍传统的UNIX登录机制。
刚接触 Vim 的同学往往因为无法搭建开发环境而“从入门到放弃”,本文旨在帮助这些同学搭建开发环境,聚焦于最核心的开发需求,忽略换配色调字体之类的细枝末节。如果需要开箱即用的 vim 配置(发行版),可以使用 Spacevim。
本文使用 neovim-nightly,但也适用于 Vim 8.2+,不需要读者有任何 VimL 基础,以 C/C++ 为例,但应该适用于任何语言。
在 Vim 中,插件只是一些脚本,存放在特定的目录中,运行时将它们所在的目录加入到 runtimepath 中。Vim 8 内置了插件管理功能,但不支持高级的插件管理功能。Vimmers 实现了多个插件管理器,可以自动下载、更新、安装插件,还可以延迟加载、按需加载,提高启动速度。
vimspector是一个基于 DAP(debug adapter protocol) 的Vim多语言调试插件,理论上能够支持所有支持语言(只要有对应的 DAP)。这个插件仍在实验阶段,可能会有各种bug,但是对C/C++、Python 等流行的语言已经进行了充分的测试。
这篇文章以调试 C/C++ 程序为例,介绍 vimspector 的配置与使用。
由于 vimspector 的作者主要在 GNU/Linux 上使用 Vim 开发,因此 Vimspector 作者 puremourning 明确表示在 vimspector 的充分测试并稳定后才会提供对 Neovim 的完整支持(见 issue coc.nvim: Debug Adapter Protocol Support #322),因此目前对于 Neovim 和 Windows 的支持都处于实验阶段。我个人建议在 Vim 中使用本插件。
C/C++ 中的变量占有一块内存,这时这个变量就是这块内存的别名,指针也可以指向内存,因此同一块内存可能会有多个别名。
int main()
{
int i = 0;
int *ip = &i;
}
其中i
和ip
是同一块内存,都是它的别名。
内存别名的存在会影响编译器生成的代码的行为。
考虑以下代码块(来自 CSAPP 5.1 节):
void twiddle1(long *xp, long *yp)
{
*xp += *yp;
*xp += yp;
}
void tiwddle2(long *xp, long *yp)
{
*xp *= 2 * *yp;
}
这两个函数的功能看起来是相同的,但其实不然。加入,xp
和yp
指向同一块内存,twiddle1()
将*xp
写为原来的四倍,而twiddle2()
将xp
写为原来的两倍。
编译器在进行优化时,要确保优化是安全的,即优化的程序和未优化的程序行为是一致的。在上面的例子中,编译器无法判断xp
和yp
是同一块内存的别名(指向同一块内存),只能保守地认为两个指针指向同一块内存,因此twiddle()
要老老实实的进行两次+=
。