DTrace

这两天搞了一把DTrace,貌似还挺有意思的。

DTrace是个动态跟踪工具,可以在动态环境下向内核/程序中插入探头(probe),收集处理以及显示一些信息。

其实本来搞DTrace是为了一个FreeBSD的bug。搞chromecast的时候发现,IP multicast的目标mac不对。不过后来分析代码大致定位到了出问题的文件,然后在最新代码里发现这个bug已经修了(PR 185395),于是纯粹就是学习DTrace了。

一开始在我的机子上DTrace还跑不起来,后来发现是因为我跑的UEFI分支里的内核路径有些特别,于是DTrace找不到符号。打了个补丁(dt_kernel_path.patch)之后,dtrace终于能用了。

DTrace脚本的主体是一堆事件处理函数。跑DTrace脚本的时候,系统碰到某个符合的事件,就调用对应的函数。这些函数用D语言(不是那个D语言,是DTrace自己的一种语言)写成,语法和C差不多。基本的赋值/比较都能干,不过没有循环,也没有if/then/else。能控制流程的,基本上就是每个事件自带的条件,和三元操作符,也就是?:。

虽然前面那个bug是修了,我还是搞了个简单脚本来试DTrace。我希望观察arpresolve函数的参数和返回结果,也就是那个返回IP对应mac地址的函数。

arpresolve的原型是

int
arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
const struct sockaddr *dst, u_char *desten, struct llentry **lle)

我希望查看dst里的ip地址,和desten里返回的mac地址。

DTrace脚本如下:

fbt::arpresolve:entry
/execname == "ping" && arg4 != 0/
{
ip = ((struct sockaddr_in *)arg3)->sin_addr.s_addr;
a = (ip & 0xff000000) >> 24;
b = (ip & 0xff0000) >> 16;
c = (ip & 0xff00) >> 8;
d = ip & 0xff;
a4 = (unsigned char *)arg4;
printf("%s %d.%d.%d.%d", execname, d, c, b, a);
}
 
fbt::arpresolve:return
/execname == "ping" && a4 != 0/
{
printf("%s %02x.%02x.%02x.%02x.%02x.%02x", execname, a4[0], a4[1], a4[2], a4[3], a4[4], a4[5]);
}

这里定义了俩probe,一个在arpresolve的入口(entry),还有一个在返回的时候触发。probe的名字有四个部分:

<provider>:<module>:<function>:<name>

provider就是提供这个probe的组件,例如fbt就是Function Boundary Tracing,其他还有syscall追踪system call的调用等。fbt可以追踪几乎内核里所有函数的调用……

module和function确定了包含这个probe的函数。module是模块名,function是函数名。如果一个部分为空(例如这里的module),那相当于*。

name就是这个特定probe的名字,这里entry和return都是。

第一个probe其实完整名字是fbt:kernel:arpresolve:entry,最简单弄成::arpresolve:entry也可以,反正没有别的。

每个probe还能限制触发条件,例如这里的execname == “ping” && arg4 != 0。这个稍微可以弥补一些没有if的缺陷。

在fbt的entry probe中,arg0, arg1…可以用来访问参数,而在return那里,arg0有返回地址(用以区分是哪个return返回的),arg1有返回值。

据说args[i]可以访问带类型的参数,但是我没试成…… 所以这里弄来arg3, arg4强转成了参数类型。DTrace会读取内核里的类型信息,所以各个数据类型直接就能用,这里就不用自己定义sockaddr_in了。转完之后,直接打出来就可以了。

因为在return那边没法读取参数,在entry里我先存了起来。

存了脚本,用dtrace -s就可以跑了。跑出来大概是这样:

> sudo dtrace -s arp.d
dtrace: script ‘arp.d’ matched 2 probes
CPU     ID                    FUNCTION:NAME
  1  20699                 arpresolve:entry ping 239.255.255.250
  1  20700                arpresolve:return ping 01.00.5e.7f.ff.fa
  3  20699                 arpresolve:entry ping 239.255.255.250
  3  20700                arpresolve:return ping 01.00.5e.7f.ff.fa
  1  20699                 arpresolve:entry ping 239.255.255.250
  1  20700                arpresolve:return ping 01.00.5e.7f.ff.fa
^C

当然这个是已经修完了的,修之前ip是网关的ip,mac变成了网关IP根据multicast对应规则转换成mac的结果,例如ip是192.168.1.1,mac是01.00.5e.28.01.01,总之很诡异…… 其实multicast情况下mac应该是用dest ip转的,那个修正也就是修了这个。

DTrace看上去挺有用的,对调试来说简直是静态调试的理想环境,插入调试语句都不用中断运行,也不用担心调试语句写错导致系统crash,还可以访问符号,大大加快调试速度。profiling应该也挺有用,不过我还没研究。

不过没有循环我倒是觉得可能会造成一些麻烦,例如在链表里找东西之类就不好找了。估计还是为了安全性验证和效率考虑吧,不过如果信得过的话,允许程序员用也未尝不可啊。

