在 Linux 下開發 C/C++ 的新手指南

标签: Programming Software Engineering | 发表时间:2012-01-18 16:22 | 作者:fcamel
出处:http://fcamel-fc.blogspot.com/

新加入一個專案,最先面對的課題是如何正確地編譯和執行專案,可從 "It works on my machine" 如此地風行,印證這件事的困難性;再來則是閱讀負責工作相關的程式碼。至於發揮程式語言的特性,運用高階設計模式等,都是另開新專案或熟悉狀況後才有機會發揮。

過去數年沉浸在愉快的 scripting language 和開發新專案中,一直沒踏入這殘酷的世界。這篇記錄在這樣的情境下,可能需要的技能,結算一下這一個多月的心得,全都是血淚談啊 ...。

系統工具

熟悉作業系統的安裝套件是首要之務,這樣才知道如何補足需要的 header、library,或是安裝含 debug symbol 版的函式庫以執行 gdb 觀察程式或除錯。參見 《自行編譯含 debug symbol 的套件 (package)》了解 Ubuntu/Debian 下的套件命名規則。

在未安裝套件的情況下,可用

  • aptitude search SUBSTRING # 找套件
  • aptitude show PACKAGE # 顯示套件用途
  • apt-file search X # 找出 X 包在那個套件裡,找 header 時很有用。

注意在用 apt-file 前要先跑 sudo apt-file update,不然搜不出東西來。

對於已安裝套件,可用

  • dpkg --search SUBSTRING # 找出安裝在那個套件,已知 header 時,適合用來找 library
  • dpkg -L PACKAGE # 列出套件內容,可用來找 header、library
  • locate SUBSTRING # 我比較常用它找 header 的位置,再觀看 header 內容

執行 locate 前記得先執行 sudo updatedb,原因同 apt-file。

編譯

連結

這一塊是我目前最頭痛的地方,大多卡在這裡。一些粗淺心得:

之後還需抽時間補充相關知識,像是 ldconfig 如何運作。

執行

光只是讀程式碼就像大海撈針一樣,不太有效率。可從動態執行過程找出主要執行的路徑,再專注相關的程式碼。

1. strace 和 ltrace

srace 是分析執行行為的強大工具,google 一下會看到很多別人的個案心得,看看再自己試一試,很快能上手,不知能發揮它多少功能。這裡列自己用的兩個小案例:

反而是 ltrace 一直都想不到使用它的時機,也沒找到好的個案心得文。

2. gdb

gdb 的重要性不需多說明,之前的幾則心得:

強烈建議使用 cgdb,簡易安裝 + 無痛上手,瞬間省下大量操作和讀碼的時間。

3. 打開除錯功能

依照開發者的習性,一定會留後門讓自己方便除錯,從這角度下手也可省下不少時間:

4. 載入函式庫

除以上所言外,我另外有找過畫出程式流程的靜態和動態分析工具,像是畫 call graph 或是 C 的 cflow。不過 C++ 的靜態分析效果很糟,就沒花太多時間研究。目前用 strace 和 gdb 覺得已夠用了,不知用工具產生 call graph、class 相依圖或其它東西,是否會更有幫助。待有需求看整體的程式時再來試試。

閱讀程式碼

聽了大家的建議後,做了一些實際操作,而有些心得:

Eclipse CDT 雖然方便,後來我還是用 gj 居多。原因有幾點:

  • 我已很習慣用 vim + screen 做事, gj 最合這個情境
  • id-utils 真的是超級快
  • 我針對自己的需求更新 gj 多次,愈用愈順手

另外 ack 也滿方便的,懶得建 index 或是想比對子字串時,可直接使用。當然 id-utils 也支援子字串比對,只是暫時懶得為此修改 gj 的程式,目前大部份需求是找完整的 symbol。

熟悉 Linux 系統程式

在基本工具都上手後,打算每天抽一點時間加減讀一點相關知識。一兩年下來應該會有不錯的成果。目前打算讀 《The Linux Programming Interface》,年假時試看看效果如何。

這一個月的心得以了解 /proc 為主,對觀察 CPU 用量、RAM 用量、載入那些函式庫、multi-thread、程式執行狀態等都很有幫助:

結論

