wpe7.jpg (11495 bytes)

我的征尘是星辰大海。。。

The dirt and dust from my pilgrimage forms oceans of stars...

-------当记忆的篇章变得零碎,当追忆的图片变得模糊,我们只能求助于数字存储的永恒的回忆

作者:黄教授

二〇一五


一月一日 当前只有等待等待

很 随意的尝试s3在本地磁盘化的方案,这个是我自己起的名字,看到的有s3fs和s3fuse,简单看了s3fs的代码,发现不能用不明白他的key是怎么 设置的,好像很就没有更新了。决定还是自己徒手尝试用我的包装过的libs3-2,把fuse的helloworld改动一下就可以了,还有很多细节,参 考s3fs的代码,它的有点在于有cache,可是不太好改造。一直想要看看nfsclient的代码参考一下。

一月三日 当前只有等待等待

尝 试使用新版本的s3fs-fuse是 在github上的,./s3fs -f -o uid=1000,gid=1000,rw,default_permissions,use_rrs=1,default_acl=public-read-write,use_cache=/tmp www.staroceans.org ~/www.staroceans.org
可是问题是我的文件的权限都为空,似乎是meta的问题,它的代码使用的是replace。没有找到原因。google说不如尝试另一个riofs,这个 据说更加稳定,编译这个遇到libevent需要2.0以上,我不想更新,就下载源码编译安装到/usr/local然后使用./configure --with-libevent=/usr/local,然后编译riofs遇到undefined reference to `ERR_remove_thread_state',我的反应非常迟钝居然以为是libevent的依赖,别人都已经说了是openssl的问题,后来 google具体的riofs的错误,才意识到是我的openssl0.9.8的问题,我一直也不愿意更新,只好手 动改代码,把ERR_remove_thread_state换成了0.9.8的版本ERR_remove_state。

一月四日 当前只有等待等待

我 的s3上打开了logging结果有巨大数量的log file这个导致了riofs和s3fs-fuse都无法正常工作,因为运行几个小时都无法初始化,不知道为什么我的libs3的代码可以迅速初始化(大概几分钟吧?)。 删除这些垃圾没有什么好办法,这个是使 用lifecycle.不过好像没有效果???
debug我的delete object的代码才发现以前的无知,我手动编译libcurl链接然后运行期的时候使用的还是系统的动态库,这个问题是多么的危险,现在工作里面天天遇 到才意识到。这个是curl的编译配置:./configure --disable-optimize --enable-debug --disable-ldap --disable-ldaps --without-libssh2 --without-libidn --without-zlib --without-libssh2
我每次都在gethostaddress_r哪里死掉,看来是线程的问题吧?在eclipse里查看gdb的输出发现了这个四成像是的错误,google 发现也许是gdb的版本问题?Dwarf Error: wrong version in compilation unit header (is 4, should be 2) [in module /usr/lib/libstdc++.so.6]
决定再次编译gdb7.7,以前似乎我debug过gdb自己,(gdb gdb exe??)不敢安装覆盖,决定使用symlink尝试。的确是gdb的问题,升级到gdb7.7后能够正常debug了,curl的回调函数的断点可以 了,然后遇到很傻的问题。printf的format有错误,我使用cout输出不正常,只能用fprintf(stdout,...)这个真的无厘头 了,也许cout.tie的不是正确的stdout?被curl截断了?

一月六日 当前只有等待等待

riofs 似乎还在童年时代,几乎不可用,现在看来s3fs不一定是问题,权限也许是有意设置的。但是性能呢?的确不是特别的好,所以,出路看来是类似与rsync 的思路,或者单独实现一个push/pull的s3版本,这个似乎是最好的解决办法。比如,jgit的实现形式。

一月七日 当前只有等待等待

git 的默认的路径.git可以指定,git --git-dir=mygit init,然后就要这样子git --git-dir=mygit --work-tree=./ status

一月八日 当前只有等待等待

一 直以来有一个不是很准确的认识,git本身是一个不需要server的架构,因此,不需要像svn一样架设服务器,因为它是基于文件啊。并不是非常的准 确。这个取决于服务器通讯的协议啊。比如你要把你的git部署在像亚马逊s3这样的static web site仅仅实现dumb http协议要怎么版呢?你需要这个步骤

1.设定hooks/post-update。比如:mv hooks/post-update.sample hooks/post-update && chmod a+x hooks/post-update
2.互联网的url能使用.git文件夹名作为url的一部分所以改名字比如repo.git为了方便我增加了~/.bashrc的一个alias:
alias mygit='git --git-dir=repo.git --work-tree=./'
3.第一步似乎不起作用,所以,我就手动这样做:
mygit add mynew.txt
mygit commit -m "adding mynew.txt"
mygit update-server-info
s3cmd sync --acl-public ./ s3://nickhuang99/tinyxml/
4。在其他地方用git clone如下:git  http://nickhuang99.s3.amazonaws.com/tinyxml/repo.git tinyxml

不过s3cmd似乎效率不是非常的高吧?我还是用我自己的工具吧。

怎样debug呢?GIT_CURL_VERBOSE=1 GIT_TRACE=1 git pull origin master


一月十日 当前只有等待等待

如 果要发布git代码,有两个方式,push或者pull,选择push意味着要设定为bare,不能有checkout,git config --bool core.bare true,缺点是默认的git-dir一定是.git,这个不能是网络的目录,所以,我还是选择pull,在准备同步的目标文件夹下mygit clone /src/path/.git ./production/path然后就是正常的pull了,随后使用s3cmd sync或者我自己的工具去上传到amazons3。
在工作中我们需要多平台编译测试,因此使用了HNAS的nfs来在多平台mount,于是遇到最最常见的文件权限的问题,这个是nfs的最最基本的问题, 高级的解决办法是使用nfs server端设定user mapping我觉得这个在nfs client端也需要的吧?为了简单我们都是用root来开发,于是在nfs server端的access configuration设定*(sec=sys,no_root_squash)于是linux的mount问题解决了,但是在windows端 nfs的uid,gid始终都是-2,我google实验了很久,看了不少的msdn/technet的文章,感觉要么使用AD+DC,要么使用AD+ LDS,最不济也要安装Identity Management for Unix等等,单单配置user mapping的数据就够复杂的,而且安装AD,DC本身就是很费时间,装好了还不能正常运作,似乎我没有配置DNS服务,总之,我花了两天也没有搞定。 终于看到这个极端的hacker的办法:修改注册表,在HK_LOCAL_MACHINE下找到 microsoft/clientForNFS/default设定anonymousuid=0,anoymousgid=0。

一月十三日 当前只有等待等待

以 前以为passwd hash的代码应该在内核,现在才明白这个是纯粹“文件系统”或者说linux distribution的工作,所以,crypt是在glibc,我的case是使用的ubuntu-eglibc2.11版。
昨天把我之前使用过的git的代码通通都放到s3上去了。大部分都是开源代码,只不过做一个备份而已。

一月十七日 当前只有等待等待


这里是安 装hp-printer的instruction。 也许就是ubuntu我的设置的问题,我在gui里的设置不是su运行的,所以设置无法保存,所以,需要在命令行运行sudo hp-setup。很多时候你并不理解什么是什么,比如你究竟需要做什么,在ubuntu里添加网络打印机核心问题不是添加,而是设置,因为打印机不再提 供用户界面去设置这个才是hp最最需要解决的问题,这也就是它各种各样的设置软件工具的目的,一旦设定好了网络你为什么还需要hp的打印机管理软件呢?不 需要了。使用ubuntu 的原生的打印机管理就 可以了。当然第一步是最困难的,当打印机不能上网的话,你什么也干不了,这个才是使用usb连线的根本原因,仅仅是设置wifi然后,你可以通过ews (embedded web service)来设置,可以设置web-scanner,设置static ip,192.168.1.247。
在rhel里面,dns的产生是靠/etc/sysconfigs/network-scripts/ifcfg-eth0里的设置的dns ip,它的运行产生/etc/resolve.conf,修改resolve.conf也许暂时有效,比如service NetworkManager restart。

一月十八日 当前只有等待等待


可以写一个小小的总结:怎样搞垮你的ext2文件系统。我只不过创建了一个循环的软连接,然后文件系统就崩溃了,怎么这个样子?ln -fs link1 link2; ln -fs link2 link3;ln -fs link3 link4;ln -fs link4 link2;ln -fs fakedir link1;mkdir fakedir;
于是我遇到了一系列的问题,首先报错软连接太多层了,然后就是文件的错乱,我的/etc/fstab居然坏掉了,boot失败:这个是回复的步骤:
1. ls (hd0,1)/确认这个确实是启动分区,
2. set root=(hds0,1);
3. set prefix=(hd0,1)/boot/grub;
4. insmod normal;
5. normal;
6. sudo update-grub
7. sudo grub-install

一月二十八日 当前只有等待等待


就在我写下怎样搞垮你的ext2fs的时候,我发现我还搞坏了我的主板,我的华硕kgpe-k16终于坏了,四百美金的主板还只是一部分,搜索能够匹配 AMD optron cpu的同类主板都更贵,这意味着我不得不再买一块。接下来就是十天的折腾,在确认主板坏之前我要验证是否电源坏了,是否机箱坏了,结果就去Fry's这 个DIY天堂买了机箱和电源,可惜他的机箱是给gamer设计的电源插槽在主机的另一侧够不着主板只能退掉。(学到了怎样验证电源好坏的办法,把4号绿线 短接旁边的线就是相当于主板开机,如果电源风扇转动就是好的,或者用万用表量每个电压。)我的主板是自带BMC的,我之前没有看过说明书不知道,准备实验 一下。同时发现了主板上一个自带的usb就把我的额外的usb硬盘盒子接上去,因为6个sata接口全用掉了,虽然主板上有一个PIKE插口可以接 asus自己的raid,可是这个PIKE设计者真糟糕因为散热板是向内的把我的PCI卡挤掉了位置,虽然很气愤,但是说实在的这个是主板设计者的问题, PIKE肯定不能向外超过主板的范围。打印机又坏了,就去买了一个超便宜的30块的激光打印机(pantumP2502w)w应该是wifi的意思,现在 的驱动做的都不错,win7自动安装驱动,我没有admin权力运行公司笔记本,本来发愁发现驱动已经装好了,不过作为wifi打印机原本usb链接就不 是问题,主要是设置wifi密码,只能尝试安装linux驱动,安装脚本写的不很好,unzip的目录名带空格,运行getconf LONG_BIT可以得到内核是否32/64,这个是 强帖:cat /proc/cpuinfo寻找flags的lm标志说明是否是32/64的cpu,但是你的os可能和这个不一致的,64kernel能运行在 64bit的cpu,uname -m告诉你的都是os的架构,当然这如果是你要的。lshw -class processor也不错。
回到pantum打印机的问题,驱动不是问题,但是怎么设置wifi密码呢?说明书说是有内置的webservice,(ews)可是ip呢?linux 的驱动直接报了一个gtk的错误,我直接dpkg -i安装了driver的包,可是无法运行设定wifi的程序,后来回到windows发现其中的wifi设置程序不需admin权力运行,这个才解决 了。
现在主流的wifi打印机的所谓驱动都是被我这种人误会了,事实上今天的驱动开发安装都很成熟了,主流操作系统都帮你做的差不多了,就像我花了无数时间安 装hp的打印机程序,最后才明白它所做的最大的工作是帮助你设置wifi密码,使用Usb连线安装驱动都是小菜一叠。当然对于我经常有白痴的问题,我以为 打印机坏了,实际上是因为门没关上,激光的不工作实际是粉盒里的保护带没有去除。

昨天遇到stdint.h的问题,uint64_t这个和unsigned long long int究竟有区别吗?不知道。但是我昨天知道了typedef是不能用#ifndef来检查的,通常作typedef都要连带作一个#define就是为 了用#ifdef来检查,因为多次typedef同样的不会错,但是不兼容的则会错,而define是傻傻的替换,多次覆盖是合法的。
工作中需要在古老的lenny5.10上开发,遇到了gcc4.3上没有实现to_string的问题,这个是stl的问题,只能从gcc4.4版本相应 的拷贝过来。系统没有安装service,只能用古老的/etc/init.d/ssh restart来重启,它的debian.org上的package都被移到archive里去了,所以,/etc/apt/source.list里相 应的要改动,同时security不再支持了都去掉吧。svn是古老的1.5,和rhel的1.6不兼容,别人没问题,可是我是用nfs的多平台都要访问 同样的svn co,所以只能自己编译svn,这里的关键是不要自己想当然啊的直接configure,需要先运行getdep.sh下载需要的apr,apr- util,然后分别运行他们的buildconf(你需要安装autoconf),然后autogen.sh再去configure,需要openssl 的开发包,是libssl-dev不是openssl,这个是命令行工具。


一月二十九日 当前只有等待等待


显卡的问题其实是amd的驱动的问题, 就是不要使用fglrx的驱动,而是要mesa,sudo apt-get install mesa-utils, 首先需要删 除所有的fglrx

  sudo apt-get remove --purge xorg-driver-fglrx fglrx*
sudo apt-get install --reinstall libgl1-mesa-glx libgl1-mesa-dri xserver-xorg-core
sudo dpkg-reconfigure xserver-xorg
sudo apt-get install --reinstall libgl1-mesa-glx:amd64 libgl1-mesa-dri:amd64 libgl1-mesa-glx:i386 libgl1-mesa-dri:i386 xserver-xorg-core
检查:
dpkg --get-selections|grep libgl1-mesa
同样要去除nvdia的驱动:
sudo nvidia-settings --uninstall
sudo apt-get remove --purge nvidia*
sudo apt-get remove --purge xserver-xorg-video-nouveau xserver-xorg-video-nv
sudo apt-get install nvidia-common
sudo apt-get install xserver-xorg-video-nouveau
sudo apt-get install --reinstall libgl1-mesa-glx libgl1-mesa-dri xserver-xorg-core
sudo dpkg-reconfigure xserver-xorg

今天在安装lenny的时候遇到ssh不能使用public key来验证的问题,SSHD Gives error could not open Authorized Keys, although permissions seem correct‏
这个
是 答案:
restorecon -FRvv ~/.ssh
不知道这个是怎么回事,但是就正常了。


一月三十日 当前只有等待等待


用ssh -X链接然后启动kompozer编辑,可是我无法激活输入法,看来是没有焦点的问题吧?
打印程序dpkg-deb -x打开一看是一个动态库,原因是我的32位的ubuntu笔记本可以正确安装驱动,64位的台式机不行,结果ldd发现64位需要glibc2.14 版,而32位你猜猜看,它居然和公司的那个日本人开发的动态库一样把stdlib静态编译进了,难怪。看来这个也许不是偶然的,是和开发环境有关的,不是 某些人的疏忽或者突发奇想。我的google-talk-plugin也无法安装,看看能不能这样子安装。
不敢贸然安装编译什么,于是还是要安装虚拟机做实验。重复一遍,先安装virtualbox-4.2版,然后安 装这个官网的包,如果遇到dependency的问题,可以尝试sudo apt-get install -f
今天写了一天的makefile其实是调试了,除了一个洋相问题,我的X_DIST=$(shell uname -m)总是带空格,使用了无数的办法来去除都失败,最后才发现是我的变量后面有空格,这个真的是要命,在makefile里你不检查的。还有就是 SERVER_OBJ=$(patsubst %.cpp,obj/%.o,${SERVER_SRC}))在svn里rename和mv是有大区别的,rename我没有做到recursive,结 果里面的文件子文件夹通通被删除了,用mv就不会。

一月三十一日 当前只有等待等待


临晨五点醒来,赖在床上看微信邮件,六点起来跑了500米,回来继续编译内核,买了一个很贵的raid卡,需要编译内核,才发现我的硬盘在上一次灾难中变 得面目全非,找不到当初的内核代码了,难怪安装virtualbox编译dkms运行失败,我压根指向的内核代码是2.6的git branch,按照阴谋论的逻辑应该是ssd的灾变,我始终有一个幻想认为ssd的产品都存在严重缺陷,在某种情况下你的数据会全部或部分的丢失, relocate sector的结果就是你得到了早先的一个版本的数据,因为现在ssd的存储原理很想是CoW的模式,为了节省删除合并的操作,都是不 overwrite,导致一旦出错你的delta部分都corrupted。因为我始终有一个dejavu的感觉好像又回到了一两年前开始编译内核的状 态。

二月一日 当前只有等待等待


记忆完全丧失。编译内核的步骤完全遗忘了,我曾经修改过setlocalversion的脚本试图改变每次新版本都是“+”的行为,但是google search的site search似乎不再是免费的,我无法找到,还是我完全没有上传?感觉丢失了很多东西。至少现在知道一下的问题:
mkinitrd不再支持,替代是mkinitramfs -o  initrd-img-`make kernelrelease`  `make kernelrelease` 但是你要手动修改/boot/initrd.img的软连接。
安装依旧是make install,但别忘记make headers_install modules_install否则你的问题就大大的,你懂得的。
要简单运行sudo update-grub而不是update-grub2那个是完全不同的东西,我模糊记得我曾经话了好多时间在折腾着个。还是返同样的错。

二月二日 当前只有等待等待


这个大概是最普通的问题,你在一个dll里面定义的函数如果是带有namespace的话,那么你的实现一定要 “在namespace里”。这个难道你都 不明白吗?可不是吗?我就竟然没有意识到使用using namespace并不代表你要把你的代码归结到namespace内。这个我觉得也许是链接的问题?这个是一个例子git clone http://www.staroceans.org/myprojects/dlllink/repo.git

二月三日 当前只有等待等待


这个是一个教训,就是对于c函数而言的确实现要放在namespace里,但是对于c++的类而言,只要声明放在namespace里,实现不用的,只需要 using namespace就可以了。
另一个问题就是makefile里缅的include,这个我始终要纠正一个误区,就是默认只去找第一个条件,满足了就停了。所以,你的all:放在后面 都是没有用的,all在make眼里和别的条件没有差别。那么你在include里的文件里定义了什么condition,就不要怪主makefile不 会再执行了,因为首先是执行include里的。
关于(test -f fileIfExist || test -d dirIfExist)这类的||是什么意思呢?是逻辑吗?应该是看shell的返回值echo $?,对于不存在的文件,test -f返回1,总体上说不是逻辑而是看返回值是否为零,因为0代表成功无错误,凡事1都是错误,||的意思是只要一个成功就可以,&&要两 个都成功,换言之,||失败第一个还要继续,但第一个成功就停下来了。&&则是第一个失败就停下来。这些是不是太粗浅了,说明我无知的厉 害?可是我确实是一知半解啊。

二月四日 当前只有等待等待


很多人和我有着共 同的想法,简单的做法就是make LOCALVERSION=3.0.69-102
现在没事就把内核编译一下,看看驱动是否能够找得到,这个太弱智了,完全是瞎撞。

二月五日 当前只有等待等待


每次都要安装声卡驱动,这 里的东西抄下来:
1. 看看os是否有声卡设定了: sudo aplay -l
2. 看看声卡模块是否安装了:find /lib/modules/`uname -r` | grep snd
3. 看看声卡是否确实被内核识别了:lspci -v | grep -A7 -i "audio"
4. 看看alsa 是否支持这款声卡

二月六日 当前只有等待等待


如何重启ibus呢,它不是一个service,这 里说的好,ibus-daemon &就好了,因为它会替换之前的instance。
经过长时间的摸索依然没有结果,alsa安装25版可以,28版有错误。但是声卡依旧不能被alsa识别,严格的说是有识别,但是alsaconf有问 题,update-modules这个脚本不存在了。我模糊记得这个问题和另一个mkinitrd很像,都是要Initramfs来做的,但是这个。。。这 里说的好清楚,xsonar dgx要内核3.14以后才支持的,我的ubuntu 10.04最新的内核也只有3.0,难道我要自己编译实验新内核?同样的声卡是pci的就可以,难道pciexpress的卡驱动就差别很大了吗?
在公司配置centos6.5遇到x11的问题,这 个说的很好
yum install xorg-x11-server-Xdmx.x86_64
yum install xterm.x86_64
yum install xorg-x11-xinit.x86_64
nfs client也没有正常工作,需要安装如下:
yum install nfs-utils.x86_64
/sbin/rpc.statd
service nfslock start

二月八日 当前只有等待等待


果然是这样子的,我从git://kernel.ubuntu.com/ubuntu/linux.git下载内核代码,checkout到3.14在声卡驱 动里看到了pcie的驱动,编译安装很顺利,
git checkout 3.14
cp /boot/config  .config
make oldconfig
make menuconfig
make -j10    《《====夸张吧我有24个cpu为什么不用呢?
sudo make headers_install modules_install install
sudo update-initramfs -c -k `make kernelrelease`
sudo update-grub
sudo reboot now
我一开始的确还是有问题无法听到声音,可是你知道我确确实实有声卡设备在aplay -l里,而且alsamixer也可以设置,除非是非常非常的不走运是声卡的port插口有问题,一切都应该正常。我没有那么“幸运”,声卡工作了。
一个tip就是可以大胆的尝试新版的内核,它对于设备的支持的确好太多了。当然这个还是ubuntu小组customised的内核,是经过检验的。

二月十三日 当前只有等待等待


Linux的内核是相当的灵活的,其实内核最主要的发展现在都是驱动的支持,真正的内核代码据说改的很少吧?现在我用的是3.18,目的是想看看asus mio的驱动是否有了,结果是没有。
使用poco里面的一个核心现在才领悟到,其实是很简单的常识,但是没有人点醒你就没有意识到。作为一个server,比如rest api server,你不应该有对于plugin的依赖,也就是说在编译期没有链接的动作,而应该完全依赖于动态加载。比如靠配置文件动态改变plugin的动 态库。这个当然就使用到了dl库,这个里面的dlopen相当于LoadLibrary的windows调用。
做了一个完全小孩子的实验,比如在一个库里定义抽象接口,在另一个库里定义实现,听上去好像com的模式。git clone http://www.staroceans.org/myprojects/dlllink/repo.git

二月二十日 当前只有等待等待


想要制作ubuntu10.04 usb live file system的启动盘,这 个也许是
你完全不需要直接启动笔记本来实验usb启动,直接使用qemu是太方便了。sudo qemu -hda /dev/sdh 但是我遇到一个错误:pci_add_option_rom: failed to find romfile "pxe-rtl8139.bin"于是这 里是解决方案

wget -O pxe-ne2k_pci.bin http://svn.savannah.gnu.org/viewvc/*checkout*/trunk/pc-bios/pxe-ne2k_pci.bin?root=qemu
wget -O pxe-rtl8139.bin http://svn.savannah.gnu.org/viewvc/*checkout*/trunk/pc-bios/pxe-rtl8139.bin?root=qemu
wget -O pxe-e1000.bin http://svn.savannah.gnu.org/viewvc/*checkout*/trunk/pc-bios/pxe-e1000.bin?root=qemu
sudo mv pxe*.bin /usr/share/qemu/


二月二十二日 当前只有等待等待


需要解开initrd.lz  lzma -dc -S .lz ../initrd.lz | cpio -imvd --no-absolute-filenames
这里介 绍的制作usb live cd的方法值得一试这 个说的更加具体,就是说用livecd来制作应该是比较靠谱的。


二月二十八日 当前只有等待等待


终 于把系统搞死了,只好重装,这个简直成了业余爱好了。有一些细节我需要注意,比如编译完内核之后要先安装modules然后才能制作Initrd这个当然 是很简单的道理,因为Initrd是一个临时的文件系统需要的那些kernel modules如果你还没有安装肯定就不行了。发现了一个可能是alsa的bug,比如在测试makefile里面通常判断空字符串的办法是用if ({$var+set} = set)这里就是一个bug,它始终不承认我把内核代码放在了/lib/modules/`uname -r`下面。

三月二日 当前只有等待等待


安装声卡的途径是最好使用3.14以后的内核,3.18后来出现了一些问题,好像是alsa编译的问题,这个是一开始我的理解,后来才感觉也许是编译器的 问题,4.4.3太老了static inline这样的定义不支持,所以,花了好多时间升级编译器到4.6.3,从svn里出来的4.6.4好像编译有问题。
显卡的安装主要是使用mesa,尝试一 下这个:lspci -vvnn | grep VGA发现我的显卡是Radeon HD 6450/7450/8450 / R5 230 OEM。

三月四日 当前只有等待等待


怎样和内核通信?使用PF_NETLINK创建socket,好像普通socket通信一样和内核交谈,这个是双向异步的。

三月七日 当前只有等待等待


任何社会成员成熟的标志就是深刻认识到,社会主义唯一擅长的是平均痛苦,资本主义唯一不擅长的是平均幸福。
看到怎样在shell 里面夹带binary,这个是一个典型的安装程序的做法,不过原文有错,看看代码就知道参数穿错了,你看出来了吗?

三月九日 当前只有等待等待


重新学习Linux From Scratch。 每次都有新体会,圣贤之书就要常温常习。昨天的一个任何人都知道也不屑于提及的东西就是Openssl里的md5的计算应该和很多标准样本实现有区别吧?我觉 得那个hardcoded的东西有很多的随机行,我用了libssl的md5。

三月二十日 当前只有等待等待


如果能够回答的了一下的问题, 你就算真正入门了:(我摘抄了这位仁兄的问题,粗读一下就明白他所说的a lot of effort是多少,他所说的understand most of the things是多少,他所说的a few questions的分量有多重,而这个兄弟在last two(2) days学的比我一两年的都多,佩服啊,在这里留下我对他的敬意,并准备在将来的学习实践工作中尝试回答这些问题。)
trent.josephsen, over the last 2 days, I have put in a lot of effort trying to understand so's. I have understood most of the things. I have a few questions, however.

1. Is it possible to append to /etc/ld.so.cache from "any random dir/user specified dir" by doing ldconfig? I tried doing ldconfig -n . , but that doesn't seem to work.

2. Which are the directories on which ldconfig operates ? Are they, a)everything mentioned in /etc/ld.so.conf.d/*.conf + b)/lib + c)/usr/lib ?

3. Don't you think all paths in the makefile should also be added to the list of dir's an "so" is searched in ? That would take away the overhead of adding paths where so's exist to LD_LIBRARY_PATH since these are already mentioned at build time. Why mention them again at runtime ? EDIT:probably, /etc/ld.so.conf should have a file like fromMakefile.conf

4. I copied an "so" to /usr/lib/i386-linux-gnu and was able to run the file, WITHOUT doing an ldconfig. Is that because
a) since it is under /usr/lib, it will run even if it doesn't figure in /etc/ld.so.cache OR
b) all directories under /etc/ld.so.conf.d/*.conf are manually searched for so's if it is not found in the cache?

5. I find the output of ldconfig lacking information about which "realname" it is currently running. I understand it will be something like libname.so.MAJOR.LATESTMINOR, but ldconfig doesn't tell me which one is the latest.

6. I don't understand why ldconfig should hold information of this nature.
libname.so.1 ==> /usr/lib/i386-linux-gnu/libname.so.1
According to me libname.so ==> /usr/lib/i386-linux-gnu/libname.so is sufficient.
I mean, the user would only enter something like -lname. so as long as information about libname.so is maintained, all others can be found through soft links.

EDIT : adding 3 more questions

7.Why do we mention the major number part also in the realname ? I mean it's confusing someone could make an so like, $gcc -shared -Wl,-soname,libname.so.33 -o libname.so.1.14 lib.o. I mean in the actual SONAME field, the soname would be libname.so.33, but someone looking at the libname.so.1.14 alone would think it is libname.so.1.

8.Don't you think finding the latest minor number which belongs to a particular major number should be done based on timestamp and not by text parsing the realname and finding out the number after the dot ?

9.Don't you think a file like libname.so.1(soname file) should NOT exist on disk.. Please check the attached picture. It is self explanatory as to how ldconfig creates a file named libname.so.1 (to help in it's processing ?) even if I have only 2 so's libname.so and libname.so.1.0. The fact that libname.so.1->libname.so.1.0 tells me what the purpose of the file is, and this will keep on getting updated as and when a new (minor number) version of the library is added. But surely, ldconfig doesn't need to show this file on disk, does it?

Please advise.
Thanks.


四月二日 当前只有等待等待


昨天改代码,有一个返回值的class被vampire设计成兼容以前的发回整数的形式,就是说有一个conversion operator,比如operator int(),而我在添加一个新的constructor带额外参数的时候,忘记它没有copy constructor,于是总是被先转换为整数使用conversion constructor。总之是小菜一碟只是费了我不少时间。

使用valgrind测试内存泄漏无法解决gsoap的问题。现在又遇到服务器端证书的问题,这个需要对于加密有更多的认识。制作LFS成了每天唯一能够作 的事情,nobrainer,而且可长可短。


四月十日 当前只有等待等待


前几天对于服务器证书算是有了一个认识,所谓证书就是一个通过用它自带的public key签名过的badge,上面写着它的名称等等,具体签名算法我要再去了解,但是对于用户来说就是是否信任它,如果你有一个你信任的证书,发现可以用它 的public key签名了别人的证书那当然是可信的,具体这里的“签名”是一个复杂的算法我还没有想明白原理。curl和其他的浏览器一样都有一个储藏证书的地方,这 个是curl编译时候的一个选项,rhel是在/etc/pki/tls/下面的一个.crt文件,把证书加到末尾就行,或者在curl命令行参数加上- cacert 文件名也行。通常如果你不想用certificate的话,你直接使用--insecure可以屏蔽这个。证书里面的cn或者common name通常是一个域名,这里curl的检查就是看是否和证书一致,所以,没办法我只能给每一个ip都制作一个证书。证书制作命令如下:
先生成一个key: openssl genrsa -out test-key.pem 1024
制作证书,注意cn必须和你的ip或者域名一致: openssl req -new -key test-key.pem -x509 -out test-cert.pem
从客户端获取服务器的证书: openssl s_client -connect 127.0.0.1:443
解读证书: openssl x509 -inform PEM -in certfile –text
永久性加入curl的证书库: openssl x509 -inform PEM -in server.cert -text >> /etc/pki/tls/certs/ca-bundle.crt

昨天在折腾hnas,它的每一个server都有一个和自己kernel通讯的机制,一个叫做ssc的命令行工具。
如何修改svn的comment:  http://stackoverflow.com/questions/304383/how-do-i-edit-a-log-message-that-i-already-committed-in-subversion

$svn propedit -r N --revprop svn:log URL
$svn propset -r N --revprop svn:log "new log message" URL

之前发现gsoap对于zlib有依赖是因为它有实现一个http的压缩协议,这个是可选的:如果你没有configure  –DWITH_GZIP就不需要使用zlib了。
对于libssh2也同样是有对zlib的依赖:配置的时候有选项--without-libz
学习自动化的linux from scratch发现你要是使用不 同的用户,你必须登录才能执行,同时发现我的编译的内核的版本号结尾有个"+"脚本不能解读,只好重编内核。


四月十四日 当前只有等待等待


重新温习以前的笔记,发现我现在的/etc/environment被gcc 修改过了,因为安装gcc4.6的时候不想覆盖原先的,所以,gcc把/usr/local/全部都放在了/usr前面在"$PATH"变量里。这个不知 道还有多少潜在的问题,因为我经常安装一些非官方的版本,这个。。。同时/sbin没有设在/etc/environment里,所以 setcap/getcap不能正常运行,也许我需要在.bashrc里面增加好些吧。

四月二十一日 当前只有等待等待


昨天闹了一个笑话,我说我不知道怎样链接一个动态库用它的全名,真是好笑,用全名难道不行?或者-l:fullnameofso?这个就是汗颜。对于 container的技术我连听说都没有就是另一个令人难看的话题,阅读lxc准备编译一下使用,当然在lfs里面大家通常使用的chroot就是他的一 个主要的核心。
昨天发现我的capability始终是空的,不明白怎么回事,看来要修改/etc/pam.d/下面的文件,但是哪一个?怎样改?把ext2fs 的文档编译了一下放在这里方便阅读。
debian的/etc/network/interface就是修改ip的地方,不像redhat你需要修改sysconfig的东西,同样的/etc /hostname就是hostname修改的地方。
你要是让你的script能够随着系统自动重启就要把它放在/etc/init.d/下面,同时要支持 start/stop/status/restart命令,最重要的是要用chkconfig来部署的话,要有一个tag,就是从开头都有# chkconfig  2345  20 80 这样子的一行,说的是runlevel和启动关闭的优先级。同时在reboot的时候stop命令会被呼叫。
sysctl -q -e -w net.ipv4.conf.eth1.promote_secondaries=1 
这里说的是sysctl是一个标准的命令, 它为非就是修改内核启动参数,他的参数实际上是一个路径/proc/sys/net/ipv4/conf/eth1/promote_secondaries 如果你cat这个文件发现它是1.
这里对于动 态库的解释实在是经典的,反复阅读都有新的理解。(手痒之下忍 不住行窃下载保存在这里)之前发现/etc/ld.so.d/libc.conf把/usr/local/lib当作首选是一个出乎我意料的,这 个导致我的“三观”都发生了变化,因为我自己安装的库的优先级是超过了系统的库。

四月三十日 当前只有等待等待


终于无法抵御诱惑安装了ubuntu14.04,感觉很慢,于是转而求其次安装了12.04快很多,比较接近10.04我还是挺满意的。制作启动U盘都是 没有错的,之所以我的电脑无法使用removeable device来启动的原因是bios把usb mass storage的模拟方式作为自动的话,那就是scsi的设备和硬盘无异,我必须手动设定为fdd,就是模拟软盘。我的声卡依旧有这样那样的问题,但是最 根本的是rhymbox无法停下来所以即便我改变了声卡的配置也无法反映出来。
这里是一行制作certificate: openssl req -new -subj /CN=172.17.57.75/ -key MetroServerAPI_key.pem  -x509 -out MetroServerAPI_cert.pem
检查语句:openssl x509 -in MetroServerAPI_certt.pem -text | grep "Issuer: CN="

五月一日 当前只有等待等待


必须要升级java1.7才能运行eclipse-luna,
sudo apt-get update
sudo apt-get install openjdk-7-jdk
昨天看代码才看到poco里面防止crash的方法是把signal拦截转成c++的exception,这个本来是基本的东西,但是我看不懂 sigsetjump的用途,注释里说是要为了获取线程的stack environment存在一个vector里,用意是什么呢?

五月三日 当前只有等待等待


这里是官方的关于cmake的find_package的解释,很好的。

五月十六日 当前只有等待等待


在编译的时候发现了一个问题,用到了很多的pthread的调用,比如同步的实现是用pthread_mutex_t,可是ldd发现动态库没有libpthread的依赖,发文去问同事才找到原因,原来是libc.so.6有一些pthread的实现。
objdump -t /lib64/libc.so.6 | grep pthread_mutex_lock
000000361d2f8170 g     F .text  0000000000000026              pthread_mutex_lock
关于kompozer的安装,ubuntu14.04可以使用ubuntu12.04的库来安装。制作launch item的菜单需先制作在~/.local/share/applications/myapp.desktop,icon可以在 /usr/share/pixmap里用.xpm.
对于vcmi非常的钦佩,有人有毅力把windows的游戏逆向制作出来,当然图形界面只是第一步,最难的是游戏的ai部分,这个非常的不容易。加油!
上班开始看poco的文档来帮助理解代码,感觉这个非常的强大,获益匪浅。编译poco注意一定不能在parent directory存在symbolic link这个官网说的很清楚,可是我还是没有意识到。否则总是有Current working directory not under $PROJECT_BASE. Stop.的错误。
使用git复制一个tag/branch,git clone --branch poco-1.47 /BigDisk/poco。

五月十七日 当前只有等待等待


在配置poco的时候总是报一个莫名其妙的错误configure.xxx bad substitution这里xxx是某一个行号,我的参数是及其普通的以前从没有发现,google了可是因为不明所以然,居然看见了答案也不明白,其 实就是configure的shell使用的是/bin/sh这里不一定就是bash,这就是问题。其次,poco-1.47编译静态库始终有问题。


五月十八日 当前只有等待等待

静态库本身有依赖性,因此只有这样的顺序才行:

libPocoDataSQLite.a
libPocoData.a
libPocoCrypto.a
libPocoNetSSL.a
libPocoNet.a
libPocoUtil.a
libPocoXML.a
libPocoFoundation.a
pthread
dl

五月十九日 当前只有等待等待

<rush> 我看了好几遍,真是令人热血沸腾。其中的很多对白是那么的让人回味无穷: Niki Lauda说: Happiness is the enemy because it weakens you. It puts doubts in your mind and suddenly you have something to lose. 他妻子回答说:If you feel happiness is your enemy, then you have already lost. 影片的另一个主人公是出了名的大帅哥,就是雷神,其实他才是主角。

Fame

Fame makes a man take things over
Fame lets him lose, hard to swallow
Fame puts you there where things are hollow
Fame

Fame, it's not your brain, it's just the flame
That burns your change to keep you insane
Fame

Fame, what you like is in the limo
Fame, what you get is no tomorrow
Fame, what you need you have to borrow
Fame

Fame, "Nein! It's mine!" is just his line
To bind your time, it drives you to crime
Fame

Could it be the best, could it be?
Really be, really babe?
Could it be my babe, could it, babe?
Could it, babe? Could it, babe?

Is it any wonder, I reject you first?
Fame, fame, fame
Is it any wonder you are too cool to fool?
Fame

Fame, bully for you, chilly for me
Got to get a rain check on pain

Fame

Fame, fame, fame, fame, fame
Fame, fame, fame, fame, fame
Fame, fame, fame, fame, fame
Fame, fame, fame, fame, fame
Fame, fame, fame

Fame, what's your name?

Feeling so gay
Feeling gay


五月二十八日 当前只有等待等待

最近fix的两个 bug都是多线程下的内存corruption的问题,以前对于这个只有一个模糊的认识,但是从来没有很深切的体会,对于指针越界比较容易理解,那个纯粹 的是代码的错误,而现在的情况是多线程的race condition加上release memory的问题, 比如,一个线程释放并重新分配一个全局变量而未保护的情况,出现的种种的稀奇古怪的现象通常都是无法解释的。远程gdb进程查看线程发现poco线程池的 所有线程都被mutex blocking了,print那个pthread_mutex发现他的Owner的LWP,也就是线程id不存在,这个说明拥有者未释放Mutiex就 死了,那个mutex是包装在一个wrapper class里在constructor里lock,在destructor里unlock,这个都是再寻常不过的了,除非遇到以前的nested exception throw才会出现destructor没有能够释放mutex的问题,当时无法找到原因项目要完工只能triage使用急救包用poco的一个把signal转成exception的宏来try catch来释放mutex,poco的代码确实不错,原理也不是非常复杂也是linux常用的办法,就是用signal handler注册关注的signal,然后使用longjump跳转回想要抛出exception的地方,不过longjump的形式使用的是自动 reset被handle过的signalhandler,不过poco的代码我还是看了一两天配合例子才理解的,因为对于longjump保存 stack还是不太理解,仅仅是stack指针真的能够保证stack没有破坏吗?

try
{
     poco_throw_on_signal;
     ...
}
catch (Poco::SignalException&)
{
    ...
}

release编译下的全局变量通常在gdb里打印不一定有正确的数值。

最终这个signal转exception的权宜之计是不能根本解决问题的,因为我们能够捕捉到segmental violation的signal本身就说明代码错的非常厉害,catch这个转变的exception仅仅保住了本来crash的线程,防止了 mutex不释放造成的死锁,但是源头是什么?最后找到的原因是一个全局变量在被每个线程都创建与释放过程未保护导致了race condition,在某个线程获得了全局变量的指针后被其他线程释放从而内存成为自由区被别人任意写入导致的混乱,这个问题上个月已经遇到过类似的一 次,不过当时是因为interface指针没有引用计数,我必须要等待所有使用线程都结束以后才能释放。两者都是多线程环境下内存corruption只 不过后者并不是真的有race condition,前者才是而已。

现在开始使用ubuntu 14.04主要是主流的软件都在支持,编译开源容易。wesnoth的ai的训练场值得学习。命令是./wesnoth-debug -t ai_arena_small -dtry


五月三十一日 当前只有等待等待

以前一直有一个错误 的认识就是i++之类的数字操作应该是一个指令所以是atomic的,其实这个不是正确的取决于编译器和架构,所以要用专门的atomic_inc之类的 来保障。带着疑问看poco::sharedPtr发现他的refCounter是一个atomic的所以是threadsafe的。poco的文件在这里.  我下载保存在这里


六月三十日 当前只有等待等待

Makefile里 的一个小常识,就是?=和=或者:=的区别,前者是当未赋值才赋值,所以,可以作为用环境变量来控制的理想人选。比如,需要作交叉编译的时候,有些变量需 要改变,可以不修改makefile来操作。以前我对于debug/release两种编译目标使用环境变量来修改总是不成功,现在明白了?=的妙处。

另一个小小的问题是关于destructor的,我们的基类是一个抽象类只定义了方法,忘记设定destructor为virtual,只是在它的 子类设定destructor为virtual,这样结果derived class不能自动调用它的destructor,所以这个virtual一定要在最早的祖先类来声明。现在debug deadlock确实还是有些心得,deadlock比race condition容易debug,只要debug编译,info thread,然后thread #到每个thread,取bt看看是否卡在我定义的mutex处,up/down到相应的frame然后print mutex可以看到它的owner的thread id,就八九不离十了。


七月二日 当前只有等待等待

class Foo{};  Foo f = Foo(); Foo d=f; d=f;这里究竟有那些member function被调用了呢?Foo f=Foo();这里只有constructor,这个是我犯的错误,我本来以为临时变量会和copy constructor一样,所以Foo d=f;才是的。

遇到了一个Multiple inheritance的问题,而且还是所谓的diamond的问题。

class Base{public: void init_storage()=0; void base_init(){init_storage();}};

class FileBase:public Base{public: void init_storage(){cout<<"file init"<<endl;}};

class BlockBase:public Base{public: void init_storage(){cout<<"block init"<<endl;}};

class Hybrid:public FileBase, BlockBase{public: void exec(){base_init();}};   //////=========>>Here is ambiguious place, You don't know which init_storage it should call.

不过我们需要的是hybrid,就是说我需要两个继承类的init_storage,于是FileBase::init_storage();BlockBase::init_storage();这样子就可以了。

我重新改写了makefile的结构,依据这样一个架构:

0. target 1.srcs 2.objs 3. paths 4.cc_flags 5. ld_flags 6. obj_rules 7. target_rules 8. make_phony_target_rules

其中obj_rules可以非常的通用化

%.o: ${SRC_PATH}/%.cpp

    CC_CMD -c ${CC_FLAGS} %< -o %@


七月九日 当前只有等待等待

上个月大病一场,花了海量的医药费。

在链接动态库时候,担心提供者不给symlink,比如libssl.so.1.0.0却不给libssl.so指向,于是我把通常的-L$ {SSL_LIB_PATH} -lssl改写成了-l:${SSL_LIB_PATH}/libssl.so.1.0.0这个做法在后来的ldd发现居然有个库是使用绝对路径,而不是 其他那样的库的名字,仿佛使用了类似r-path一样,迷惑了一下才发现那个绝对路径的是间接的库,比如我们的应用依赖关系如下webserver== >libHiStor.so==>libthird.so那么链接之后libthird.so就是全路经,而libHiStor.so还是正 常的libHiStor.so.SONAME

以上似乎是不对的,结论是永远永远不要使用动态库的绝对路径来链接。因为动态库链接另一个动态库如果使用绝对路径如同r-path一样是非常要命的。

另一个反复忘记的就是不论使用linux gcc还是cross gcc都是一样的,如果你要编译-shared都要-fPIC每一个obj文件,而不是仅仅.so的时候。


七月十日 当前只有等待等待

你的应用比如 webserver链接了一个dll1而这个dll1又需要一个dll2,那么在dll1里你是否应当看到调用dll2的unk的symbol呢?我本来 以为这个压根不是问题,可是没找到。用nm,objdump,readelf都是一样的,自己做了一个最普通的c的函数调用自然是有的,可是为什么工作中 的没有呢?找到了部分原因。在dll1里使用dll2的是一个类,创建是使用工厂模式,所以返回的是指针,方法是virtual的member function。首先,对于只是返回指针而分配内存实现在dll2的来说,dll1压根不用关心他的constructor,甚至如果不是调用他的方法 连名字都不许要,当然不用方法创建做什么呢?不过对于virtual的方法通常都是在virtual table里的函数指针,调用的时候是偏移量,只需要类的type指向他的vtable就行了,当然方法名字还是需要在编译的时候有类的定义以便获得偏移 量。说到这里我突然想到了为什么我们的服务在用户调用a方法时候b方法被调用而且导致crash了,应该是代码附带的头文件和编译的dll不匹配。在编译 dll1的时候需要的仅仅是dll2的头文件以便生成调用方法的类的偏移,在runtime的时候压根不是使用函数名字来动态resolve的,在编译的 时候只是解决了一个基类的vtable的指针,在运行期解决实际类型的type的id之类的rtti以便调用合适的vtable的全局变量,而偏移量是在 编译期已经解决了,所以在dll1里是不会出现dll2的方法的symbol的。需要学习的是什么是weak symbol,weak object symbol,等等。这个可不是那么trivial的概念,看看再说吧。


七月二十一日 当前只有等待等待

标准的 singlton的创建方法之一是所谓的double lock check(DLC)其中的一个细节是创建的时候如果是传入指针参数有可能对象还未完全创建的时候内存已经分配并赋值给指针了从而导致后续的创建 singlton请求误用非法的指针。这个在wiki的解说里举例说是有些OS有些编译器的行为,可是从一个实际项目的角度来看这个是有现实意义的,比如 通常singlton都不是什么trivial的对象内存分配而已,而是相当复杂的过程,比如我们使用一个factory类来掩盖不同系统平台的创建细 节,那么在这个过程里其实并没有人明确保证传入的指针只应当在最后一刻才赋值,虽然这个是程序眼的道德底线,可是,你没有这么作也没有人能够怪你。而且这 个过程牵扯到subsystem的初始化时间是不可忽略的,相当的慢。比如如下红色部分通常都是疏忽的地方,因为factory的create方法天知道 是什么时候给传入参数赋值的,安全起见是要小心的。以前我也常常对这些不以为然,以为小题大做,直到吃了苦头才小心谨慎起来。最刻骨铭心的是一个全局变量 被多线程使用,结果这个空有release接口的指针并无计数功能,也就是说你一旦呼叫其release接口他就简单的释放自己的内存delete this;结果导致其他正在是有的线程遇到一系列稀奇古怪的问题,比如这个对象有一个mutex,调试gdb发现其数据非常诡异,它还有其他一些子系统的 数据也变得莫名其妙,其原因就是内存破坏,因为在他是release了自己的内存允许其他人使用其释放的内存,可是还在运行的握有其指针的线程使用的就是 垃圾了。内存corruption的bug非常的不容易解决因为现象非常莫名其妙不可重现,常常会误导你的思路。

class Singlton
{
private:
Singlton(){cout << " a very long procedure" << endl;}
static Singlton* m_pSinglton;
public:
static Singlton* createSinglton();
};
Singlton* Singlton::m_pSinglton = NULL;
Singlton* Singlton::createSinglton()
{
    if (m_pSinglton == NULL)
    {
        LOCK myLock(g_mutex);
        if (m_pSinglton == NULL)
        {
            Singlton* pTmp = NULL;
            if (Factory::create(&pTmp))
            {
                m_pSinglton = pTmp;
            }
        }
    }
}

关于gsoap的内存泄漏问题,在资讯其技术支持后意识到我把proxy和普通c style的函数混用了,而且其原则是init一定要在soap_new之类之后调用。而set_local_namespace这个东西在proxy里 已经有了不需要你自己去做了。使用valgrind可以很轻易的发现这些错误。


七月二十二日 当前只有等待等待

使用vlc快速验证 webcam: vlc v4l2:///dev/video0 至于麦克风使用audacity很好。同时使用aplay 和arecord可以简单验证录音播放功能。昨天在svn branch里使用svn update -r <release number>不成,google才明白那个版本号是在trunk里。每天都有进步阿。使用valgrind验证我的改动居然是0内存泄漏, gsoap的proxy的constructor内部会调用init函数,包括set_local_name_space所以,我的内存泄漏都是源于这两 个方面,即我使用proxy但是代码还是不使用proxy的方式,重复了,所以,才有内存的泄漏。


七月二十九日 当前只有等待等待

收集论文,是rsync的基础算法的原创者吧。看不懂就看前言,我的论文阅读就仅仅限于abastract的阅读


七月三十一日 当前只有等待等待

dynamic loading的flag即便是RTLD_LAZY也仅仅是针对函数的,对于变量是要立刻解决的,而假如你要load的dll1又depend another dll2的定义的一个全局变量A的时候要小心的了,假如A是定义未__attributes__((visibility ("hidden"))) int A的话,你就会遇到undefined symbol 的错误了。

八月二日 当前只有等待等待

几乎天天都在看风小筝的yy直播。yy的视频直播是最棒的,但是它的神曲播放估计资源不够非常的慢,这个也是可以理解的,我的猜测是云存储方案的问题,那么我就下载到亚马逊来存储播放吧。
黄梅戏爱情主演青狐媚帝都姑娘爱情郎半壶沙蜀绣漂洋过海来看你君妾别恋人心不再联系不怕不怕太多同桌的你梦魇致青春爱妃入戏太深我不是新娘白骨哀酒馆小调卷珠帘终于等到你夜光匆匆那年风吹麦浪着魔忘情谷二缺一

这里还有一个小虾米的搞笑三轮车坏姐姐。文er的中气非常足,梦回当年古战场

简单的看了一下poco的httpRequest类,实际是很简单的,因为uri指的就是/开始的部分,host:port不用说,不过输出的时候 有可能加[]在host上,如果其中包含:的话,不知道这个情况是什么意思。至于我一直想要找的serialization的方法也找到了,他的祖先类 httpmessage/httpheader类都有实现,read/write,所以这个是很直白的de/serialization。当然其中的 fields是用multi-map实现的,要小心重名,是否大小写区别呢?这个要证实。


八月十四日 当前只有等待等待

ldd是个脚本,他呼叫的是一个动态库,ld.so,没有想到吧!想看看怎么回事,编译glibc,只有最新版的2.22可以编译,ubuntu所用的eglibc2.19编不过。

八月十九日 当前只有等待等待

ld.so是一个精微奥妙的东西,不知道有多少人感兴趣看它如何腾挪,年轻的时候曾经看过两天PE文件格式,似通非通的囫囵吞枣用来卖弄,如今开始了解a.out和elf的区别,这里的水很深阿。
之前作了一个Unittest的测试环境,模拟server调用一个handler的函数的过程,我们的poco server首先读配置文件,找到url对应的module和class method然后dynamic load library搜寻其中的symbol运行接口的几个函数,其中setContentLength是设定poco的HTTPServerRequest的 stream的地方,我在这里使用了一个mock class,继承了它的祖先HTTPRequest类然后实现了一个file stream的阅读过程就行了。其后就是一系列的使得它易于使用的过程了,无非是定义一些函数指针数组,作成回调函数代不同的参数使用不同的serial number的设备来测试而已。
经常扫描pdf文件,要合成一个大的,使用pdftk input-list-pdfs cat output output.pdf

八月二十四日 当前只有等待等待

binutils是一个非常值得任何程序员浏览的部分,对于系统感兴趣的人的第一急所:binutils.pdf

八月二十六日 当前只有等待等待

有时候最初的好印象 会误导你很久,我一直对于midnight commander深信不疑,结果导致我好几天都陷在迷惑中,打开elf文件,或者.o,.a,.so之类的第一件事肯定是读magic number,但是在mc里给你看的第一行是文件名,还是全路经,我不经惊讶莫名,这个是颠覆的观念,你居然要把文件路径写在文件起始行,这个是什么样的 令人震惊,我对此百思不得其解,因为readelf,objdump之类的代码总是在读magic number和!<arch>\n即便我用gdb跟踪也是如此,难道??排除了一切的可能最后的唯一的不可能就变成了答案:mc不知道为何把 文件路径夹在了file view的起始行!为了证实用head -n 1 <filename>就可以了,同时决定以后选用ghex之类的。

八月二十八日 当前只有等待等待

看了几天唯一的长进 就是明白了为什么会有objdump和readelf两个功能相似的东东,因为objdump是依赖于bfd的,这个和nm是一样的,而bfd并不是一个 native的东西,意思是它的目标原本是一个通用的兼容各种格式比如coff,pe,a.out等等而不是仅仅基于elf的library,因此作为一 个从原生的elf代码衍生出的readelf就很有必要可以作为一个互相印证的工具。这个是我读注释的来的,我以前曾经批判过我的同事是不学无术的程序注 释阅读员因为那位大爷除了能够读懂代码的注释基本看不懂代码,难道今天我也沦落至此?

关于eclipse的老问题,就是使用gcc builtin 的设置。You could also try use "CDT GCC Built-in Compiler Settings". Go to the project properties > C/C++ General > Preprocessor Include Path > Providers tab then check "CDT GCC Built-in Compiler Settings" if it is not.


八月二十九日 当前只有等待等待

误闯“白虎堂”来到了一个从未到过的地方。 为什么会到这个地方?说来话长,我想gdb无非就是使用SIGSTOP之类的向cpu发信号另外向OS要当前的proc的信息比如pc,另一方面得到 text也就是code的地址就需要类似addr2line的功能来定位source code的file:line对子,于是我就gdb addr2line看看怎么实现的,其实也简单因为有了bfd一切都是一个简单的应用,binutils的几乎所有功能都离不开bfd,而根据我读代码注 释的心得bfd的正式的缩写是big fucking deal而不是后来杜撰的所谓的binary format data,这个据说是当时的大牛作者在讨论这个项目的时候另一个大牛的评论,平心而论这个是所有程序员都会望而生畏的,尤其bfd号称是要兼容多种格式 的,怎么兼容我连边都不理解。于是跟踪到了一个__libc_start_main就无意中google了一下才误闯了白虎阶堂,此处是linux的核心 所在,就是说所有的linux distribution的libc的interface,是不是kernel去调用libc的接口?应该是 ,这个就是所谓的lsb的标准,我这几天一直在疑惑一个进程是如何被载入的,动态库加载的过程是怎样的,应该要从这里入手才对吧?这个函数看看prototype就能猜测个十之八九,好几个回调和main的argc,argv.

这里是关于dynamic调用的格式,这里就比较好理解了,无非就是一个_DYNAMIC的list里面是一系列的d_tag和地址的对子,对于dynamic object的执行有了一个框架的定义。所以,重复一下,dynamic library必须是有segment的而且要在program_header有一个PT_DYNAMIC的element,在segment里有这个_DYNAMIC的list。(我把人家的话抄了一下改了一下顺序说了一遍,这个是典型的plagerism)

见到了听闻许久的隐者system V ABI,这个以前就想读一下,目前只关心object file的格式,在magic number后要有这个
Position                                                                             Value
e_ident[EI_CLASS]                                                      ELFCLASS64
e_ident[EI_DATA]                                                         ELFDATA2LSB

我抄下这个警句:Processor identification resides in the ELF headers e_machine member and must have the value EM_X86_64(从注释中发现它的值是62)(找时间看一下file的命令的实现就知道了。)
从白虎阶堂的军用地图看到了一大堆的文献,比较粗浅的是fhs(fileystem hierarchy standard)
什么时候弄一个cronjob来定期更新呢?


九月二日 当前只有等待等待

下载了Linux的标准,很有用的东西

九月三日 当前只有等待等待

昨晚看了大阅兵,在 直播的过程特地转台去看美国主流媒体是否有报道,可惜不要说画面,连只字片语都没有,仿佛根本没发生,转念一想,其实也是,目前大部分的所谓新式装备说白 了都是美国十几年甚至几十年前就装备的了,比前苏联落后还要多的,在美国人眼里的确不值一提。美国人压根没有关心美国以外的兴趣,外面的世界除了战乱饥荒 还有什么,美国国内的和平繁荣压根儿不需要外界的干扰是最好的。对于阅兵我个人唯一感兴趣的是带队的军长师长身先士卒是一个大的改观,比较像是有些改变, 有了一点军人的样子。解放军多年不打仗已经生锈了。
把binutils下的神器的帮助文档存放于此:bintuils, ld, libiberty, bfd, gprof, gas.

九月五日 当前只有等待等待

前两天在公司赌气就 去试图追踪一个日本的命令行工具运行情况,使用strace发现它使用unix domain socket和主程序通讯,然后查看lsof那个socket文件发现了正在监听的主程序,然后再次使用strace那个主程序发现它接受的命令并使用 scsi命令转发给后台存储,所以现在如果要破解命令就是要去要救scsi命令格式了,这个我目前还没有时间。这两天在拷贝粘帖bdf的使用代码来学习, nm是一个最好的范例,为了明白怎么编译链接,在binutils下make nm-new之类的可以看到底怎么链接libbdf.a,此外还需要一个libiberty.a这个里面都是一些系统可能没有的工具。不过我想走另一条路 就是使用readelf的路径,因为它是完全原生的二进制文件解读,当然bdf是任何架构平台的通用,不过我讨厌复杂。

九月七日 当前只有等待等待

去优山美地玩了一天。这里有一些关于ld.so的论述还 是有些价值的。其中我感兴趣的是有关program interpreter的表述,这里说明了什么呢?就是说OS必须无条件的加载这个文件镜像然后把控制权交给它。多么好啊,自己如果能够加载自己然后运 行。总之,这个就是我每次strace看到第一个syscall都是这些步骤的原因,每次都是由glibc的mmap去把这个大侠请出山,然后才是相应的 各个需要的library的加载,包括动态库的地址修改部分?这里是elf的规范

九月十四日 当前只有等待等待

找到了一个好东西,就是在binutils下的一个elfcpp, 这个是一个非常简单医用的c++的elf reader/writer的实现,这个正是我需要的,简单易用,而且模板的效率非常的高,我仿照说明实现了一个简单的配套就是要实现一个接口View来 掩盖文件读写的细节,我只关心读,就很简单了,不过我发现似乎这个是一个作者不值一提的小东西,所以没有用心再培育,属于一个临时的工具,那么我正好结果 来大改一下,删除了我不可能用到的写的部分准备把很多代码改掉。

九月十五日 当前只有等待等待

在文件列表的map基础上增加了vector列表,本来是想保留文件目录结构的。代码的改动实在是trivial

九月十七日 当前只有等待等待

找到一个很有用的文档, 是关于32/64位架构的历史资料了吧?前几天和vampire斗气,尝试跟踪一个日本提供的命令行工具,strace发现它打开unix domain socket和它的manager通讯,本来准备截听它发的讯息,后来发现还不如直接监听它的manager,通过lsof显示它的manager的进程 号码,然后同样使用strace监听它的manager的syscall的调用,发现使用scsi命令传指令给后台存储,这里我缺乏scsi命令的基础停 在这里,不过原则上我能够破解scsi命令则完全可以跳过这个命令行工具直接使用scsi命令和存储设备通讯。

使用readelf --debug-dump=decodedline ./myElf看到了debug的信息,大开眼界,感觉真是孤陋寡闻。


九月十八日 当前只有等待等待

使用linux32/linux64可以改变32/64位的环境,这个还真有些神奇。这个被成为personality tool:

Architecture
Personality Tool
AMD64 
linux32
PowerPC64 powerpc32
Sparc64 sparc32
zSeries s390
这里是一个非常帮的关于kernel boot的东东入口第一第二第三第四第五

下面的例子是怎样剥离debug信息在另外的文件:
$ gcc -g -shared -o libtest.so libtest.c
$ objcopy --only-keep-debug libtest.so libtest.debug
$ objcopy --add-gnu-debuglink=libtest.debug libtest.so
$ objdump -s -j .gnu_debuglink libtest.so

九月二十七日 当前只有等待等待


64位elf的文档应该不是很需要,uclibc直接是自动生成的?我也下载了,和HP大同小异?这里是Linux Standard Base Core Specification 3.1 uclibc的网站有很多文档

十月二日 当前只有等待等待


把那个巨型文件改成了link-list的款式.
增加curl-7.35.0因为我刚才意识到我的project实际上是要用到libcurl的。

十月四日 当前只有等待等待


关于streambuf的有趣的话题,这里是gnu的权威的帮助文档.

十月六日 当前只有等待等待


把程序改造了一下,现在有一个文件树结构网页了。修改的程序在这里

十月八日 当前只有等待等待

美国众议院议长选举流产了,候选人麦卡锡临阵退缩让我大感意外,随后CNN的现场采访让我明白其实是理所当然,之前贝纳辞去议长一职如果我还以为是因为教皇来访的演说感动他就说明我就是华盛顿政治的局外人,因为谁愿意当这个倒霉的位置?马上就是又一轮的举债上限的斗争了。

十月十三日 当前只有等待等待

在一个迷茫的早上来到这里,观看大侠惊心动魄的战斗片段,其实除了前面的绕过gdb/ptrace的部分,后面的汇编还原c代码部分我肯不太懂。大侠的总结是要学习汇编,让我神往了一会儿,看来我也要。。。

十月二十五日 当前只有等待等待

nfc的简介。netlink是我应该尽快熟悉的,BA实际就是用这个和内核通讯的,简单的原理在这里。

十月二十八日 当前只有等待等待

nfc的编译指南。ext2 filesystem指南,来自GNU。e2fsprogs. introduction of ext2 filesystenm

十一月十日 当前只有等待等待

开车去洛杉矶三天 车技有很大进步。关于libstdc++的基础你知道多少?使用libbfd的demangle是一个太复杂的路径,这里是使用rtti配合c++的abi的函数获得的例子,但是从nm/readelf之类得到的名称和rtti的名字是有一个前缀的区别的,那个_ZTI的前缀怎么去掉呢?好像对于vtable的前缀是_ZTV。这些都是问题。如何减少vector的capacity,这个是经典的答案

十一月十二日 当前只有等待等待

我想了一晚上一直以为这个是近乎不可能的任务,早上看Poco-1.5.4的代码才豁然开朗,原来有这个办法!
故事的起因是这样子的,openssl是一个广泛被应用的库,我们的后端和一个soap service通讯使用gSoap工具产生的客户端使用openssl实现https的协议,在初始化openssl的时候都会设定自己的回调函数来设立 同步机制,比如CRYPTO_set_dynlock_create_callback, CRYPTO_set_dynlock_lock_callback,CRYPTO_set_locking_callback等等,所谓的回调无非就是 设定自己的lock/mutex之类的,通常大家线程都是用pthread,那么就是直接使用pthread_mutex来实现这些回调。同样的在 Poco里面也有这样的设置因为如果你要用Poco创建一个web service的话,那么我们的REST server在使用Poco作web 服务的时候要初始化openssl,同事后端作为其他子系统的客户端的gSoap的客户端也要初始化openssl而且他们的回调函数实现还不一样,混用 的问题是无法想象的。我看到的crash我十分怀疑这个是root cause。怎么解决呢?这个近乎非常非常复杂,要改变两个系统的源码,让他们使用彼此定制的回调来保证openssl的线程安全?看上去是一个很大的工 作。绝非一两天就能解决的,早上看到Poco-1.5.4的初始化代码与1.4.7的不同才意识到需要调用 CRYPTO_get_locking_callback。不过我看了这里又有些疑惑,似乎openssl已经是线程安全的了,无须自己在作额外的,至少windows和什么平台可以调用系统默认的线程函数。

十一月二十五日 当前只有等待等待

POD代表plain old data。 就是可以memcpy的数据,阅读ABI是一个程序员应该必由之路?其实,我自以为学了十年的c++但是一些基本的问题都回答不上来,比如一个empty class的size是多少呢?你以为是0吗?实际上ABI有规定,在多数情况下是1,那么constructor/destructor有多少种呢?说来惭愧我竟然没听说过 看了解释联想昨天的一个基本问题就会有所领悟,比如在auto或者static/global的内存中分配的object的destructor是会被呼 叫的,那么new出来的在heap的object在程序结束的时候会随着进程解体被呼叫吗?显然不会。这个问题多么的显而易见啊。昨天S居然认为他使用同 样的接口实现的singleton在多个library会分配同样的地址,这个是在是令人无语。地址要么在编译期解决要么在运行期解决,你的函数代码被分 享编译在三个不同的dll里被同一个进程dynamic loading到内存那么你的代码是否是同一个symbol?
使用gSoap产生了所谓的c++的类来实现soap的客户端,但是现在你能否添加任意的customs http header呢?从c++的角度来看我作为使用者就是用gsoap生成的request/response类,里面的成员变量都是自动生成的,我怎么添加 任意定义的http header呢?大牛给了我一个post hook的例子代码,在gSoap的引擎里有很多回调函数,你可以在一个里面去添加。牛人其实很多的,没有做不到,只有想不到,其实也不难,只是你没有去 看代码,去想。曾经花了一个早上看Poco怎样bring down一个http server为了回答我们的REST server是否是grace shutdown的问题,答案是肯定的,做的工作真不少,从改变线程whileloop的停止标志开始等待工作线程结束,包括发信号给socket listening的线程调用syscall的shutdown socket以便让正在连接的tcp session终止,到把当前在idle queue里等待的job唤醒以便完成,这个过程相当的复杂,真的不容易。

十一月二十六日 当前只有等待等待

mangled name是一个经常遇到的问题:
<builtin-type> ::= v    # void
         ::= w    # wchar_t
         ::= b    # bool
         ::= c    # char
         ::= a    # signed char
         ::= h    # unsigned char
         ::= s    # short
         ::= t    # unsigned short
         ::= i    # int
         ::= j    # unsigned int
         ::= l    # long
         ::= m    # unsigned long
         ::= x    # long long, __int64
         ::= y    # unsigned long long, __int64
         ::= n    # __int128
         ::= o    # unsigned __int128
         ::= f    # float
         ::= d    # double
         ::= e    # long double, __float80
         ::= g    # __float128
         ::= z    # ellipsis
                 ::= Dd # IEEE 754r decimal floating point (64 bits)
                 ::= De # IEEE 754r decimal floating point (128 bits)
                 ::= Df # IEEE 754r decimal floating point (32 bits)
                 ::= Dh # IEEE 754r half-precision floating point (16 bits)
                 ::= Di # char32_t
                 ::= Ds # char16_t
                 ::= Da # auto
                 ::= Dc # decltype(auto)
                 ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
         ::= u <source-name>    # vendor extended type

十二月一日 当前只有等待等待

关于好多年前在 bloomburg的面试有一个问题是关于内存动态分配如何记录分配的内存大小的,当时没有这种意识,其实这个是在一定程度上abi有规定,或者是一个约 定成俗的办法,都是一个小cookie来记录大小在倒退一个size_t的地址,所以分配的时候也会多至少一个size_t的内存,这里的规定是关于更加复杂的对象数组的情况,但是基本的情况当然也可以这么实现。现在才意识到他们当初也许都在实现自己的mem manager之类的,这个是大多数人都会去做的。保存所谓的generic ABI的文档,这个很有用,因为是最最基本的linux的入门的东西,可以称之为宝典。c++本身的ABI下载的是一个Html文件,是在这个基础之上的。这个网站有下载。各个处理器相关部分,这个是386部 分。其中一些关于plt的论述很微妙,我目前对于S的做法依旧表示怀疑,他定义了一些函数把它放在executable和dynamic library的共同的代码中,那么同样的函数在exe和dll中各有一份是不是在个字的plt都有?那么这个解决的过程似乎是不一样的吧?我还没有找到 答案。
linux foundation organizaition是比较完整的网站。下载了AMD的x86-64的架构部分。
个帖子是很好的例子。

十二月三日 当前只有等待等待

找到一本老书感谢作者公开Jonh Levine.为人类文明进步所做的贡献。四个c library的比较,有机会尝试再说。这些人的信念是小到不能再小。
In protocol design, perfection has been reached not when there is nothing left to add,
but when there is nothing left to take away.
--RFC1925
挖掘古迹。这些人是真正的精英,绝非小孩子之类的玩意。最小的c编译器?最小的bootloader直接编译内核然后启动

十二月十六日 当前只有等待等待

昨天折腾了一个上午 才搞明白了一件事,关于CC,在我们的Makefile里原本是hardcoded CC=g++我因为需要进行交叉编译需要在不修改makefile的情况下来设定CC,所以,就把CC?=g++期望说我能在调用make之前通过设定环 境变量来改变编译器设定。结果发现原本的project编译出错了,在链接的时候c++的部分通通是undefined,再一看编译命令原本.cpp的代 码居然通通使用cc命令来编译,linux里cc默认设定成了gcc的symlink,我没有主动设定CC=cc那么究竟是谁做的呢?在同事的帮助下 debug好久才发现是gnumake的默认设定,gnumake除非使用非默认变量才能去除这个设置。其实这些都是常识,在微软visual studio里会自动根据后缀名.c/.cpp来选择c还是c++的编译器,linux里你要用规则来选择。通常用g++能够编译正规的代码,就是 vampire那个小子的代码。当然使用c编译器来编译c++代码只能把不认识的c++部分当作undefined,这个只有在linking的时候才能 发现。好朴素阿。

十二月二十二日 当前只有等待等待

昨天这篇文章也许误导了我??关于动态库其实还有很多的未知,做了一个小实验结果似乎和我想的不一样

十二月二十三日 当前只有等待等待

从此又多了一项有用的debug的途径,通过设定LD_DEBUG可以看到linker的搜索方式了。不过LD_DEBUG_OUTPUT设定还是不能用,我已经发现不像是secure mode可是还是不行。。。

十二月二十七日 当前只有等待等待

为了支持盗版光碟的事业,使用handbrake,结果不能识别starwars的dvd,于是想自己编译源码看看。这个过程中需要编译libgudev,遇到一个奇怪的现象WARNING: 'aclocal-1.13' is missing on your system.这个是很奇怪的,因为我根本不需要安装aclocal,解决办法是运行一下aclocal然后automake就可以了。

十二月二十九日 当前只有等待等待

终于找到了一个神器,apt-file这个是在不明白依赖包的时候的最好的工具。
我总是记不住我的桌面图标在哪里:
/usr/local/share/applications/ghb.desktop
/usr/share/app-install/desktop/handbrake:ghb.desktop
前者是所谓的"handbrake"的图形界面,后者是我拖拽而成的快捷方式。
下载了libbluray的文档。向videolan的大牛们的公益事业致敬!

十二月三十日 当前只有等待等待

实际上我是被迷惑 了,libdvdnav和libdvdread似乎是如出一辙,他们都是一个来源。但是他们似乎都不能够应对加密的dvd,不过这个是一个很好的高层库, 你可以象浏览文件一样的应对高级的如angle之类的功能。所以,我遇到加密的dvd应该还是要回到libdvdcss来。这里是一个关于dvdcss的破解历史。我也拷贝了一份原本的档案。这里是所有关于css的权威。关于破解的证据,这位高人保存了一份拷贝,我也效仿留了一个本地的拷贝,链接的旁边是(local)就是本地的。MoRE(Master of Reverse Engineering)的证言本地拷贝

十二月三十一日 当前只有等待等待

这个看起来是非常的 弱智的问题,我的vlc有些问题,应该是默认的libdvdread.so没有找到我安装的libdvdcss.so或者版本不匹配?总之,加密的dvd 无法解读,我的粗暴解决办法就是卸载ubuntu标准版本自己下载最新版编译源码,配置libdvdread的时候强制寻找libdvdcss,发现是一 个脚本的问题,大概是configure脚本寻找版本号没有包含1.14版,(寻找方法很简单,就是${EXE}${v} >/dev/null, 而其中的v是一个循环变量从一组版本号取值,比如1.1,1.2,1.10等等,唯独缺了我的版本1.14)所以,我自己的libdvdread.so是 config.h里有打开使用libdvdcss.so的宏开关的,那么动态加载dl是会加载动态库的。至于vlc就是一个接口版,意思是不直接链接所有 的所谓的plugin,而是生成一系列的libXXX_plugin.so存放在/usr/local/lib/vlc/xxx下,分门别类,那么我打开 vlc加载dvd报错的信息说是libdvdread_plugin.so是corrupt的,我使用ldd查看发现它找不到 libdvdread.so,注意不是libdvdcss.so因为隔了一层。只好手动在 /etc/ld.so.conf.d/libdvdread.conf加入/usr/local/lib的路径,我通常不喜欢这么作,可实在颇不得以。然 后还是失败,稍一凝眉想到忘记了ldconfig。ok了。弱智阿。
这个小段子是把当前目录下的avi文件转为m4v格式。
for var in `ls *.avi`; do  name="${var%.*}"; ffmpeg -i "${var}" -vcodec mpeg4 -acodec aac "${var}.m4v"; done
发现我犯了一个错误,编译ffmpeg的时候居然没有enable-libx264难怪encoder里没有h264,也难怪我的老旧的smartTV不 能播放mpeg4的格式,它只是支持h264,这个曾经迷惑了我,因为当我使用Handbrake从DVD抓成m4v的时候我是无意中使用默认的h264 的encoder,这个在我使用ffmpeg的时候是完全不同的,所以,虽然container都是m4v,但是codec是不同的,也就是同样是m4v 的ext,用handbrake抓的dvd就可以播放,而使用ffmpeg转录的m4v就不能播放,原因在此。
所以,要改成这样:
for var in `ls *.avi`; do  name="${var%.*}"; ffmpeg -y -i "${var}" -vcodec h264 -codec aac "${name}.m4v"; done

up.gif (335 bytes)