致命误操作

Gigabyte BRIX (XM11-3337)在路上飘近一个多月之后,终于到手。遂即安装了Win7及Ubuntu双系统,但Ubuntu不能正常启动。通过U盘启动了Ubuntu Live去查看原因, 在准备chroot环境时,不小心打错了命令:

tar zcvf /dev/sda*

结果,硬盘上的分区及引道记录全被覆盖,好在/dev/sda*只是设备名称,只冲写掉前面几个扇区,数据区域无碍。

通过/proc/partitions里的数据重建分区,前面的主分区正确识别,但扩展分区无法识别,应该是有错位,在新建的扩展分区前后搜索”55 AA”标志,遂找到了正确的扩展分区起始位置。主引导记录的修复只好用Windows 7安装光盘来修复。

后来还要接着搞grub无法启动Ubuntu的问题,grub提示无法找到/boot/grub/normal.mod,此时grub仅支持少量和命令,如ls, set, insmod等,linux及initrd命令必须等linux.mod加载后方能生效,通过set命令查看:

prefix=(hd0,msdos3)/boot/grub

(hd0,msdos3)为/boot分区,并不是root,故需要修改prefix为: (hd0,msdos3)/grub,即

set prefix=(hd0,msdos3)/grub

之后就可以手工启动Linux 了:

insmod linux
linux (hd0,msdos3)/vmlinuz-3.8.0-…-generic ro root=/dev/sdaX
initird (hd0,msdos3)/initrd-3.8.0-…-generic
boot

Ubuntu可以正常启动了,但问题的修复还要费些脑筋,因为我的Ubuntu系统设置了独立的boot分区,早知如此当初就不这么麻烦了,好在还有个比较投机的办法,在/boot目录下建了一个指向上层目录的symbolic link:

ln –s .. ./boot

重启系统并验证grub可以正常启动Ubuntu了。

生命不止,折腾不息!附个BRIX酷照:

Gigabyte Brix

 

用CubieBoard玩转网络共享

将CubieBoard或Raspberry Pi架成Wireless Access Point的办法网上已有很多,但和我的需求正好相反,我是打算让连在CubieBoard的ethernet上的内部子网络可以共享CubieBoard的无线网络端的internet联接,即AP Client方式。

AP client的实现并不复杂,通过dhcpd及NAT即可做到。

第一步:设置有线网口(eth0)为固定ip

~# cat /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.0.1
netmask 255.255.255.0

第二步:安装并配置dhcpd服务

~# apt-get install isc-dhcp-server

添加dhcp网段地址:

~# cat /etc/dhcp.dhcpd.conf
……
subnet 192.168.0.0 netmask 255.255.255.0
{
    range 192.168.0.50 192.168.0.250;
    option routers 192.168.0.1;
    option domain-name-servers 8.8.8.8,4.2.2.2;
}

限定dhcp服务运行于连接在eth0上的子网:

~# vi /etc/default/isc-dhcp-server
……
INTERFACES="eth0"

启动dhcpd服务:

~# service isc-dhcp-server restart
isc-dhcp-server stop/waiting
isc-dhcp-server start/running, process 23686

~# ps -efa | grep dhcpd
root     23686     1  0 15:45 ?        00:00:00 dhcpd -user dhcpd -group dhcpd -f -q -4 -pf /run/dhcp-server/dhcpd.pid -cf /etc/dhcp/dhcpd.conf eth0

此时dhcpd服务架设成功,连在网口eth0子网上的电脑客户端可以自动获取到ip了。

第三步:设置无线上线

用实际的ssid及password替换下面的命令:

~# wpa_passphrase ssid password >> wpa.conf
~# cat wpa.conf
network={
        ssid="ssid"
        #psk="password"
        psk=44116ea881531996d8a23af58b376d70f196057429c258f529577a26e727ec1b
}

连接无线网络:

~# wpa_supplicant -iwlan0 -B -Dwext -c ./wpa.conf
~# dhclient wlan0
~# ifconfig wlan0

wlan0     Link encap:Ethernet  HWaddr 14:xx:xx:xx:xx:xx
          inet addr:10.0.3.93  Bcast:10.0.3.255  Mask:255.255.255.0
          inet6 addr: fe80::16cf:92ff:fe1b:34ef/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:240 errors:0 dropped:0 overruns:0 frame:0
          TX packets:497 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2299089 (2.2 MB)  TX bytes:1124901 (1.1 MB)
