关于gcc和X86上整数溢出的检测

今天同事贴了帖子问两个int64相乘怎么检测整数溢出的,本人小白,刚好也不懂,就搜下学习了下。以前读书还觉得我们浙大本科软院的课程还合理的,现在才发现,还是该本科就去读计院的,不学汇编,做底层的东西太亏了,得自己补课学习了。转入正题。

经过我快速学习,小结到如下:

  1. gcc会对某些溢出做wrap,导致程序误以为自己没有溢出: http://wangcong.org/blog/archives/1986
  2. 可以通过绑定平台的汇编来判断X86的CPU设置的标志位:http://stackoverflow.com/a/13764376
  3. 用INT64_MAX / A < B来判断A*B会不会溢出(正数)

加一点点自己简陋的见解:

1. 这个溢出的wrap仅对于某些简单的加减生效,是在编译阶段wrap的,可以通过gcc的编译选项-fstrict-overflow来避免。还有个gcc的选项可以在溢出的时候给进程发SIGABORT的信号,啥选项找不到那个网页了。。

2. 这个标志位还是很有用的,但是我担心会不会有线程安全的问题,希望有了解的同学能给些指导。关于标记位的说明,可以参看http://blog.sina.com.cn/s/blog_a25e014401012btf.html这个同学写的很详细。

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
NT IOPL OF DF IF TF SF ZF AF PF CF

使



I/O
权限
标志
占2位




















使




使




使



3. 这个就不详细讲了。

 

附一些自己要看的参考资料:

1. 关于整数溢出的一堆资料:http://stackoverflow.com/a/199413

2. 关于汇编的学习的:http://blog.csdn.net/yming0221/article/details/6216634 http://www.ibm.com/developerworks/cn/linux/sdk/assemble/inline/index.html

gfs阅读札记

前提
PC机器
大文件
大带宽而不是低延时
追写操作而没有随机写
顺序读为主,不优化随机读
多线程写入

杂记
chunk用64bit标识
namespace
chunkserver依赖linux系统的文件缓存,而没有自身的缓存
chunk 64MB, 64KB blocks each has 32bit chucksum

metadata:通过log来保证一致性
the file and chunk namespaces,
the mapping from files to chunks,
the locations of each chunk’s replicas (只存在内存,不进入log。rs定期检查cs的chunk)

The master maintains less than 64 bytes of metadata for each 64 MB chunk.
the file namespace data typically requires less then 64 bytes per file

rs的operation日志被同步到多个远程机器上,为了提高效率,会进行多条日志的同步写入。checkpoint是类似compact B-tree的结构,可以直接读到内存

chunk一致性
1. 所有对一个chunk的改动按照相同的顺序在所有的副本数进行
2. chunk有version,用于检测是否得到所有的改动更新
客户端chunk的分布信息依赖定时的更新,所以可能读到版本老的chunk,但是由于chunk一般是追加的,读到老的话只是过早的碰到文件结束,如果重试的话就会读到新的了。

Lease:用于保证chunk写入的顺序。master会指定一个chunk的一个副本会主副本,主副本会指定其他副本的写入顺序。lease一般长60s,可以通过心跳延长;也可以由master在lease超时前重新发布。

write写入的过程
1. client从master查询chunk的lease所有者和replicas位置。(如果没有的话master会指定一个新的lease)
2. master返回chunk的lease所有者和replicas位置
3. client向所有的chunk副本推送数据(传数据是按照pipeline的形式),chunkserver把数据存在LRU的buffer中。
4. client把数据发到所有的replicas以后,想primary发送write 请求;primary为mutations生成一个序列,并本地执行
5. primary把生成的mutation序列发给 secondaries , secondaries 按照收到的序列执行mutations
6. secondaries向premary汇报执行结果
7. primary向client汇报执行结果
如果有secondaries 执行mutations失败,其他primary或者secondaries上已经执行的mutations是不会滚的。client可以选择重新write(重复3-7步)。

append追加过程
append的模式和write类似,除了写入的时候保证位于同一个chunk的同一个offset
追加如果发生错误,client会重试,这时可能导致有的副本有重复的行。gfs只保证数据被写入多余一次。

