Test Doc
<h1 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h1><p><img data-src="/../../../images/elogs/b921c8dd42bc1bcccf1a4d99d08f79e1
<h1 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h1><p><img data-src="/../../../images/elogs/b921c8dd42bc1bcccf1a4d99d08f79e1
<h1 id="intro"><a href="#intro" class="headerlink" title="intro"></a>intro</h1><p>在抬笔之前,纠结许久,过去的这一年,真的有这么多要记录的东西么,有必要花几个小时的时间去写么?我不知道。但同时,我的鼠标已点开了之前的博客,开始翻看前些年写的文字。看着看着,我找到了许多自己已经不怎么记得,但想起却感到十分温暖的那些瞬间和回忆。虽说都不是什么大事儿,但是如果不记录,它们可能真的就会遗失在记忆的荒野里了。</p> <p>所以,我还是要写些文字,来记录我这平凡,也小有起伏的一年时间。</p>
<p>在挺久之前,可能是刚读大学的时候,就隐约听说这本《禅与摩托车维修艺术》的大名,也得到了几位朋友推荐,但在当时,翻过几页后发现根本看不下去,就束之高阁了。这次终于在好奇心的不断怂恿之下花费了一些意志力重新拾起,终于随着情节的展开,同作者一起踏上了骑着摩托车横穿整个美国的长途旅行。</p> <p>在最开始的认知中,我认为这场摩托车旅行一定是一个非常酷的故事,但后面发现虽然故事的确很酷,却非第一印象中的那种酷。</p> <p>在这场旅行中,我在了解美国地理的同时,也被作者和“斐德洛”的暗中较量所吸引,对父亲与克里斯的矛盾所疑惑,更为寻找“良质”同作者(或者说是“斐德洛”)一起陷入了对当下的反思。</p>
<p>时间很快,如今已经是2021年伊始了。虽然已经很久没有写过文章,但是,面对2020年,我总还纠结着要说些什么。</p> <p>2020最大的主题就是变化。不仅有意料之中的变化,更多是意料之外的变化。</p> <h1 id="疫情"><a href="#疫情" class="headerlink" title="疫情"></a>疫情</h1><p>说到变化,总也绕不过的就是疫情。</p> <p>我的2020年是以一次滑雪作为开始,在那场滑雪之后,我还在畅想在结束毕业论文写作之后,毕业前的时间我应该怎样度过,是要趁着有闲逛上大半个中国,还是省一些钱躲在实验室里啃啃买来一直没读的大黑书。</p>
<p>在上一篇博客<a href="/debug-linux-kernel-with-vscode">使用Qemu和GDB对Linux内核进行调试</a>中已经介绍了使用Qemu和GDB对Linux内核进行调试的方法,但是GDB调试对于用惯了GUI工具的人(比如我)来说并不是很直观,所以就希望尝试使用比较熟悉的GUI编辑器,如VSCode,对内核进行调试。</p> <p>由于VSCode的调试方式同样基于GDB,所以需要先在GDB中测试没有问题。</p> <h2 id="插件"><a href="#插件" class="headerlink" title="插件"></a>插件</h2><p>需要在VSCode的插件市场中安装微软官方的C/C++插件,该插件可用于IntellSence和GDB调试。</p> <h2 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h2><p>为了使VSCode支持内核的调试,需要配置launch.json,特备注意需要配置<code>setupCommands</code>属性,以便在GDB启动后对其进行设置,大致的配置文件如下:</p>
<p>使用Qemu对Linux内核进行调试是一种较为便捷的方式,近日进行了一番实践,并将大致步骤与其中一些小坑记录了下来。</p> <h1 id="环境"><a href="#环境" class="headerlink" title="环境"></a>环境</h1><p>由于放长假赋闲在家,所以手头只有一台装有MacOS的MBP可用,而Linux内核的开发与调试使用Linux环境下会比较方便,所以就使用VMware Fusion创建了一台安装有Ubuntu 18.04系统的虚拟机。由于编译Linux内核及相关软件需要的资源较多,所以为虚拟机配置了双核CPU、2GB内存和20GB磁盘空间(笔记本本身资源有限),但实际使用(特别是物理内存和硬盘)捉襟见肘,于是又在系统中添加了3GB的SWAP内存并扩容了20GB的磁盘空间(其实还是不太够)才解决问题。</p> <h1 id="编译Linux内核"><a href="#编译Linux内核" class="headerlink" title="编译Linux内核"></a>编译Linux内核</h1><p>首先,尝试对内核进行编译,在编译前需要使用通过KConfig启动内核的调试配置。</p> <h2 id="下载内核源码"><a href="#下载内核源码" class="headerlink" title="下载内核源码"></a>下载内核源码</h2><p>由于Linux内核代码量非常大,且由于国内网络大家都懂的原因,所以的下载内核源码是一项较为复杂的体力活动。</p>
<p>最近在项目中遇到需要在 NodeJS 中调用 C++代码的问题,在此略作总结。</p> <h1 id="主要方案"><a href="#主要方案" class="headerlink" title="主要方案"></a>主要方案</h1><p>在 NodeJS 中,和其他语言编写的代码通信主要有两种方案:</p> <ul> <li>使用 AddOn 技术,使用 C++为 NodeJS 编写一个拓展,然后在代码中调用其他语言所编写的源码 or 动态库</li> <li>使用 FFI(Foreign Function Interface)技术,直接在 Node 中引入其他语言所编写的动态链接库</li> </ul> <p>在对这两种方式进行比较后,发现这两种方式各有优劣。</p> <p>首先,AddOn 技术比较通用,它可以使用 C++代码来拓展 Node 的行为,很多库都是使用这种方式来完成一些比较底层操作(比如和操作系统的一些通信)的。但是它写起来比较麻烦,要编写一个 C++项目,还要按照 NodeJS 的规范 export 相应的函数,而且每次安装的时候都需要进行编译(以适应本地 Node 的版本)。如果只是调用一个 DLL,那就还需要在项目里重新包装一遍 DLL 的接口。</p> <p>如果使用 FFI 技术,限制就会比较多,首先,它只能调用其他动态库,如果你想使用 C/C++完成更多功能的话,还需要再封装一层 DLL,另外,它只支持<code>_cdecl</code>调用约定(也就是 DLL 在导出的时候一定要标记用<code>_cdecl</code>编译命令),不支持<code>_stdcall</code>或者<code>_fastcall</code>调用。但是调用起来就会很方便,可以直接在 JS 代码中声明 DLL 的接口就可以了。</p> <p>综上比较,如果只调用第三方 DLL(而且恰好是<code>_cdecl</code>导出),使用 FFI 就再合适不过了(虽然性能可能会有一定的损失,而且调试起来会有困难)。</p> <p>其实,从理论上来讲,FFI 也是基于 AddOn 技术的,只是它可以帮你把在 JS 中定义的接口直接转换成 C 语言的接口,并利用 NodeJS 的 Buffer 内存,将其同载入的 DLL 共享。当然由于 FFI 的这种通用性,也导致了一定的性能损失。</p> <p>下面就以在 Windows 平台上使用 FFI 为例,简单聊一下如何使用 NodeJS 和 C++编译而成的 DLL 通信吧。</p>
<p>引用是C++相对于C而引入的一个重要特性,它使得许多地方的语法变得更加简洁,但是它们的底层究竟是怎么实现的呢?</p> <p>在Wikipedia中,对指针有如下介绍:</p> <blockquote> <p>In computer science, a pointer is a programming language object that stores the memory address of another value located in computer memory. A pointer references a location in memory, and obtaining the value stored at that location is known as dereferencing the pointer.</p> </blockquote> <p>从定义可以看出,指针从本质上来讲就是一个变量,其中所存储的就是其他变量的地址。 而C语言中的指针非常灵活,它可以任意指向某一个地址,不论这个地址究竟是否存在,或它究竟存储的是否为指针所代表类型的数据。</p> <p>那么也不难想到,指针在实现的时候也是内存里的一个变量,它存有其他变量的地址。</p> <p>在Wikipedia中,对引用有如下介绍:</p> <blockquote> <p>In computer science, a reference is a value that enables a program to indirectly access a particular datum, such as a variable’s value or a record, in the computer’s memory or in some other storage device. The reference is said to refer to the datum, and accessing the datum is called dereferencing the reference.</p> <p>In the C++ programming language, a reference is a simple reference datatype that is less powerful but safer than the pointer type inherited from C. The name C++ reference may cause confusion, as in computer science a reference is a general concept datatype, with pointers and C++ references being specific reference datatype implementations. The definition of a reference in C++ is such that it does not need to exist. It can be implemented as a new name for an existing object (similar to rename keyword in Ada). </p> </blockquote> <p>从上面的定义可以看出,在C++中,引用可以狭义地认为是某一个变量的别名,它本身是并不存在的。</p>
<p>自昨天下午看完《流浪地球》以后,内心久久难以平静。闭上眼睛后,大脑中出现的是流浪地球的主题曲《带着地球去流浪》和地球飞临木星时候大气交汇时那种磅礴而又难以用语言形容的场景。</p> <p>这首歌里,一面是曹操的《观沧海》,描述了人类面对这个世界所发出的赞叹,描述出了大好河山的雄伟壮丽。而另一方面,又进行了古今对比,更体现出这场星际旅行的悲凉与无奈。伴着这首歌,我就知道必须要写些什么了。</p>
<h1 id="Intro"><a href="#Intro" class="headerlink" title="Intro"></a>Intro</h1><p>倏忽之间,又过去了一年。是时候向 2018 说一声再见了。</p> <p>今年,我只在写 <a href="/feelings_around_new_year">年关随笔</a> 时立了一个 Flag,要练习深度写作,至少每个月输出一篇文章。可惜因为暑假时候偷懒,这个 Flag 也并没有达成。不过,我还是要在 2019 重新立起这样一个 Flag —— 2019 年每个月至少输出一篇文章,可以是技术,可以是随笔,也可以是观点。希望明年这个时候再回来看,不要像今年一样打脸。</p> <p>再说回 2018。这一年相比前些年,在我的努力下,节奏逐渐慢了下来,让我有了许多时间静下心来思考、做事,也有时间和爱人相处、与朋友侃大山(至少在十一月之前是这样的)。同时,这一年又并不像以往那么顺遂,让我明白了人力有限,世间有太多力所不能及之事。</p> <h1 id="时光·记忆"><a href="#时光·记忆" class="headerlink" title="时光·记忆"></a>时光·记忆</h1><p>在大自然面前,没有什么是能够永恒的。人不能够,事不能够,城也不能够,甚至文明也不能够。</p>
Chen's Blog,分享安全领域的所思、所想、所学。
空鸣深语
无论你是游戏死忠,还是轻度的休闲玩家,在这里都能找到感兴趣的东西。
技术&思想
LoRexxar's Blog