~# ping www.google.com
PING www.google.com (74.125.128.99) 56(84) bytes of data.
64 bytes from hg-in-f99.1e100.net (74.125.128.99): icmp_req=1 ttl=46 time=69.2 ms
64 bytes from hg-in-f99.1e100.net (74.125.128.99): icmp_req=2 ttl=46 time=59.4 ms
^C

第四步:设置网络转发及NAT

编辑/etc/sysctl.conf启用ip forward:

~# cat /etc/sysctl.conf

net.ipv4.ip_forward=1

使ip forward更改生效:

~# sysctl –p

设置NAT转发:

~# iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE

设置好NAT后,子网客户端就可以上网了。

注1:dhcpd server可以用udhcpd来替代
注2:无线网络的设置也可以通过/etc/network/interfaces来做
注3:ip forward的设置(/etc/sysctl.conf方式)重启仍然有效
注4:有关iptables的设置及防火墙配置请参阅相关资料

由Hook引起的XP Explorer崩溃

有用户反应XP系统上一拖动桌面上的图标即会导致桌面重启,验证后,证实和360安全的升级有关,360安全9.0及后续版本和我们的软件有冲突。

360安全本身太激进,作为一款安全及防毒软件来说,激进并不是什么好事,这也是我不喜欢用360安全软件的原因之一。但是在事情未查出原因之前,不能随便怪罪360,毕竟在二者不共存时,均不会有桌面崩溃的事情发生。

先通过排除法,发现冲突发生在Hook上,而且是在特定的响应拖拽事件的API的Hook上:

    ole32.dll: DoDragDrop

问题定位之后照理应该很直接了,但分析新的DoDragDrop的实现及相关代码,并没有发现明显问题。

我们的代码在一个DLL文件中,并根据需要注入被Hook的进程,此案中便是Explorer.exe。调试起来稍有些周折,但也不算太麻烦。对此类的应用层调试问题,用VS (Visual Studio)远程调试最方便。远程attach到目标XP系统上的explorer.exe进程,然后触发崩溃事件,VS直接响应,显示问题出在一条很正常的压栈(push)操作上,再查看堆栈指针,果然已经耗尽,esp所指内存为非法地址(空页)。

初步揣测可能是堆栈不够所致,explorer.exe默认的size of stack reserve是0x400000,即4M字节。为了验证是不是堆栈的问题,直接将修改explorer.exe的PE文件头,将reserved stack size改成了64M(0x4000000)。

再测试时,explorer.exe在拖动桌面图标时还是会崩溃,只是会等上一会,不像之前一拖动便立即崩溃,看来问题并不是堆叠不够所致。

通过VS中断,发现Call stack中全是iNetSafe.dll (360安全的一个模块),由此断定出现了嵌套调用,死循环。

后面继续跟踪代码的调用过程发现了这样一个有趣的事,先将相关代码列出来:

ole32.dll地址空间 【774E0000 - 7761E000】:
_DoDragDrop@16:
775D0DC0 E9 0B DA 13 EE       jmp         6570E7D0
775D0DC5 83 EC 4C                sub         esp,4Ch
。。。。。。

iNetSafe.dll的地址空间 【65700000 - 65737000】:
6570E7D0 E9 AB 3A 1E 9B       jmp         CDragDropObj::NewDoDrapDrop (8F2280h) 
6570E7D5 57                           push        edi 
。。。。。。
6570E7F5 8B 4C 24 18          mov         ecx,dword ptr [esp+18h] 
6570E7F9 8B 54 24 14          mov         edx,dword ptr [esp+14h] 
6570E7FD 51                         push        ecx 
6570E7FE 8B 4C 24 14          mov         ecx,dword ptr [esp+14h] 
6570E802 52                   push        edx 
6570E803 51                   push        ecx 
6570E804 56                   push        esi 
6570E805 FF D0                call        eax                     [eax: 6FFE00A0]
6570E807 5F                   pop         edi 
6570E808 5E                   pop         esi 
6570E809 C2 10 00             ret         10h 
6570E80C 8B C7                mov         eax,edi 
6570E80E 5F                   pop         edi 
6570E80F 5E                   pop         esi 
6570E810 C2 10 00             ret         10h