snapshop
1. master更新所有的lease,使得所有的写入都需要和master交互
2. 更新operation日志,拷贝内存的metadata数据
3. 当client更新chunk的时候,master会让chunk所在的所有chunksesrver拷贝一份新的chunk。剩下的操作和正常的一样。

namespace和锁
gfs没有目录的概念,路径是类似文件系统目录的结构的,namespace实际上一个前缀压缩的树,每个节点(文件名或者文件夹)都有对应的读锁和写锁。锁只有需要的时候才生成,用完就删掉。由于没有目录结构,所以修改文件只对文件加写锁,对应的文件夹只需要读锁,增加了并发性。

chunk新建的节点选择
1. 磁盘利用率低于平均水平的
2. 分散最近新建的chunk到不同的节点
3. 跨机架避免交换机或者机架电源等带来的风险

chunk复制的条件
1. 副本数低于安全水平
2. 优先复制那些导致客户端访问失败的chunk
3. 为了避免对客户端访问的影响,master限制了总的复制数和单个chunkserver的复制数

新上线的chunkserver会被慢慢的被已有的chunk填满而不是被集中新建新的chunk,这样可以避免新建chunk太多带来的集中的写入。

垃圾回收
两种机制:
1. 只是把文件重命名成隐藏文件,超过三天(可自定义)以上的删除。chunkserver的心跳包带一部分chunk的信息,master会告知chunkserver哪些是需要删除的。
2. 可以配置某些路径的文件单备份或者立刻删除

旧chunk检测:依赖chunk version number,这个值master每次发lease的时候更新一次。

可靠性
1. server快速recover
2. 多副本:
1. chunk的多副本
2. master日志的多副本,shadow master。shadow master和master一样和cs交互获得新的chunk分布,同时读取master的operation log副本来获得chunk的新建和删除操作。shadow master只是为了增加读的可靠性。写的可靠性只能通过gfs以外的工具监控master,并在其他operation log副本的地方启动新的master来实现。

数据一致性
chunk分成64KB的block,每个block有一个32bit的checksum,chesksum保存在日志里。
减小checksumming的影响:1. client按照block大小读;2.全部放在内存中;3. 这个计算开销通常比IO小很多
读的时候会检测checksum,空闲的时候chunkserver会扫描闲的chunk

metadata
chunkserver: block的checksum和chunk的version number
master:文件名;文件的所有者和权限;文件和chunk的对应关系;chunk的version,location和reference count
master的metadata差不多每个文件100bytes

下面是我猜的,我觉得100bytes好难啊。。
如果1024M文件,差不多399bytes,怎么算都比平均100bytes多很多
文件名(经过树结构压缩的,估计平摊下来10byte)
ownship 4个byte
permission1个byte
需要16个chunk对应关系
id 8个byte,
version 8个byte
location 4个byte,
reference count 4个byte,

用vimdiff替换默认的svn diff

其实挺简单的。
修改配置文件:vim ~/.subversion/config

editor-cmd = vim
diff-cmd = yongle-vimdiff.sh

再加个yongle-vimdiff.sh到PATH包含的目录(/usr/bin或者~/bin随自己呗)就行了。
[yongle@centos6 src]$ cat ~/bin/yongle-vimdiff.sh

#/bin/bash
echo "yongle-vimdiff $*"
vimdiff ${6} ${7}

其实svn diff传给diff工具的参数如下:

yongle-vimdiff -u -L a.h (revision 1111) -L a.h (working copy) .svn/text-base/a.h.svn-base a.h

上面的yongle-vimdiff.sh也就很好理解了,呵呵。

最后运行之前的svn diff命令就能通过vimdiff看了,爽吧

home目录空间不足时du与df的大小不一致

上周搞了个python脚本定期查开发机上的home空间,今天老接到报警邮件说空间不足。
df命令的结果是空间用了200+g了,而du -sh /home/的结果则只有80g左右。
后来发现是文件被删除了,但是对应的进程却还活着,导致文件系统的空间没有释放,而du是根据目录结构计算文件占用磁盘量的,当然无法检测到被删除的文件。
用lsof |grep deleted可以看到哪些进程占用着被删除的文件,把对应的进程干掉就能释放出这些空间了。

junit测试中获取单个case的结果