即使大概知道有那些東西,還是需要實際動手的經驗,才會真的學進去。一個月下來進步了不少,不過對於要面對的戰役,還有一大段路要趕上,還有很多很多要學的。

相关 [linux 手指] 推荐:

在 Linux 下開發 C/C++ 的新手指南

- - fcamel's blog
新加入一個專案,最先面對的課題是如何正確地編譯和執行專案,可從 "It works on my machine" 如此地風行,印證這件事的困難性;再來則是閱讀負責工作相關的程式碼. 至於發揮程式語言的特性,運用高階設計模式等,都是另開新專案或熟悉狀況後才有機會發揮. 過去數年沉浸在愉快的 scripting language 和開發新專案中,一直沒踏入這殘酷的世界.

Javascript 里跑Linux

- rockmaple - Shellex's Blog
牛逼到暴的大拿 Fabrice Bellard,用Javascript实现了一个x86 PC 模拟器,然后成功在这个模拟器里面跑Linux(请用Firefox 4 / Google Chrome 11打开,Chome 12有BUG). 关于这个东西… 伊说 “I did it for fun“,大大啊大大啊….

Linux Ksplice,MySQL and Oracle

- Syn - DBA Notes
Oracle 在 7 月份收购了 Ksplice. 使用了 Ksplice 的 Linux 系统,为 Kernel 打补丁无需重启动,做系统维护的朋友应该明白这是一个杀手级特性. 现在该产品已经合并到 Oracle Linux 中. 目前已经有超过 700 家客户,超过 10 万套系统使用了 Ksplice (不知道国内是否已经有用户了.

linux makefile编写

- hl - C++博客-首页原创精华区
在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则. target也就是一个目标文件,可以是Object File,也可以是执行文件. prerequisites就是,要生成那个target所需要的文件或是目标. command也就是make需要执行的命令. 这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在 command中.

Linux下的VDSO

- 圣斌 - Adam's
VDSO(Virtual Dynamically-linked Shared Object)是个很有意思的东西, 它将内核态的调用映射到用户态的地址空间中, 使得调用开销更小, 路径更好.. 开销更小比较容易理解, 那么路径更好指的是什么呢. 拿x86下的系统调用举例, 传统的int 0×80有点慢, Intel和AMD分别实现了sysenter, sysexit和syscall, sysret, 即所谓的快速系统调用指令, 使用它们更快, 但是也带来了兼容性的问题.

Linux wget命令

- - CSDN博客推荐文章
wget是linux最常用的下载命令, 一般的使用方法是: wget + 空格 + 要下载文件的url路径. 例如: # wget  http://www.linuxsense.org/xxxx/xxx.tar.gz. 简单说一下-c参数, 这个也非常常见, 可以断点续传, 如果不小心终止了, 可以继续使用命令接着下载.

linux 小技巧

- - DBA Blog
2:如何限制用户的最小密码长度. 修改/etc/login.defs里面的PASS_MIN_LEN的值. 比如限制用户最小密码长度是8:. 3:如何使新用户首次登陆后强制修改密码. 4:更改Linux启动时用图形界面还是字符界面. 将id:5:initdefault: 其中5表示默认图形界面. 改id:3: initdefault: 3表示字符界面.

Linux iostat命令

- - CSDN博客系统运维推荐文章
iostat用于输出CPU和磁盘I/O相关的统计信息. . iostat [ -c | -d ] [ -k | -m ] [ -t ] [ -V ] [ -x ] [ device [. iostat各个参数说明:. -c 仅显示CPU统计信息.与-d选项互斥. -d 仅显示磁盘统计信息.与-c选项互斥.

Linux的架构

- - 博客园_首页
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明. 我们以下图为基础,说明Linux的架构(architecture). (该图参考《 Advanced Programming in Unix Environment》). 最内层是我们的硬件,最外层是我们常用的各种应用,比如说使用firefox浏览器,打开evolution查看邮件,运行一个计算流体模型等等.

linux命令locate

- - 操作系统 - ITeye博客
    locate命令其实是"find -name"的另一种写法,但是要比后者快得多,原因在于它不搜索具体目录,而是搜索一个数据库(/var/lib/locatedb),这个数据库中含有本地所有文件信息. Linux系统自动创建这个数据库,并且每天自动更新一次,所以使用locate命令查不到最新变动过的文件.