360 iNetSafe.dll 所维护的Hook地址信息:
6FFE00A0 E9 DB 21 91 90       jmp         CDragDropObj::NewDoDrapDrop (8F2280h) 
6FFE00A5 E9 1B 0D 5F 07       jmp         _DoDragDrop@16+5 (775D0DC5h) 

MyHook32.dll地址空间 【008F0000 - 00C5F000】:
CDragDropObj::NewDoDrapDrop:
008F2280 55                   push        ebp 
008F2281 8B EC                mov         ebp,esp 
008F2283 8B 0D 38 70 C1 00    mov         ecx,dword ptr […::m_OldDoDragDrop 0C17038h] 
                                                                  0C17038h:0EC9002C  ECX = 0EC9002C 
008F2289 33 C0                xor         eax,eax 
008F228B 85 C9                test        ecx,ecx 
008F228D 74 03                je          CDragDropObj::NewDoDrapDrop+12h (8F2292h) 
008F228F 5D                   pop         ebp 
008F2290 FF E1                jmp         ecx                              [ecx = 0EC9002C]
008F2292 5D                   pop         ebp 
008F2293 C2 10 00             ret         10h 

MyHook32.dll: 原地址及代码
0EC9002C 56                         push        esi 
0EC9002D 8B 74 24 08          mov         esi,dword ptr [esp+8] 
0EC90031 E9 9F E7 A7 56      jmp         6570E7D5 

流程分析:

当Explorer调用_DoDragDrop()函数时,将跳转到iNetSafe的DoDragDrop实现,地址为6570E7D0。iNetSafe的DoDragDrop函数又被MyHook32 Hook了,所以还要继续跳至地址008F2280。MyHook32执行完还会跳转至被Hook前的_DoDragDrop函数,地址存放于0EC90032处,跳转地址为:6570E7D5,即iNetSafe的DoDragDrop函数入口加上5个字节的偏移。同理,iNetSafe的DoDragDrop函数也要调用它所Hook的原DoDragDrop地址,此地址的跳转指令存放于6FFE00A0处。但奇怪的是,位置6FFE00A0所存放的地址竟指向MyHoo32的
NewDoDrapDrop(即8F2280),所以任何对_DoDragDrop的调用,将会陷入一个嵌套的死循环里再也出不来了,直到堆栈被耗尽。

从上面代码上来看,iNetSafe在前,MyHook32在后,所以iNetSafe于6FFE00A0中所保存的原_DoDragDrop地址不应该是MyHook32的,而应该是ole32的_DoDragDrop才是。

但根据Explorer.exe进程的加载模块表,MyHook32.dll的加载order为40,而iNetSafe则为103,明显是MyHook32.dll先被加载,所以Hook的顺序明显违背上面的分析。

至此,方想到问题可能出在MyHook32的Anti-UnHook检查机制上。MyHook32在一个线程里面会实时检测被Hook的函数入口代码,如果不是MyHook32自己的,则会再次尝试Hook,因为360的Hook,便导致了MyHook32的再Hook,所以结果便导致了嵌套Hook的乌龙。

问题已经明确,并不是360的问题,而是出在我们自己的程序上,实在不应该先入为主的怪罪360,尽管其中还是有不少感情因素。

调试终于结束,剩下的的事情便是思考出一个万全的Anti-UnHook机制了。

下图为Explorer.exe所加载的模块(截屏自VS2010):

HookModules-01HookModules-02HookModules-03

注:有几个DLL的图标上均有红叹号,表示是此DLL被加载到的虚拟地址空间并不是此DLL所指定的地址空间。如MyHook32.dll(此版本为DEBUG版本,故体积及占用的地址范围也比较大)其默认的虚拟地址为10000000 - 1036EFFF,而实际上却被加载至008F0000 - 00C5F000。对于DLL文件的加载及从Vista之后所支持的ASLR(Address Space Layout Randomization),以后有机会再单独介绍。

MPI小试牛刀

有朋友问我一个Fortran程序的问题,Fortran语言以前曾学过,只是时间上太过久远,所有的语法全还给老师了。看着类似天书的代码,不禁想在单机系统上已经有如Matlab这样的如此强大的数值计算软件为什么还要费力用Fortran来实现呢?!在多机或集群环境上可能会不一样,只是我对并行计算所知甚少。

集群环境上MPI使用相当多,也只是了解一些,从未实际使用过,正好趁现在有些兴趣便做了做实验。