DTrace一开始是Solaris搞的,后来Mac和FreeBSD都port了一份过来。根据布总的教导,各个系统都有,windows下面有个可以处理SQL语句的,Linux虽然官方内核没有,但是有一堆第三方的。

导热硅脂

家里的台式机CPU温度过高已经很长一段时间了。一个i5-2500K的CPU,全功率运转的时候温度轻松上百,在BIOS里面看着温度监控都能到87,平时闲着也有七十几,这俨然不正常。

前两天拆开来,发现风扇里面好多灰…… 于是清理了一把。本来想着这回应该没问题了,结果开机之后状况依旧,丝毫没有好转……

拆开来的时候发现风扇底下的导热膏已经全干了,剩下一层灰状物质分布在散热片表面和CPU表面。之前听说过导热硅脂干了会影响散热,因为硅脂干了之后,CPU和散热片之间会有空气间隙,导热很差,于是CPU的热量无法传达到散热片上。这种情况需要换新的导热硅脂。虽然没搞过,还是可以一试。于是去Amazon上随便搞了个5刀的导热硅脂,搞败了也没啥损失。

 

今天硅脂送到了,拆开来之后看上去是个针筒,不过比较细,头上有个盖子。

拆下CPU上的风扇,把上面的旧硅脂车掉,再把CPU拆下来也这么搞一遍。全搞干净之后,我开始研究硅脂怎么涂……

网上说可以用玻璃棒啦针头啦之类的涂。拧开盖子之后,看上去就是个针筒头的样子。把针筒顶在散热片上轻轻按下去,出来了大约1mm粗细的牙膏样的东西。

反正我也没有别的工具,干脆直接用这个针筒的头来涂。重复着挤出来一些再抹到边上去的操作,直到看上去基本上都布满了……

看网上的说法应该均匀涂,还要啥薄的像纸但是没有空隙…… 想想反正装上去之后就会压平的,谁管那么多……

 

涂完之后把风扇装回去,因为装得不太顺利还抬起来了几次。装完之后,怀着忐忑不安的心情开机……

貌似效果还不错,BIOS里看看也就四十几,进了系统闲着也就四五十的样子。全功率跑起来,温度升…… 升…… 也就升到刚过七十。

现在跑了几个小时了,还是71~73的样子,系统温度35。看来基本上算是成功了。

之后再观察个几天,看看会不会有所反复。终于可以全功率跑程序了……

搬家

10月底的时候,我从学校提供的一个宿舍搬到了另一个宿舍。

× 起因

我一直听说学校宿舍是可以申请换的,我也知道我那个宿舍比起周围的贵不少。但是出于惰性,一直没有搬。

这回暑假实习回来,不但租我房间那个人把房间搞得一团糟,我室友还在我不在的时候几乎占据了整个客厅,让他GF就住在他房间里。这大大增加了我搬家的动力,于是到了10月初可以申请换宿舍的时候,就去网上交了个申请。

× 过程

结果倒是很快就批下来了,还提供了两个选择。

一个在125街附近,离地铁站倒是很近,附近还有个麦当劳,以及我们公认附近最好吃的拉面店Jin Ramen。不过那个地方偏北,接近黑人区,不太安全。不过价格是两个里面比较便宜的一个。

另一个在119街,离学校非常近,出门一分钟到学校。出于方便考虑,我觉得还是这个比较好,于是约了个时间去看了一下。

看完了觉得还不错,虽然厅比我原来宿舍小了不少,但反正也无所谓。别的和原来宿舍差不多,还不用交电费和网费。室友看上去挺和善,也是个中国人,还是个学长…… 于是就决定要了。

学校给的日程倒是很紧,说好哪天搬,哪天才能拿钥匙,第二天就要还掉原来的钥匙。

到了那天,找了个中国人开的搬家公司,花了一百多刀,就搬了过去。预先把所有东西打包到了纸箱里,于是搬起来很快,也不到一小时的样子。

× 事后

我原来搬家的一大阻碍是我觉得改地址会很麻烦,搬完之后实践了一把,还好。

大约改了这么些:

* USPS:网上就能改,不过居然要收1$…… 据说会forward信件一年,杂志一个月还是两个月……

* 杂志:CACM和Wired都可以在网上改

* 学校ISSO:可以在网上改,不过我还在担心改完了没有……

* 学校信息系统:包括一般信息和寄支票的地址等……

* DMV(驾照):虽然我还是learner permit不过也要改

* 银行:Chase和Citi都能在网上改

可能有忘了的,不过也差不多了……

新家是学校网络,网速是基本上可以撑满的百兆网,不过不知道下BT会不会被抓。到目前为止,还没啥问题……

新房一开始有点味道,我怀疑是他们重新粉刷了一次,于是头几天都一直开窗通风,后来天冷了于是作罢。现在没啥感觉了……

× 总结

搬完了还是很爽的,少了的房租加上不用交电费网费,一个月多了不止一个Nexus 7……

离学校近了好多,每天路上节约40分钟……

另外楼下就是Subsconscious了,到了饭点不用愁……

总之,早就该搬了……