最近一直在做兼职测试人员,发现组里测试的框架问题蛮大了,各种日志乱保存,想精简一下。问了下负责测试的老大,说以前其他组里做测试的时候都是case开始时设置个变量,结束时改下标记为pass,然后teardown的时候去判断是否需要收集日志。额,这case现在有上百个了,机械任务我可不喜欢做。。

跑到junit的官网找了半天没啥头绪,后来发现个rule的方式的类TestWatcher可以看跑的结果,http://kentbeck.github.com/junit/javadoc/4.10/org/junit/rules/TestWatcher.html。结果发现没发跑,MethodRule 已经被废弃了,看来junit的文档有点老了。

后来看到http://stackoverflow.com/questions/9942825/how-to-tell-when-junit-finishes-by-just-using-a-testwatcher这个,直接拿来用了,挺好用吧。把原来@after的teardown放到了finished函数里面,效果用起来不错。

 

又是个木有技术含量的帖子,仅作为笔记。

 


public class Testtttttt {

	private Logger logger = Logger.getLogger(Testtttttt.class);

	@Rule
	public TestName name = new TestName();
	@Rule
	public TestWatcher watchman = new TestWatcher() {

		@Override
		protected void starting(Description d) {
			logger.info(name.getMethodName() + ": starting : " +d.getClassName() + "."+ d.getMethodName());
		}

		@Override
		protected void succeeded(Description d) {
			logger.info(name.getMethodName() + ": succeeded : "+d.getClassName() + "."+ d.getMethodName());
		}

		@Override
		protected void failed(Throwable e, Description d) {
			logger.error(name.getMethodName() + ": failed : "+d.getClassName() + "."+ d.getMethodName());
		}

		@Override
		protected void finished(Description d) {
			logger.info(name.getMethodName() + ": finished : " +d.getClassName() + "."+ d.getMethodName());
		}

	};

	@Test
	public void fails() {
		Assert.fail();
	}

	@Test
	public void succeeds() {
	}

	@After
	public void tearDown() {
		logger.info("tearDownnnn");

	}


}

hudson的邮件通知配置

又是个测试人员干的活,呵呵。

默认有SMTP 的形式的,如果公司有提供这个方式的邮箱的话就什么都不用做;如果没有的话直接用Hudson Email Extension Plugin插件就好了,在配置里面勾上Override Global Settings,将SMTP server这项留空,hudson会通过javamail发送邮件了。

只是给自己记录下,无技术含量。原始网页在:http://www.fmw007.com/archives/242

从svn迁移到github

发现之前好多木有技术含量的东东,继续来个没技术含量的,仅做记录。

taobcode上面的oceanbase昨天也放到github上面去了,同事给我的手册有点点问题,做不下去。下面记录下怎么迁移的。

  1. 安装软件:git,git-svn。centos里面直接可以yum装的。
  2. 生成ssh-key,并添加到自己github的账号里面******体看github的指南https://help.github.com/articles/generating-ssh-keys
  3. git命令:
git svn clone http://code.taobao.org/svn/OceanBase/trunk/oceanbase oceanbase
git remote add oceanbase ssh://git@github.com/yourusername/oceanbase.git
git push oceanbase master

这样就搞定了。原来用过hg,两个很类似,不过hg有好用的客户端,git的我还没找图形客户端,下次看看。

前辈访谈小感

好久没有写博客了,今天完成了百啊的影子传说任务,深度采访了主管楚材,专家组的普空,还有隔壁组传说中的褚霸。

老大楚材说话还是很亲切,不过被嫌弃访谈“闷”了~三个小男生,貌似真不会开玩笑……要主动,要迎接变化~

普空是个很坦诚的老人(哈哈),没有了和主管谈话的拘束。普空说了挺多的,前期要专注,这个我很赞同。

霸爷则是仰慕已经的大牛,跟了两期的了解系列课程,可惜最近百啊,没能跟这周的课程了。霸爷很谦虚,老说自己其实挺loser的。有两句话,很有感触:

每个人都有每个人的苦,看不到而已。
如果自己不花时间,不会有人愿意帮你,还是得自救。

 

入职已经两个多月了,从刚入职的迷茫到现在说不出明确的方向,我想接下来几天会好点。最近快结束培训了,先把ob的事情搞专了,然后再考虑该专什么。不过幸好ob就是当初自己选的,挺喜欢的。借用楚材的话,永乐是一进来就点名要ob的,哈哈。

喜欢,投进去,干起~