在网上看到有个计算Pi的程序 <http://chpc.wustl.edu/mpi-fortran.html>,用Fortran写的,其实就是计算定积分:

image

文中采用的是蒙特卡洛方法,我重写了一个C语言的实现,程序MPI_mc_pi.c,并在VMware环境下做了做实验,使用了2E9个采样点,分别做了单机不同并行进程数及双结点的对比,随并行度的增加,所需时间基本上是线性减少,由于测试机是双核四线程的Intel i5 CPU,当并行度超过4时便没有什么意义了,纯粹是为测试着玩。

后面又用差分的办法重新做了同样的计算,将[0, 1)分成2E9个网格,每个进程平分空间[0, 1),如进程1为[0, 1/nprocs),进程0处理最后剩下的部分[1-(nprocs-1)/nprocs, 1),见程序MPI_dc_pi.c,计算结果基本遵循线性减少规律,但是时间上却要比蒙特卡洛方法高出很多,特别是单进程的情况下,效率差了近50%。

于是又改进了差分程序,将空间平均分布,改成各进程散布在[0,1)空间上,即每个进程在网格采样上心nprocs为步进,参见程序MPI_dc_pi2.c,如此改进后,结果和均分采样空间基本差不多,没有显著变化。

后面又用双机做了Beowulf Cluster测试(VMware + X61),每个节点限制为2个进程,因为另一台机器是双核的CPU(X61),发现双节点情况下性能明显好于单节点。

将结果汇总后做成图表如下:

MPI-mc_vs_dc

如图所示,两种差分方式基本一致,这点完全可以理解,但是蒙特卡洛方法为什么能快这么多,确实让人费解,难道是drand48()的效率比double型除法还快?想起来总觉不太可能,那就让数据说话吧:

分别对drand48()和double型除法做了测试,结果正如预料,drand48()的效率更差,分别执行1E10次的时间为:

drand48():         4m21.065s double型除法: 3m27.399s

排除了这个原因之后,剩下的可能只能在drand48()里面了,drand48()虽是高精度的48位的伪随机数产生器,其结果应该还是不够平均和随机。评估drand48()的事咱不干,所以就做了个简单实验,只要能验证计算时间和drand48()生成的随机数不平均度显著相关即可。验证程序还是采用蒙特卡洛方法,只是将随机数的产生范围限定在[0.5,1]之内,不是之前的[0, 1],结果单进程计算时间为1m59.160s,双进程为1m35.185s,这足以说明随机数的随机度对计算时间有较大影响(Pi的值对与不对没关系,此时只关注计算过程所花的时间)。

最后在Mathematica上也做了个测试,出人意料的是Mathematica只用几了秒钟就算出了1E10网格的差分,即便是定积分计算,也是完完全全的秒杀,太牛x了,不服不行!

image

本文相关代码:

