Random Beijing Image 4


我今天才知道原来中科院自动化研究所就在我住的地方往北走一分钟。


也是今天才知道中科院数学与系统研究院在我住的地方往北走五分钟。


才发现住的地方地理位置这么好,直往北走就是清华大门。楼下有两个公交站,距离地铁和沃尔玛四五分钟的路程。我住处楼下的“白塔庵”公交车站,后面就是我住那楼。


路口西面的车站,后面是翠宫饭店。


路口东面的车站,后面是中关村海关。


自动化所侧面,傍晚光太暗了。


这个楼干吗的?不会是晨兴数学研究中心吧。


中关村国行。哈哈,居然在银行大楼下停车场出口挂这样的横幅,搞笑吧!

ALBUM: http://picasaweb.google.com/solrex/RandomBeijingImage

Adding a New Target to GDB (1)

为 GDB 添加新的目标机 (1)

工作基本结束,留下些文字,希望能对别人有些用处。本文遵从 GNU Free Documentation License (see http://www.gnu.org/copyleft/fdl.html ),并特别对 冒充另类(TeaWater) 的《移植GDB》一文表示感谢 (see http://teawater.spaces.live.com/ )。由于大体和细节的东西在《GDB Internal》和《移植 GDB》一文中已经有了很多描述,所以本文的目的在于 Howto,step by step 地描述如何为 GDB 添加新的目标机,并对某些以上两文中阐释不清的地方做出自己的解释。

为 GDB 添加新的目标机的意思就是让 GDB 支持一个新的 CPU 体系架构。这点从 GDB 的编译选项中可以看出来,在./configure 命令后有一个 --target= 的选项,这个等号后面就是 GDB 调试的二进制文件应该在什么目标机上运行,可以是: mips-elf,arm-elf 等等,在 config.sub 文件中你可以看到这些选项是如何工作的。

下面我们假设要添加的新 target 为 solrex-elf。

1.如何配置编译环境

当你为一个 GDB 添加 target solrex-elf 的时候,至少需要让 GDB 在 configure 为 solrex-elf 时候能够编译通过,为此你需要添加和修改一些文件。

GDB 其实由很多部分共同组成,GDB 源文件目录下有几个目录,bfd 目录下是 LIB BFD (Binary File Descriptor Library),opcodes 目录下是 opcode library,这两个 library 都是跟随 binutils 分发的; libiberty 目录下是 libiberty library,它给许多 GNU 软件提供一些通用的子程序,好像是跟随 gcc 分发的;readline 目录下是 readline library,提供一些命令行功能,比如<tab>补全,它好像是独立分发的;最关键的 gdb 目录,这个下面才是 GDB 的主体。

是想让 GDB 编译通过,不能只修改 gdb 的东西。要调试程序,必须要有先编译出来二进制代码,所以对 BFD 和 opcodes 的修改应该是最早的,binutils 依赖这些库来编译出来二进制工具,比如ar, as, ld, objdump, readelf 等,然后 gcc 利用这些二进制工具把它编译出来的汇编码最终组合成目标文件和可执行文件。

但是,在某些阶段,比如编译器尚未完善之际,可以先 cheating GDB,就是拿来一个已有 target 的 BFD lib 和 opcode lib,修改成自己的 target。

下面是要编译 target=solrex-elf 需要修改的文件:

Key source files:
gdb
* gdb/config/solrex/tm-solrex.h: New file.
* gdb/solrex-tdep.h: New file.
* gdb/solrex-tdep.c: New file.
bfd
* include/elf/solrex.h: New file.
* bfd/cpu-solrex.c: New file.
* bfd/elf32-solrex.c: New file.
* bfd/archures.c: New arch.
* bfd/bfd-in2.h: New arch.
* bfd/targets.c: New target.
opcodes
* opcodes/solrex-dis.c: New file.
* include/dis-asm.h (print_insn_solrex): New function.
* opcodes/disassemble.c (ARCH_solrex): New arch.
Config files:
gdb
* gdb/config/solrex/solrex.mt: New file.
* gdb/Makefile.in (solrex-tdep*): New target.
* gdb/configure.host (solrex*, solrex*-*-elf*): New target.
* gdb/configure.tgt (solrex*, solrex*-*-elf*): New target.
bfd
* bfd/config.bfd: New target.
* bfd/configure.in: New target.
* bfd/Makefile.am: New target.
opcodes
* opcodes/configure.in (bfd_solrex_arch): New target.
* opcodes/Makefile.am (solrex-dis*): New target.
general
* configure.in (solrex*-*-elf*): New target.
* config.sub (solrex, solrex*-*): New target.
* readline/support/config.sub (solrex, solrex*-*): New target.
Auto Generated files:
* configure (solrex*-*-elf*): New.
* bfd/configure: New.
* bfd/Makefile.in: New.
* bfd/doc/bfd.info: New.
* opcodes/configure (bfd_solrex_arch): New.
* opcodes/Makefile.in (solrex-dis*): New.

上面列出的是想成功编译出 solrex-elf target 需要修改的最少的文件。至于如何修改 config 和 makefile 文件,只需要查看一下某个特定的 target,比如:mips,或者简单点的 xtensa,就知道该怎样改了。

在 bfd 和 opcodes 里的文件不是这篇文章中讲的重点,想 cheat GDB 最简单的办法就是把另外一个 target 的名字,比如:mips, xtensa 全部换成 solrex 就行了,使用另一种 target 的 binary file descriptor 会影响 GDB 的某些功能而不是全部。

为 GDB 添加新的目标机 (2)

本文遵从 GNU Free Documentation License (see http://www.gnu.org/copyleft/fdl.html ),并特别对 冒充另类(TeaWater) 的《移植GDB》一文表示感谢 (see http://teawater.spaces.live.com )。由于大体和细节的东西在《GDB Internal》和《移植 GDB》两文中已经有了很多描述,所以本文的目的在于 Howto,step by step 地描述如何为 GDB 添加新的目标机,并对某些以上两文中阐释不清的地方做出自己的解释。

2.对所需添加进 gdb 目录的文件的功能介绍

这部分和 《GDB Internal》中的 9.12 Adding a New Target 一部分是重合的,不过我添加一些实例和自己的介绍。

’gdb/config/solrex/solrex.mt’:这个文件里的东西会添加到 Makefile 里面,很简单,给个例子:

$ cat gdb/config/solrex/solrex.mt
TDEPFILES= solrex-tdep.o
DEPRECATED_TM_FILE= tm-solrex.h

第一个就是要编译 solrex 的 target 需要的文件,solrex-tdep.o 是下面要讲的 solrex-tdep.c 的目标文件,还可以加一个 TDEPLIBS= ,意思是需要的 lib。 DEPRECATED_TM_FILE= tm-solrex.h 的意思这种做法已经 deprecated 了,但是我们仍然可以使用,是 target 所需要的头文件,下面会讲到这个文件,但是这个文件如果没有的话可以不要。

’gdb/config/solrex/tm-solrex.h’:这个文件里可以定义一些通用的宏,给个例子:

$ cat gdb/config/solrex/tm-solrex.h
#define GDBINIT_FILENAME ".solrex-gdbinit"
#define DEFAULT_PROMPT "(gdb-solrex) "

第一个是 GDB 启动时候的默认读取文件名,第二个就是 GDB 的缺省 prompt。这个头文件会变成编译时候的 tm.h 文件,这些宏定义会覆盖 GDB 的本身设定,当然,如果你不需要这些宏完全可以不要此文件。

’gdb/solrex-tdep.h’ && ’gdb/solrex-tdep.c’:这两个文件是最重要的文件,也是 GDB 能够识别 solrex-elf 这个 target 的根据,这两个文件中定义了很多 solrex arch 特定的东西,比如:target 是 big-endian 还是 little-endian 的?target 的 registers map;target 的字长,register 的类型,返回值的存放,等等等等,这些后面的文章都会仔细介绍,也是主要介绍的部分。

为 GDB 添加新的目标机 (3)

本文遵从 GNU Free Documentation License (see http://www.gnu.org/copyleft/fdl.html ),并特别对 冒充另类(TeaWater) 的《移植GDB》一文表示感谢 (see http://teawater.spaces.live.com )。由于大体和细节的东西在《GDB Internal》和《移植 GDB》两文中已经有了很多描述,所以本文的目的在于 Howto,step by step 地描述如何为 GDB 添加新的目标机,并对某些以上两文中阐释不清的地方做出自己的解释。

3. taget dependent 文件补充说明
其实关于 solrex-tdep.h, 和 solrex-tdep.c 文件中所涉及的函数, TeaWater 的《移植 GDB》一文讲得非常清晰,我也没必要重复,我只对一些他没提及的东西做一下解释。

(1) solrex-tdep.h 中应该放些什么

其实这个主要是根据需要,如果一些东西会被别的文件使用,那就放在这里,如果没有,这个文件甚至不需要。当然,一些应该放在头文件中的东西还是放这里比较好。

(2)关于 struct gdbarch_tdep

这个结构体是用户定义的,最重要的使用也是在这两个文件中。可以根据需要增减,一般的话需要几个:registers map,重要的 register number,然后就是 abi 的东西。只要用户觉得某个东西有用,就可以放在这个结构体里面。

(3)关于 pseudo registers

这个东西主要看编译器的实现,如果编译器就根本没有这些东西,没有必要处理这些东西。

(4)关于 unwind_pc

不要被它的名字迷惑,unwind_pc 所起到的作用原理很简单,返回一个位于(参数 next_frame 的上一层 frame)中的地址,一般情况下就是这个函数的返回地址。因为函数的返回地址一般就是对这个函数调用的汇编指令的下一个指令,GDB 内部会把这个返回地址再减去一个指令长度,这样就回到了函数调用那句话,函数调用肯定位于被调用的函数的上一个 frame 中。但是有两种情况你需要考虑,如果 next_frame 是一个 sentiniel frame, 只需要返回当前 pc 的位置,如果是一个 normal frame,就需要返回这个 frame 的函数返回地址。这个具体怎么做需要看特定的 target,比如 mips 很简单,只是把 pc 给它,但不是所有的 target 都是这样的。只需要看一下汇编代码就知道该怎么做了,一般情况下进入一个函数,首先是把移动 sp, 给这个函数留出一段栈地址,然后是把 ra 压栈。但是有时候也不完全这样,假如 ra 不是 GPR,不能直接存入栈中,只能先放到一个 GPR 中然后再把那个 GPR 压栈。

之所以要讲到上面的例子就是因为,GDB 的逻辑是这样的:告诉他要 unwind 哪个 register,它会先调用注册的 frame_prev_register 函数去找这个 register,很多情况下 target 都是先注册 dwarf2 的 dwarf2_frame_prev_register。这个函数会根据 debugging information 中的 FDE 和 CIE 去找这个 register 是放到哪里了,然后去那里找到这个 register 的值。但是这个函数有个缺陷就是,假如把一个 register 放入另一个 register 中,它只会到下一层的 frame 中去找那个 register,这样在上段说的最后一个例子,就会出现错误,因为被存入的 register 只是做一个中间值的用处,它会把自己压到栈中,而 dwarf2_frame_prev_register 到下一层的 frame 中去找它的值,显然不可能得到正确的结果。

(5)关于注册特定的 frame_unwind_append_sniffer 有没有用

在很多情况下,尤其是在 linux 的编译器都会为 ELF 文件加入 DWARF2 格式的 debugging information,所以很多情况下用户注册的 frame_sniffer 都是没有太大用处的,但是如果不注册也会发生问题。因为 GDB 中 DWALF2 的处理是先找 symbol 里对应于这个 pc, 有没有 FDE,如果有 FDE 就采用 dwarf2 的 frame sniffer,如果没有就采用用户另外注册的 frame sniffer。如果用户没有另外注册 frame sniffer 的时候,GDB 会出现 internal error,而当注册了以后,GDB 内部会在二进制文件中找这个 pc,如果找不到,会返回用户不知道现在位于什么位置。所以,当二进制文件中有 debugging information 时候,再注册特别的 frame sniffer 只是为了不出现 internal error。因为当 pc 正确时候,自然有 dwarf2 处理,当 pc 不正确的时候,GDB 也不会使用用户定义的 frame sniffer。用户定义的 frame sniffer 唯一有用的时候就是二进制文件中没有 debugging information,这样 GDB 会调用用户定义的 frame sniffer 来找 frame 的开始位置,栈分布和 register 的处理。

(6) gdbarch 中那么多东西,应该注册多少

我觉得,至少应该告诉 GDB 的是: info.byte_order, tdep, num_regs, sp_regnum, pc_regnum, stab_reg_to_regnum, dwarf2_reg_to_regnum, register_name, register_type, skip_prologue, inner_than, unwind_pc, call_dummy_location, unwind_dummy_id, push_dummy_call, print_registers_info, print_insn,然后再加上注册一下 frame_unwind_append_sniffer 和 frame_base_append_sniffer 就行了,剩下的就要看各个 target 的特性,需要不需要添加了。

唉,写了以后才发现自己没多少可写的,因为每个函数的用处 TeaWater 的《移植 GDB》中都讲到了,而要是真 step by step 地写,工作量也太大了点,算了,就这样吧,其实很多东西是只有到用的时候才知道哪里会出现问题的。不过用 GDB debug GDB 也是一件很有趣的事情。

Let People Continue To Have Confidence In The Future

今天看了柴静的一篇文章《我和你都深深嵌在这个世界当中》:http://blog.sina.com.cn/u/48b0d37b010008g2,有些惭愧。大概是因为所涉及的层面问题,柴静在博客上一直都是那种弱势群体的维护者,对社会黑暗面的揭露者,写着一些带着强烈情感的文字。

虽然受儒家文化浸染已久,对自己的评价也认为是儒生的成分居多,但那种为天地立心,为万民立命,为往圣传绝学,为万世开太平的责任感却往往只是瞬现瞬逝。 也许是见多了人情世故,受到 social Darwensim 影响太深。在崛起中的中国,无论哪里都是适者生存,不适者淘汰,没有人去可怜失败者。念书时的考试,找工作时的竞争,无一不提醒着我让 自己更强。前几天获鼎兄的博客不还在说:"07年的春节,无论如何也是戏剧性的一年。这个家庭在家族中的地位也发生急剧的变化,十几年没上门的亲戚出现在 简陋的客厅里面,昔日欺负我、藐视我的同学居然主动过来称兄道弟。真是倍感世态炎凉,又觉大快人心。"这种情况我又碰到过多少次?所以在我的骨子里就有一 种信念,可以说是一种成为人上人的强烈欲望,因此也就把自己的理想全放在了个人的成就上了。

但无论如何,这种情况我会试着去改变的,一种病态的信念会阻碍个人道德的完善。呵呵,又想起了《万历十五年》对明代道德观的描述,真是精辟啊!中国人的信 念就是以德立国,不是还有不战而屈人之兵的说法吗?但是自从近代饱尝苦果之后,反而对弱肉强食这句话理解得更深刻,动辄就是弱国无外交,和平崛起,在教材 中也对达尔文的一套理论奉若圭皋,大部分人失去了把中国建设成为一个好国家的兴趣,所有的目标都是让中国更强,让中国再不受凌辱。人生和国运其实很像的。

很喜欢她文章里的一句话:"其实,我们在做着同一件事,让人们对明天继续有信心。"我有机会去从事这样的事业吗?

Boy, what is your future?

最近好累,没完没了的调试,对GDB做了几遍 checking test,好多 fail 。只能 一个一个去找,却发现基本上是在给 compiler 做测试,基本都是因为 debugging information 的不完全还有 compiler 的优化。因为都是底层问题,只能 dump 出 来 assembly code 和 debugging information,一点一点的去找,看得我视力急剧下降。

工作是基本熟悉了,只是发现自己的很多问题又浮现出来。在保送研究生之前的大学生活大部是一段焦虑期,那种对未来的不可知和眼界的狭小让自己很惶恐。保完研,顺利找到实习以后基本上算进入了一个安静期,如果不算情感上波动的话。很欣欣自得于自己的状况,学业暂时无忧,经济暂时独立,工作也算理想,于是乎毫无念想去考虑其它。

现在应该是大四下学期了,前日系里开班会,我也没打听消息,无外乎是毕业论文和学期安排,大概还有毕业委员会的事情吧。这个世界离了谁都转,我这个小年级长在不在也没所谓。只是想到毕业论文,才觉得自己浪费的时间不少了。上个学期曾兴致冲冲地去找吴朝阳老师要求跟他作毕业论文,老师也给我指了两个方向。可惜的是,我把论文看得太轻了,只顾花费时间在一些别的事情上,告诉自己,还有时间,还有时间。

其实现在来说,我也不担心论文通不过的问题,本科论文也不会有太大意思。我是在怀疑自己有没有研究能力,独立思考的能力,到底适合不适合做科研。我丝毫不怀疑自己的行动力,但是我知道自己有很大缺点在意志力和创造力上。从小到大的人云亦云,从小到大的好学生,我对自己所学过的东西一片茫然,对自己要做的事情也无甚了解,我实在不知道自己选择学术这条路是对还是错。读研,我能读出来什么吗?

我不知道自己这种对能力的怀疑是暂时的还是永久的。不过我想这种情况也应该不只在我身上出现,地质大师许靖华在自己的自传中也写到在刚到美国开始自己的学术生涯时候也是不知所措,谁知道未来是怎样呢?我只是觉得自己对数学的兴趣不大,对计算机的兴趣也是一般,严格的来说,我没觉得什么学科对我来说有很大吸引力。高中的时候,倒是挺喜欢生物的,现在来说也了了了。一个对学术没有极大热情的人去从事它,会变得喜欢上吗?

其实说到了,可能还是功利心太强了,但是,这个世界允许我没有功利心吗?我没有那个条件去淡泊名利。

Random Beijing Image 3


锦秋国际十层,温室里的植物。


锦秋国际十层,春雨中的知春路。


圣诞节过了,春姑娘来了,你也该下来了吧。


前台,这几条金鱼居然三个多月都没死,我很惊讶。


同事的小孩,在我电脑前,你知道他在玩什么吗?Super...,哎,企鹅怎么说?


停在住处楼下的甲壳虫,副驾驶前面还挂着一个维尼,很可爱啊!没见过车主,是个美女吗?


这个雕塑好特别,后面是中关村地下广场,我很讨厌的地方--人太多了。

Scim comes back

哈哈,我的 Ubuntu(feisty)能输入中文字了,虽然 Kmail 里还是不能显示所有中文字,但编码是没有问题了的。不能用诡异,能用也诡异,我什么都没
做,就过了几天登录ubuntu,不小心点到了ctrl+space,惊喜地发现scim弹出来了,开心开心。

我要搬到Ubuntu下工作了,要享受beryl带来的快感了。

Random Beijing Image 2


还记得这辆自行车吗?


现在变成这个样了!!


北京的自行车很多的......


还有这些莫名其妙的交通牌


注意,交通安全,Microsoft 提醒您!!


公交车真多啊,这是在新中关楼下的天桥上,向南看


向北看,我真想说,真TMD叹为观止啊!


第三极书局六层,看见北面那一片楼了吗?要能住进那里多幸福啊!!

RSS List Sharing Movement @ Rainy Day

北京不可多得的好天气,蒙蒙细雨,三个月来第一次见到
本打算找个公园转转,早起的小雨打乱了我的计划
去北航里的工行给小黑打完我的奖学金税,便又踱步到公司了

灯都没开,一个人都没有,似乎没人愿意在雨天里到公司加班
摁亮显示器,进入 SUSE,检查一下 Kmail,仿佛又无所事事了
打开 Firefox,又开始我的程式之旅:
lilybbs, blogspot, WLM space, google reader

今天忽然想到,许多未订阅的朋友的 blog 好久不曾逛了
于是乎,从 link list 中一个一个点入
然后一个一个加到 google reader 的 rss list 中

我的 link list 一直在加长, rss item 也在增加
有个冲动,想发起一个 share rss list 的运动
让大家把订阅的 blog 列表用XML或OPML文件格式共享出来
不过那样会泄露很多隐私的
当然了,可以有选择的共享
不知道有没有人欢迎?

脱离了 windows 系统之后,msn 上的小星星也看不到了
只能通过 rss reader 刷刷刷
加之也离开了南京
所以 google reader 就成了看别人生活的窗口

进入大四以后,几乎所有人的博客更新都放缓甚至停止了
互相之间的访问也少了
我又换了 BSP
也不知道有多少人会看到这篇 blog

我把我的 RSS 订阅列表 opml 文件放到了博客主页面右侧的最下
链接名为:Solrex is reading...
我会不定期的更新这个文件
你可以查看我正在阅读哪些人的博客,并把它加到你的阅读列表中
也可以把这个文件导入到你的阅读器中然后做取舍

如果你愿意参加这个运动,可以采用同样的方式
也可以把我的共享链接加到你的页面上
如果不知道如何上载文件,也可以放在博客文章里
总之,Hope everyone enjoy your reading!

How To Add New Features To DejaGnu Testing Framework

如何为 DejaGnu 添加新特性

DejaGnu 是一个非常好的开源的测试工具,尤其是做 GNU 开源工具链的软件开发,更离不开 DejaGnu 的支持,因为 binutils, gcc, gdb 自带的测试用例都是使用 DejaGnu 进行测试的。但是,DejaGnu 也有一些不足之处。因为它是开源的,我们可以修改它来满足我们的需求。

DejaGnu is a very good open-source testing framework, expecially in GNU development tool-chain developing. Because binutils, gcc, gdb use DejaGnu to test themselves. However, DejaGnu can not cover all aspects. Luckily it is open-sourced, so we can modify it to meet our demand.

我曾经想把下面代码提交到 DejaGnu,但是很遗憾,它的维护者似乎并不希望添加这些特性。所以我只好写在这里,希望能对某些人有所帮助。

I have tried to commit the fellowing code to DejaGnu, but unfortunately its maintainers did not want these features. So I write them down, in the hope that them will be useful.

1. DejaGnu 的官方介绍
1. Introduction From DejaGNU’s website

DejaGnu is a framework for testing other programs. Its purpose is to provide a single front end for all tests. Think of it as a custom library of Tcl procedures crafted to support writing a test harness. A test harness is the testing infrastructure that is created to support a specific program or tool. Each program can have multiple testsuites, all supported by a single test harness. DejaGnu is written in Expect, which in turn uses Tcl -- Tool command language.

2. 怎样给 runtest 命令添加新的选项
2. How to add new options to runtest command

runtest 有很多选项,可以通过 runtest --help 查看。下面是向 runtest 添加两个选项的代码,"--pr"是带优先权的测试,通过在 site.exp 或者 unix.exp 等其它设置文件中添加 pre_test_list 变量(list类型)来实现优先测试 pre_test_list 中的测试用例;"--sm"是 smoking test,意思是可以在抽一支烟的时间内测完的用例列表,也是通过在设置文件中添加 smoking_test_list 变量(list类型)来实现。

"runtest" command has many options, you can use command "runtest --help" to get more information. The following code adds two options to runtest. "--pr" is for test with priority on some testcases, via setting a list variable "pre_test_list" in configure files like site.exp and unix.exp. "--sm" is for smoking test, set a list variable "smoking_test_list" in the same place as --pr.

在 dejagnu/runtest.exp 中,添加下面的代码:
Adds the following code to dejagnu/runtest.exp:

/* 在最后一个 switch -glob -- $option 的 swith 体中,添加:*/
/* Find the last "switch -glob -- $option", adds the fellowing to it’s switch body:*/
# Options handler.
"--pr*" { # (--priority) run preferential tests first, then others
if {[info exists pre_test_list]} {
set SOLREX_testlist $pre_test_list
# Flag to control priority and smoking test.
# 0: run before whole test
# 1: run only listed test
set SOLREX_flag 0
verbose "Running preferential tests $SOLREX_testlist"
continue
} else {
warning "Variable pre_test_list is null. runtest as default."
continue
}
}

"--sm*" { # (--smoking) run smoking tests
if {[info exists smoking_test_list]} {
if { $smoking_test_list != ""} {
set SOLREX_testlist $smoking_test_list
set SOLREX_flag 1
verbose "Running smoking tests $SOLREX_testlist"
continue
} else {
warning "Variable smoking_test_list is null."
exit 0
}
} else {
warning "Variable smoking_test_list is not defined. "
exit 1
}
}

/* 在最后一个 set testlist 的循环语句后,添加下面代码: */
/* Find the last "set testlist " statement, jump out of the foreach loop, adds: */
# Exe code for --pr and --sm.
# If SOLREX_testlist is defined, run these *.exp files listed in it first.
# code in foreach loop bellow is copied from above.
if {[info exists SOLREX_testlist] } {
foreach x $SOLREX_testlist {
verbose "trying to glob ${srcdir}/${x}" 2
set s [glob -nocomplain ${srcdir}/$x]
if { $s != "" } {
lappend testlist $s
} else {
set f [exec find $srcdir -name "$x"]
set f [split $f "
"]
set f [lindex $f 0]
set s [glob -nocomplain ${srcdir}/$f]
if { $s!= "" } {
lappend testlist $s
}
}
}
if { $SOLREX_flag == 0 } {
foreach test_name $testlist {
if { ${ignoretests} != "" } {
if { 0 <= [lsearch ${ignoretests} [file tail ${test_name}]]} {
continue
}
}
set subdir [file dirname $test_name]
set p [expr {[string length $srcdir] - 1}]
while {0 < $p && [string index $srcdir $p] == "/"} {
incr p -1
}
if {[string range $subdir 0 $p] == $srcdir} {
set subdir [string range $subdir [expr {$p + 1}] end]
regsub "^/" $subdir "" subdir
}
set runtests [list [file tail $test_name] ""]
runtest $test_name
lappend ignoretests [file tail $test_name]
}
set testlist ""
}
}

/* 在 usage 函数中,添加下面两句:*/
/* Find "proc usage", adds following two lines in it: */
# Help information.
send_user " --priority (-pr) Run tests in ’pre_test_list’ first and orderly, defined in ’site.exp’
"
send_user " --smoking (-sm) Run tests in ’smoking_test_list’ only, defined in ’site.exp’
"

3. 怎样给 DejaGnu 添加新的开发板描述文件
3. How to Add Board Description File to DejaGnu

DejaGnu 在baseboards目录下内建了很多开发板描述文件,例如:arm-sim.exp, mips-sim.exp,可以在这个目录下新建或修改原有文件来为你的开发板配置一个正确的环境。

DejaGnu have many board description files in directory dejagnu/baseboards, i.e. arm-sim.exp, mips-sim.exp. You can add or modify file to get a right configuration for your board.

开发板描述文件示例:
Example board description file :

$cat dejagnu/baseboards/gdbserver-sample.exp
......ignored headers......
# gdbserver running over ssh.
/* 加载 tool-and-target-specific interface 配置文件,这个文件应该在当前测试环境的 config 目录下,可以在它里重写很多库函数。*/
/* Load tool-and-target-specific interface file, it should be in your testhome’s config dir. You can overwrite library functions in this file. */
load_generic_config "gdbserver"

/* 下面都是很明了的了,但是需要说明的一点是 board_info 并不是一个 struct, 可以自定义很多内容。比如 GDB 就定义了许多变量,例如:gdb_prompt, mathlib 等等。 你也可以为自己定义一些变量,只需要在这里 set_board_info xxxx yyyy, 当你要使用时,先测试它是否存在:[target_info exists xxxx],然后取得它的值:set YYYY [target_info xxxx]。*/
/* The following is self-explained. But maybe you are glad to know that "board_info" is not a struct, you can define variables in it. For example, GDB defines many variables, i.e. gdb_prompt, mathlib. Of course you can define youself some variables for configuration use. Put "set_board_info xxxx yyyy" here first. When you want to use xxxx, you test if it exits: "[target_info exists xxxx]", then get xxxx’s value: "set YYYY [target_info xxxx]" */

process_multilib_options ""

# The default compiler for this target.
set_board_info compiler "[find_gcc]"

#set_board_info compiler "/opt/src/gcc/install-30/bin/gcc"
#set_board_info c++compiler "/opt/src/gcc/install-30/bin/g++"

set_board_info rsh_prog /usr/bin/ssh
set_board_info rcp_prog /usr/bin/scp
set_board_info protocol standard
set_board_info hostname voltaire.debian.org
set_board_info username dan
set_board_info gdb_server_prog /home/dan/gdb/mv/obj/gdb/gdbserver/gdbserver

# We will be using the standard GDB remote protocol
set_board_info gdb_protocol "remote"

# Path to the gdbserver executable, if required.
set_board_info gdb_server_prog "../gdbserver/gdbserver"

# Name of the computer whose socket will be used, if required.
set_board_info sockethost "voltaire:"

# Port ID to use for socket connection
# set_board_info gdb,socketport "4004"

# Use techniques appropriate to a stub
set_board_info use_gdb_stub 1

# This gdbserver can only run a process once per session.
set_board_info gdb,do_reload_on_run 1

# There’s no support for argument-passing (yet).
set_board_info noargs 1

# Can’t do input (or output) in the current gdbserver.
set_board_info gdb,noinferiorio 1

# Can’t do hardware watchpoints, in general
set_board_info gdb,no_hardware_watchpoints 1

城市梦

火车是越来越难坐了。这次和我坐一趟汽车的有几个人,前一天都曾尝试过坐火车,但都没能挤上去。想起去年春运回校时上火车的镜头,300多人挤一个几十厘米宽的车门,现在还有点后怕,所以这次没再敢尝试去买硬座车票。而在我家那个小站,卧铺车票是相当难买的,那得意味着你在车站里有相当硬的关系,不然是绝对没有可能搞到的。春节黄金周,五一黄金周,十一黄金周,虽然对商家来说代表着更高的人气,更好的销量,更多的利润,但对于需要旅行大半个或者小半个中国回家的人来说,只能是更难买的车票,更拥挤的车厢,更贵的商品,更累的假期。

在这些倒霉的人当中,最具代表性的当属学生和农民工,这大概是最惨的两个团体了。之所以说他们最惨是因为在这两部分人里只有极少数才有可能负担得起除长途汽车和火车之外的交通方式,而且一般的旅行距离都不会短,再受到地理因素的限制,很多人基本上是没有选择,只能坐某趟火车或汽车才能到家。所以他们不得不提前N天买票,不得不忍受无座票,不得不起早贪黑地赶车。当学生的如果再碰到南京大学这样的无良高校,火车票都不能保证给学生买到,就会更惨。(在我所知道的高校里面,能做到像南京大学这样对学生的购票问题那样令人发指的也屈指可数,还好它的放假时间一般比较早。)

不管用什么统计方式,学生流和民工流总是在持续增多,因为中国的学生越来越多,民工也越来越多。高校的扩招虽然逐渐放缓,但二级学院,私立院校,研究生招生依然在增加,农民工就不用说了,现在回到老家看看还有多少年轻人在家里死种地?但我觉得这并不是主要原因,更重要的原因在于这两种人的城市之梦,大城市之梦。如果学生都选择在本省甚至本市读书,如果民工都选择在省内打工,结果会是怎样?但人都是有选择的权力的,把城市和乡村相比,更愿意选择卫生教育文化购物环境比较完善的城市;把大城市和小城市相比,更愿意选择有着更多机遇和挑战的大城市。暂住证根本无法限制住庞大的流动人口,而中国落后的交通网也只好承载它的无法承受之重。

说到底城市有什么好,估计聊起来都会抱怨这个那个,但真正做起来都会像是餐桌上的某些人,一直对别人说不好吃自己却绝不停箸。城市化进程是不可避免的社会现象,虽然中国的农民并没有失去土地,而是在贫富差距下自动选择进入城市,但也是一种无奈。对于学生来说,可能这种状况改善一些,因为他们的城市之梦要比农民工的实现起来容易许多,但也是几人欢喜几人愁。“学而优则仕”慢慢地转变为“学而优则 oppidan ”和“学而优则 American ”。成长在大城市的人们也许会羡慕农家那恬淡的生活,但是采菊东篱下,悠然见南山的田园梦仅是诗人描绘的景象,也仅仅是士大夫才有能力获得的。从来就讨厌很多上海人、北京人那样高高在上的优越感,但是谁不愿意享受呢?相信看到今年春晚农民工孩子的朗诵,很多在外奋斗的人心都酸了吧!

中国的城市总要比乡村强上许多倍,大城市也比小城市强上许多倍。每次回家总感觉像来到了一个完全不同的世界,所有的生活习惯都必须得改变,在感慨于家乡的落后以外总免不了对大城市的向往。这也就是为什么大学里最努力的总是那些来自小地方的学生,为什么农民工们干着城里人不乐意干的活拿着低几倍的工资仍然开开心心,因为他们知道在物质条件上这里比家乡好很多,因为他们渴望留在大城市,希望成为城里人。就像 American dream 一样,在他们眼里,大城市就是一片乐土,一片充满冒险和成功故事的新大陆。

但是,他们仍然和旧世界有着千丝万缕的联系,所以这些新大陆的探险家们只能忍受一年才能回家两三趟的痛苦,只能成为人人讨厌的春运庞大客流中的一员。在路上时,他们肯定都会梦想着有一天自己发达了,就再也不用和别人一起走这条路了。

这个年那

今年这年过的啊,可真是郁闷。在外面折腾了一学期了,本想回去好好休息调养一番,可惜懒觉一天没睡成,天天被拉起来走亲戚。唉,大家庭就有这个好处,永远有走不完的亲戚。七大姑八大姨的就不说了,再加上我的那帮哥哥姐姐们还在可劲儿地造,我现在有多少侄子侄女外甥外甥女我自己都数不过来。更甚的是春节前一个比我就小俩月的外甥奉子成婚,看来我离当爷爷辈也不远了,真是老了啊!!!

回家过一个年,人憔悴了一圈,真是不爽。先说回去的火车,北京凌晨5点44发车,弄得我早去也不是晚去也不是。本来心一横想早晨起来再打车过去,可翻来覆去睡不着,只好爬起来去火车站,正赶上319最后一班车。坐了整整一白天啊,天黑时候才到郑州,又从郑州坐9点的车往家倒,到家已经11点了。其实从北京到郑州的车上一点都不挤,从发车就没多少人,很奇怪。反倒是从郑州回家的车人比较多,不过短途的占大多数。

过年觉睡不好还在其次,最郁闷的是饭也吃不好,见了油腥就反胃,在家八天吐了两次,饿得前胸贴后背还只能清汤稀饭,唉,无语啊,不是享福的命。从家里回来,火车票还买不到,只能坐了趟加班的汽车,原来的大客都往南方跑了,只有那种平常作中短途运输的29座的宇通,坐着别提多难受了。下午两点抢上的车,开到维修厂检修到5点半,刹车片漏油,后轮卸下来擦擦刹车片再上油装上。腰窝着,冷风吹着,晃悠着,一会儿上高速一会儿下高速,开得贼猛,居然安全把我带到了北京,我都有点奇怪。早晨四点半从莲花池车站下来都快冻成棍了,坐走夜路的汽车不多穿点衣服真是一大失误。还好六里桥北有944直接到翠宫饭店,看到站牌都快激动死了,总算不用再往西站折腾了。

到住的地儿已经快6点了,上床眯了会儿,8点起来的时候还发现自己有点发烧,好悲惨啊。泡了碗面,吃了点药就赶公司来上班了,还好到中午烧就退了,可胃还是一直不舒服。总之,这个年过的很不好,不过不算倒霉,老杨我的心情还是很好地。牢骚发完,扯乎,好好吃饭去。

擦身而过一个机会

今天公司 SW 小聚,经理的 email 说有重要人物高教授参加。当时也没想着问问是谁,后来才知道是特拉华大学的高光荣教授。其实我在餐桌上也不知道他有多厉害,只是听老板介绍说是编译器和计算机体系结构方面的专家,貌似在学术界很牛的样子,张口闭口都是那些计算所的同事们如雷贯耳而我却从没听说过的名字。回来一搜才发现,果然很牛,大陆在 MIT 的第一个 CS Ph.D 啊,还当过这个那个委员会的主席。要知道就稍微准备一下,好好套套近乎了。唉,只因为自己研究生读的是网络安全,和编译器扯不上边,当时也没想着怎样,不过老板说,以后从 compiler 做安全也是一个趋势,可以发好多文章的。看着大好机会从身边溜走了,郁闷。不过老板也说,以后要是想读 compiler 方向的话,他可以给我推荐,因为这个的教授基本上都熟,但是别的方向就不行了。学术,学术,谁知道自己会搞什么呢?我读数学的不也照样改行到网络了吗,说不定以后真要做 compiler 呢,GDB debugger 的移植也基本算完了,只剩 test 和 debug 了。要是老板让接着做 compiler 的东西,可能还真得好好学一下。

没有一种感觉,比得上回家

如果老外在这个时候来到中国,他绝对不会产生中国居民购买力低下的结论。中关村的家乐福就不说了,本来天天都跟赶集一样,挤得难受得不行。就我天天光顾的知春路沃尔玛,这两天也是人声鼎沸,所有收银台前所未有地全部亮灯。排队的全推着一车一车的东西,我就拿着一盒饭夹在里头好痛苦啊!人们办年货的热情在中国各地似乎是没有什么区别的。

昨天去村里给我妹买了个三星 E-878,半个多月的工资唰就没了。又到第三极买了几本书,萨缪尔森的《经济学》,亚当斯密的《国富论》,曼昆的《经济学原理》,凯恩斯的《就业、利息和货币通论》,回去得好好教育教育我这妹子,学经济的眼光太短浅可不行。这也总算没白看第三极的书,不过两百多块扔里面本想着能订个半年的《南方周末》,却被告知活动已结束,好郁闷。有了这几本书压阵,想轻装回家已经是不可能了,还好没有什么别的东西了,就当背着书包去上学吧。

对于买票来说,我觉得自己运气实在是好。我一直太懒了,懒到连问问怎么买都没有。今天早上才有点着急,正好室友张哥也要去买票,他说太阳园旁边有个预售点,我们早上起来就过去了。一问,人家说:您那,就别问了,今儿已经有好几拨人问过了,这几天到商丘,洛阳,郑州,安阳的票都没有。当时一听就泄了气了,得,那等晚上七点放票的时候再过来吧。从队里出来正准备走呢,后面一美女问:请问这车在安阳停吗?我一听售票员说:这车不停。心中大喜,连忙叫住她,一看是到郑州的票,我就问她退票吗,她说那是给朋友买的,她得问问。我就等了一会儿,哈哈,功夫不负有心人那,她朋友一看在安阳不停,就把票转给我了。临客,有座,除了点儿差点儿,凌晨五点多在北京发车,晚上六点到郑州。晚上到郑州倒没啥,都到郑州了我还回不了家?就是凌晨在北京发车有点愁啊,那么早也没公车,出租就算有也便宜不了,难道我要在火车站先等一宿?真郁闷,不过好歹有票了,刚在新浪看到新闻:“目前本市去往各地的火车票全面吃紧,从今天开始到16日的座位票已经全部售空,仅有部分无座票仍在销售。”我觉得还是值得庆贺一下的。

我们屋的人这两天也就走得差不多了。庞师傅是明天走,他公司放了两个星期假;简哥在鼎好自己摆柜台,无所谓假期,也是明天的票;张哥公司是科技部下面改制的半导体照明产业联盟,国有,没啥事儿,上班放假都比较随意,票还没买到;呼宏宇那小子在新东方学计算机,半个月前就跑了,说先回家过个好年,回来再找工作;还有一个成都电子科技大过来上 GRE 班的研究生,也是 14 号就走了。我好像还是最晚的一个。

说起我们屋里的几个人,我都有点感慨。三个已经结婚的,都是两地分居。简哥在北京已经干了一年半,老婆在南昌老家,还没孩子,大半年回家一趟;庞师傅都不知道在北京待了多长时间了,家在石家庄,两个星期回去一次,孩子刚满周岁;张哥十二月才结婚,嘿嘿,避孕不慎的结果,家在山东,也是多半年回去一次。他们都没有在北京安家的打算,都是为了多攒点钱再回去找个清闲的工作,不然也不会住这种集体公寓。可是他们的工资也和我现在差不多,什么时候是一个头啊。我不愿意显得很物质,但是作为一个男人如果不能让家人过上美满的生活,不能让孩子衣食无忧,还得与老婆孩子分居两地,我认为这样的人根本没有尽到自己的责任。如果我的孩子以后说起自己的爸爸是”那个两个星期(半年)回家一趟的人“,我会很谴责自己的。所以在现阶段,以及相当长的一段时期内,我都会以钱作为自己的目标,作为衡量自己能力的标准。就像现在一样,我不想让我妹子觉得自己比别的人差,去羡慕别的女孩儿的穿用,那么我只有努力挣钱,减轻家里的压力。我不会再谈爱情,再谈理想,俗话说:钱短英雄志,失去物质支撑的这些什么都不是。HOHO,过激了过激了,打住打住。

总之,要回家了,前几天还不怎么想,现在真觉得归心似箭那。“没有一种感觉,比得上回家!”可口可乐这句广告,做得真好。

Beryl is so cool

以前看到 SUSE 10.1 带的 beryl 效果,觉得非常有意思,但肯定会吃资源,就没想过尝试。自从那天看到同事的桌面也用了 beryl 之后,我才知道原来集成显卡也是可以安装滴。只可惜我的 SUSE 是 10.0,Qt 库的版本不够,只能望屏兴叹。昨天晚上下好了 Ubuntu 7.04, 叫什么 herd-3 测试版还是什么东西,我也记不住这种东西。心想,安上这个就可以玩 beryl 了。

测试版真的是很讨厌,我的 SATA 硬盘,WinC 盘是 FAT32 的,为什么把光盘镜像放在这个分区上就找不到呢?我差点想去改 initrd.gz 里面的寻找路径,还真从那里面让我找到了,但头痛的是,我不知道我改了后再压缩会不会识别不了。心想,算了,说不定是分区的问题,失败两次之后就学乖巧了些,拷贝到 ext3 格式的 linux 分区一个镜像,结果再找镜像就 OK 了。

但是安装时候还出了一个问题,我选择语言是中文,国家和地区是中国,它就是会停到安装 openoffice-java-commen 这个包上,真是奇怪了。只好选择语言英文,但是,但是,为什么我选择语言是英文不能选择国家和地区是中国呢?这是什么逻辑?没的办法只好选择香港。

安装好以后,彻底 upgrade 一番,这没出问题。但在安装中文支持的时候,最后一步说不能识别 zh locale。我郁闷了,一看,下载下来的中文支持包是 6.06 版本的,怪不得,那么久没有更新了。所以,现在我的 feisty 能正常显示中文了但不能输入,scim 能启动但就是没法换输入法,唉,忍了吧,谁让咱是中国人呢?中国博大精深的文字那些鬼佬们怎么能轻易而举地使用呢?

然后就是安 beryl,看网上教程看到头痛,丫的安一个软件这么费劲。我一怒,不管了,就把 ubuntu 的 beryl org 的源加到 source.list 里面,然后 wget 一下 key,直接 sudo apt-get update, sudo apt-get install beryl。我紧张地看着进程跑完,哈哈哈哈,居然没出问题,直接就能用。看来 Ubuntu 在这方面还是下了点功夫的。

我最喜欢 beryl 的就是桌面的转换,cool 啊,而且使用快捷键比原来 1234 桌面换来换去直接地多,也能在脑子里形成反射:恩,去左面的桌面,恩,去右面的桌面。而不用像以前一样老在想,该进几号桌面啊?

版上还有人评价 windows vista 和 beryl 达到同等效果所耗费的内存。虽然两个操作系统这么比没意思,但还是觉得 beryl 做的相当不错。

过年啦,发红包啦

本来不想写,但刚才看了一下红包的内容觉得心情很好,所以......扯两句吧!:)

快要过年了,也该回家了。今年冬天我可创下自己的很多第一次了,第一次没穿毛裤,第一次睡觉只盖一床薄被,第一次过年前才回家,第一次到现在还没有买好回家的车票......太多啦,写也写不完,总之,有意思。

不过就是再怎么也不能干耗着到走前头再买车票啊,周末还是要去车站转悠转悠滴,能买到就买,买不到就给黄牛党一个赚钱的机会,不能不回家啊。想起看《春运帝国》,"想要票的,都跟我来吧!"这会儿要是真有一个人这么一喊,我还保不准马上就凑上去了。

干了两个月也算稍微攒了点钱,也能理直气壮地花钱了,自己挣的嘛。要给我妹买个手机带回去,再捎几本经济学方面的经典教材,就算我第一次办年货啦!

唉,还是家里好啊!

人生 Regression Test

最近虽然主要在做 GDB 的移植,但也一直负责维护公司的 regression test(回归测试)框架和脚本。经常说的几句话就是:“今天 regression 过没过啊?”“我已经添加了新 testcase 的 script,你 update 一下 run 一遍看看有没有错。”而且修改程序必先 regression 再 commit 已经成了惯例。

由此想到一个有趣的话题,如果把人的一生看作是软件开发的过程的话,为了避免出现重大失误,应该怎样进行 regression test 呢?显然,这里 DejaGnu 无能为力了,expect 也不见得有多大用处。

首先,得要明确进行测试的目的,在 Grenford J. Myers 的 《The Art of Software Testing》 提出:测试是为了发现软件错误,是为了证明软件有错而不是无误。推而广之,可以说对人的测试是为了发现人的错误,为了证明人有错而不是无误。而人生的回归测试就是为了尽早地发现人的错误而不让它导致整个人生的失败。

其次,作为一种测试,有两个问题必须解决:

第一,测试的对象是什么?以曾经的所作所为为对象那不叫测试,因为那是既成事实的东西,发现了错误也无法修改。可人类又有句老话:过而能改,善莫大焉。可见,这里的错误包含的意思说,它也是可以改正的。由于讨论的是回归测试,可以这样来考虑,测试的对象是人的意识(不都标榜它是人和动物的区别嘛,具有一定代表性,而且,重要的一点是,它是值得、需要测试并且可以修改的),而曾经的作为可以看作是 log,所以部分测试结果可以通过对 log 进行分析得出,当然,会有一部分即时进行的测试用例,但这种用例都应该比较小,而且主观性比较大。

第二,测试的标准是什么?谁来做测试?拿什么标准来判断意识的对错,来判断测试用例是 pass, fail 或者 unresolved, unsupported? 如果把测试的对象看作是人的意识的话,会分好多领域。就拿道德观来说,美国人会认为入侵伊拉克是发扬人道主义精神,救伊拉克人民于水火之中(就像日本人认为侵略中国是为了使东方诸国免于受西方列强的奴役);显然部分伊拉克人会认为这是赤裸裸的侵略和对他们国家主权的亵渎。一个物质主义者会认为物质(可能具体的来说,财富)才是最重要的,他衡量自己是否成功是否幸福是否快乐的标准和物质的多少有关;而一个理想主义者更关心的可能是内心世界的和谐与宁静,以及对真善美的追求,并以此为评价标准。所以这种标准显然不适合自身以外的其它人来制定,因为很难有两个人的标准完全相同。就像软件公司都是自定义测试用例的成败一样,但不可忽视的一点是作为一个人也有目标客户,就是他想去取悦的人(没人会在乎和自己无关的人,就像没有公司会在意永远不会买自己产品的客户一样)。所以判断的标准应该是自身标准和客户标准的折衷,当然,如何折衷就得看各人的本领了。

这里得出的结论就是:人生回归测试应该由自己在外界的影响下定义测试对象、标准并且由自己执行。

再次,就应该是方法论了,如何进行测试?怎样选取测试用例?对意识进行测试,无非是拿标准和自身思想进行对照,用标准对自己所作所为进行分析。但是,这个标准是空泛的,不具体的,把标准具体化之后,就得到了测试用例。

最后,会有一个标准化的问题,怎样将测试框架、测试指标、测试用例标准化?标准化的好处显而易见,提高效率,降低成本,便于交流,提高公认度。其实古人已经做了很多工作,比如君子和小人就有两套相对标准的框架。

发现中国的古人真的好厉害,我在这里写那么多,人家用一句话就概括了:“一日三省吾身”,连测试的频率都包含了。

/* 今天把 BFD library 移植问题解决了,下面只剩下 stack frame unwind 相关的几个函数,时间较多,心情较好,闲扯几句,以为笑谈。 */