mpiuser@Ubunut-X64:~/MPI$ cat MPI_mc_pi.c #include <stdio.h> #include <stdlib.h> #include <time.h> #include <mpi.h> int main(int argc, char** argv) { int myrank, nprocs, rc; unsigned long t, times, avg_times; double l_sum = 0, g_sum = 0, x = 1.0; times = 2000000000; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); avg_times = times / nprocs; if (0 == myrank) { avg_times = times - avg_times * (nprocs - 1); } /* printf("%d: points: %lu\n", myrank, avg_times); */ srand48((myrank + 1) * (time(NULL) & 0xFFF)); for (t = 0; t < avg_times; t++) { x = drand48(); l_sum = l_sum + 4.0/(x * x + 1.0); } rc = MPI_Reduce(&l_sum, &g_sum, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD); if (0 != rc) { printf("MPI_Reduce failed with error code: %d\n", rc); } else if (0 == myrank) { printf("PI result: %f/%lu =  %f\n", g_sum, times, g_sum / times); } MPI_Finalize(); return 0; } mpiuser@Ubunut-X64:~/MPI$ cat MPI_dc_pi.c #include <stdio.h> #include <stdlib.h> #include <time.h> #include <mpi.h> int main(int argc, char** argv) { int myrank, nprocs, rc; unsigned long t, grids, avg_grids, start, end; double l_sum = 0, g_sum = 0, x = 1.0; grids = 2000000000; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); avg_grids = grids / nprocs; if (0 == myrank) { start = avg_grids * (nprocs - 1); end = grids; } else { start = avg_grids * (myrank - 1); end = start + avg_grids; } /* printf("%d: [%lu - %lu)\n", myrank, start, end); */ for (t = start; t < end; t++) { x = 1.0 * t / grids; l_sum = l_sum + 4.0/(x * x + 1.0); } rc = MPI_Reduce(&l_sum, &g_sum, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD); if (0 != rc) { printf("MPI_Reduce failed with error code: %d\n", rc); } else if (0 == myrank) { printf("PI result: %f with %lu grids.\n", g_sum/grids, grids); } MPI_Finalize(); return 0; } mpiuser@Ubunut-X64:~/MPI$ cat MPI_dc_pi2.c #include <stdio.h> #include <stdlib.h> #include <time.h> #include <mpi.h> int main(int argc, char** argv) { int myrank, nprocs, rc; unsigned long t, grids; double l_sum = 0, g_sum = 0, x = 1.0; grids = 2000000000; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); for (t = myrank; t < grids; t += nprocs) { x = 1.0 * t / grids; l_sum = l_sum + 4.0/(x * x + 1.0); } rc = MPI_Reduce(&l_sum, &g_sum, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD); if (0 != rc) { printf("MPI_Reduce failed with error code: %d\n", rc); } else if (0 == myrank) { printf("PI result: %f with %lu grids.\n", g_sum/grids, grids); } MPI_Finalize(); return 0; } 编译命令: mpiuser@Ubunut-X64:~/MPI$ cat build mpicc MPI_mc_pi.c -std=c99 -W -Wall -pedantic -D_SVID_SOURCE -g -o MPI_mc_pi mpicc MPI_dc_pi.c -std=c99 -W -Wall -pedantic -g -o MPI_dc_pi mpicc MPI_dc_pi2.c -std=c99 -W -Wall -pedantic -g -o MPI_dc_pi2

ERESOURCE:和你玩躲猫猫

我是一直都知晓你的存在的,虽然你从未现身,任何时候都像操控着一切的隐形之手,但在我心里,你是世界的主宰,规则的制定者,高高在上的上帝。

我只是一个小螺丝钉,每天只是重复地做着我被要求的工作。关于我的出生,我并不清楚,因为我的创造者-“瓶瓶”老爷向来沉默寡言,从不多说话,并且一直都是忙忙碌碌。我也只能在他有空的时候,和他有一句没一句得聊聊天,这才从他口中得知关于我身世一星半点的信息。

听“瓶瓶”老爷说,他是最不愿意制造我们这些螺丝钉的。他说,每制造出一个,他的负担就会增加了一个,虽然我们都是他的长工,每时每刻不停得为他工作,但我们的衣食住行还是要“瓶瓶”老爷为我们打点才行,这也是忙碌的他在空闲时经常向我们发的牢骚。不过,尽管他爱发些不着边的牢骚,我们还是很喜欢他,毕竟他创造了并一直照顾着我们,我们真心地愿意为他打长工,哪怕是一辈子,只要这个世界存在并运转着。

但就在前些日子,世界不在像以前那么可靠了,原因是那只隐形的上帝之手在规则上所做的一个很小的改动,改动虽小,对我来说却是灾难,从此我的世界整个都变成瓦蓝瓦蓝的了(Blue Screen Of Death)。生活如此简单的我,与世无争,咱这井水犯不着任何一条河水,真想不到哎,躺着也会中枪。

我只是重复着做一丁点儿的事,说来也很简单:以Paging I/O的方式去从文件里读数据出来。至于为什么要以Paging I/O方式,我曾问过“瓶瓶”老爷,他说的话很长很长,很深奥很深奥,我只记住了一点点,希望我的复述你能听得明白:

我要读的文件是于用户层中打开的,而我却生活在内核里,我的另一个哥们会将用户层的HANDLE转成FileObject并交给我,之后用户层会将这个HANDLE释放掉(CloseHandle),这时候我虽然手上有Fileobject这把钥匙,但通向Cached I/O及Direct I/O的路全给封上了,只有Paging I/O这条黑路让我去走,我的职责如此,即便是刀山火海,也只能认了。但自从世界变成Win7之后,我总会遇到麻烦,连Paging I/O这条黑道有时也不让我走了,特别是看起来更炫的Win8世界,任何时候都是瓦蓝瓦蓝的。

当时我很伤心,世界一片惨蓝,我以为再也见不着太阳了。可“瓶瓶”老爷又让我重获新生。所以我更感激他了,我发誓愿意为他打二辈子长工,最多只能二辈子,不能再多了,因为我们所处的这个世界一直是很二很二的。

在世界又恢复至正常后,“瓶瓶”老爷曾对我说,或者是老爷他自言自语地说:Win7世界的NTFS动了点手脚,在获取文件ERESOURCE锁后,它会改变此ERESOURCE的Owner Thread’s Pointer(参见ExSetResourceOwnerPointer)!虽然我知道在Filter中是不应该操作此ERESOURCE锁的,但针对这种情况,也是不得已而为之,做个简单的Paging I/O也不是什么危险或惹事的操作。

“瓶瓶”老爷现在让我获取两次共享锁并在释放锁时多做个判断,你想看看我最得意时的状态吗?

0: kd&gt; dt _ERESOURCE 0xfffffa80&#x60;02b62050; !locks -v 0xfffffa80&#x60;02b62050;
nt!_ERESOURCE
+0x000 SystemResourcesList : _LIST_ENTRY [ 0xfffffa80&#x60;02b620f8 - 0xfffffa80&#x60;029030d0 ]
+0x010 OwnerTable       : 0xfffffa80&#x60;03ba48c0 _OWNER_ENTRY
+0x018 ActiveCount      : 1
+0x01a Flag             : 0
+0x020 SharedWaiters    : (null)
+0x028 ExclusiveWaiters : (null)
+0x030 OwnerEntry       : _OWNER_ENTRY
+0x040 ActiveEntries    : 2
+0x044 ContentionCount  : 0
+0x048 NumberOfSharedWaiters : 0
+0x04c NumberOfExclusiveWaiters : 0
+0x050 Reserved2        : (null)
+0x058 Address          : (null)
+0x058 CreatorBackTraceIndex : 0
+0x060 SpinLock         : 0

Resource @ 0xfffffa8002b62050    Shared 2 owning threads
&lt;strong&gt;     Threads: fffffa800196ab53-01&lt;*&gt; *** Actual Thread fffffa800196ab50&lt;/strong&gt;

THREAD fffffa800196ab50  Cid 1364.1368  Teb: 000007fffffde000 Win32Thread: fffff900c229fc20 RUNNING on processor 0
IRP List:
fffffa80042c2c40: (0006,0118) Flags: 00060043  Mdl: fffffa80045c7340
Not impersonating
DeviceMap                 fffff8a00256f460
Owning Process            fffffa80019b9b30       Image:         notepad.exe
Attached Process          N/A            Image:         N/A
Wait Start TickCount      8907           Ticks: 0
Context Switch Count      219                 LargeStack
UserTime                  00:00:00.000
KernelTime                00:00:00.592
Win32 Start Address 0x00000000ff383570
Stack Init fffff880171f1db0 Current fffff880171f0940
Base fffff880171f2000 Limit fffff880171e9000 Call 0
Priority 10 BasePriority 8 UnusualBoost 0 ForegroundBoost 2 IoPriority 2 PagePriority 5
Child-SP          RetAddr           Call Site
fffff880&#x60;171f17b0 fffff880&#x60;159d69de Foobar!FbDirectReadWriteSingle+0x2a1 [Foobar\read.c @ 332]
fffff880&#x60;171f1840 fffff880&#x60;159d73a8 Foobar!FbDirectReadWrite+0x85e [Foobar\read.c @ 628]
fffff880&#x60;171f1930 fffff800&#x60;01cbb1b5 Foobar!FbDispatchRead+0x18 [Foobar\read.c @ 1172]
fffff880&#x60;171f1960 fffff800&#x60;01cbac89 nt!IoPageRead+0x255
fffff880&#x60;171f19f0 fffff800&#x60;01ca165a nt!MiIssueHardFault+0x255
fffff880&#x60;171f1ac0 fffff800&#x60;01c920ee nt!MmAccessFault+0x146a
fffff880&#x60;171f1c20 00000000&#x60;ff384061 nt!KiPageFault+0x16e (TrapFrame @ fffff880&#x60;171f1c20)
00000000&#x60;000fde80 00000000&#x60;00000000 0xff384061

&lt;strong&gt;              fffffa800196ab50-01&lt;*&gt; &lt;/strong&gt;

THREAD fffffa800196ab50  Cid 1364.1368  Teb: 000007fffffde000 Win32Thread: fffff900c229fc20
……

哈哈,不论你怎么躲,也躲不开我了,因为我知道了你所有的藏身之所。现在想改变规则了?你想怎么改呢?

我是个简单的小螺丝钉,我不惧怕任何权威,我吃苦耐劳,我要求很少,只要不让我的世界一片惨蓝,做再多的事我也愿意。

现在我的生命力更顽强了,我不仅会点自检,还会些自愈。面对这个美好的世界,只想说一句话,那就是:活着真好。

最后,我的id是“螺丝钉小P”。你的呢?我知道你有多个马甲的,嘿嘿!

摘自“螺丝钉小P”的日记(DEC/12/2012)

 

A Half Day

Pingping (瓶瓶) is a software engineer, as thousands of other software engineers, everyday he codes, everyday he gets bugs, so everyday he de-bugs.

Today is just a normal day that every normal software engineer would normally have.                                                  

This afternoon, when testing his software, trying to save something he randomly typed in windows notepad, he encountered an error. To confirm, he restarted a new instance of windows notepad, and got the same error.

It's an obvious bug.

So he debug.

Soon he was absorbed in his interesting enterprise of debugging. One round after another, every restart he typed something to verify, until the end of the bug.

It was already mid-night. On his computer's screen, was a long log in windows notepad.

I’m too somehow a night bird. When I occasionally saw it and thought it was interesting, then I made a copy, because I know, pingping is a guy who is always seeing forward, he would let it go and ghost his test system to a fresh, with all data destroyed.

So luck for you, here's the log, also for pingping if he isn't coding or debugging right now.

Round 1, 2012/12/07 13:06
Hi buggy, I'm waiting for you … 
   
Round 2, 2012/12/07 13:10
Now we are acquainted. But I still don’t know where you are from and when you arrive here. Tell me your story, let me know you, Pleaseeeee !

Round 3, 2012/12/07 13:17
You are really a hard nut, just my taste, I'm nailing up you.

Round 4, 2012/12/07 13:26
Huh, you are so deeply hid. But anyway, it's just a matter of time for me to get you, shorter or short, haha.

Round 5, 2012/12/07 13:39
What a doggy luck you have today ! But you are almost running out of it, I'm sure of that.

Round 6, 2012/12/07 14:02
Ok, fine, fine, you are good, really good. Unfortunately, I will NOT give up.

Round 7, 2012/12/07 14:30
Now I know you better, know you more. Don't bother to hide any more.

Round 8, 2012/12/07 14:37
You are good at hiding, but remember I'm damn good at seeking, top level in the world.

Round 9, 2012/12/07 14:52
Once i catch you, I'll screw your neck, and squeeze your head. So pray now before it's too late.

Round 10, 2012/12/07 15:09
pang !

Round 11, 2012/12/07 15:29
peng !

Round 12, 2012/12/07 15:40
bang !

Round 13, 2012/12/07 16:01
Yes, I'm still here, with full eyes on you. You, little damn buggy, show yourself !

Round 14, 2012/12/07 16:20
bang ……

Round 15, 2012/12/07 16:32
peng ……

Round 16, 2012/12/07 16:50
pang ……

Round 17, 2012/12/07 17:03
Ah, finally, I got you. now you know I'm a damn good seeker.

Round  18, 2012/12/07 17:09
Hurrah !

Round  19, 2012/12/07 17:16
Yippee, did one more test just to confrim. I'm quite satisfied of your disapperance.

…………

Round 20, 2012/12/07 18:00
I'm back, little buggy, are you there ?

Round 21, 2012/12/07 18:15
I'm back again, little buggy, can you hear me ?

Round 22, 2012/12/07 18:20
where are you ? playing with another software engineer ? is he cool ?

Round 23, 2012/12/07 18:25
???

Round 24, 2012/12/07 18:30
I know now, just because of the half day we stay together, a bug is not only a bug, but a present of a secret. Of all bugs, you are the secret of all secrets.

Round 25, 2012/12/07 18:40
I … I,  starts missing you.  

Round 26, 2012/12/07 19:00
Hi there, if you can hear me. I'm here to say goodbye. I must go now, another bug was just coming. For the first time of the life, I just feel so sad to leave. May I see you again ?

< Dec. 07 night, on the train from Beijing to Jining Shandong. >