Bye Bye Moto

    随着Motorola Home部门正式被Arris收购,我也不再是moto员工了。作为一毕业就加入moto并一直干到现在的“老员工”,对于moto还是很有感情的。。。 所以,回顾一下我的moto生涯吧——
    05年大四开始找工作,拿到南摩的offer,很是开心——一方面是搞定了工作,另一方面,可以先开始intern,工资4k,其中1k交学校,剩下的都 归自己。当时每个月生活费也就几百,3k的纯收入真是笔巨款,而且住学校,吃住都很便宜,上下班还有班车,就停在学校边上的珠江路上,超级方便。
    06年毕业,本来可以带着intern的CoreId直接上班的,不过当时为了看世界杯,中间断了一段时间,结果入职时就换了CoreId,还损失了那几天的工资,后来觉得有点亏。
    那段时间主要在Terry的team里做Intel FDI文件系统,这是在Nor Flash上的一个私有文件系统,充分利用nor flash特性设计的文件系统。印象比较深刻的是当时有个老外帮忙用单片机做了一个专门用来做掉电测试的板子,随机地让手机开机、掉电,不停的循环,确保 文件系统不会坏。把一个文件系统做稳定之后还是小有成就感的。
    后来re-org,当时文件系统已经成熟了也不需要太多的维护,有机会转去做bootloader,想想有机会跟硬件、汇编打交道,蛮有意思的。
    moto的手机主要用TI和Qualcomm的芯片,当年还是TI很火的时候,TI很牛,也不给BSP,不过有之前的bootloader的base,换用新的芯片,也就是改些配置,把板子跑起来的事情,其实没有太大的挑战性。值得说的大概有两个事情。
      · 一个是在某个片子上只有32KiB的internal RAM,跑之前的code因为太大根本不行,只能想办法,改编译选项(-Os),找大的global变量,看看能不能缩减字库之类的,后来总算把最开始的 bootloader弄得足够小,然后去初始化DDR Ram,然后内存使用就豁然开朗了;
      · 另一个是关于flash速度的,当时用RSDLite烧机(现在俗称刷机)速度很慢,不但烧写慢,checksum也很慢,远远太不到flash的理论速 度。我正好之前做文件系统对flash很熟,知道怎么配置,怎么用burst read/write,改动一番后,flash的速度提高了很多。
    09年中的时候,上海的home部门在招人,当时正好想换个环境到上海去,就内部申请transfer了。内部电话面试一下,两边的老板同意就行了,这一点还挺人性化的,公司的HR也很专业,transfer的事情基本上都由HR搞好了。
    于是,在南摩工作了整3年之后(不包括intern的半年),我来到了上海摩托。
    这是个完全不一样的部门——
      不再是MobileDevice了,而是Home,专做机顶盒的软件;不再用Clearcase/ClearQuest了,而是用Bugzilla(不过 现在改用Jira了)/ SVN了;电脑变差了,没有免费饮料了,没有building了。。。 诸多变化,一开始还是挺不适应的。。。
    在这里,因为是scrum,做的事情很杂,经常几个月就换个方向做,于是,在上海摩托,做过这些东东:toi, bitband, viaccess, ekioh-webkit, dlna, dtcp,以及修过任何机顶盒会碰到的问题,hdmi啦,audio/video output啦,等等。
    做新的东西,是能学到不少东西,但很多时候项目就是在修bug,这个就很没意思了,在上海3年多,工作上更多的只是跟着项目走,真正深入地学到东西,很 少。有时候只能自己在业余的时候搞搞Android开发,玩玩自己的博客,翻翻墙,看看Twitter,看各种IT博客之类,收获倒是挺多。
    · 一方面,Linux玩多了,各种脚本,以及python,svn,git,玩得还都不错,也在Android市场上有两个评分都不错的app;
    · 另一方面,各种博客(以及StackOverflow!)看下来,真心能学到很多东西,并发编程、c/c++/java的某些细节,等等。佩服那些大牛小牛们,呵呵。Google Reader真是神器,可惜就要关了。
    这期间,经历了Moto的拆分,Google的收购,还始终算是moto的员工;经历了Twitter的崛起,饭否的成功、封杀与复活,新浪微博的ws, 微信的异军突起,从不怎么使用新技术新产品,到现在用着twitter, facebook, foursqure, ifttt, pocket, evernote, dropbox, amazon aws, godaddy, bitcoin等各种新玩意儿,算是积极的变化吧。
    然后,Arris的收购,然后,终于不再是moto人了。。。
    Bye Bye Moto
    —-
    谨以此文纪念在moto的岁月
    2013.05
Share

用dmalloc调试memory leak的一点使用经验

用c/c++开发的程序,不可避免地会遇到memory leak的问题。在俺们的项目里自己的code基本上已经boost::xxx_ptr了,但是用上第三方的库,总还是得用raw pointer,于是会有各种诡异的memory leak问题。

Dmalloc可谓这方面的神器,它功能很多,不过这里只记录一下怎么用它来找memory leak。

  • 环境: Fedora 11, gcc 4.4.1
  • 准备:
    1. Get dmalloc from http://dmalloc.com/ (latest version 5.5.2)
    2. Patch cxx return value, 如果没有这个patch,dmalloc log里c++的函数地址似乎有问题
    3. make && make install, 注意还需要额外make cxx, threads, install也一样
    4. 设置环境变量,我们只需要打印log信息,所以
    dmalloc runtime -p print-messages
    然后设置相应的环境变量就ok了
  • 调试:
    放两个例子。(相关code在这里 dmalloc_share.tar.gz

    1) 最简单的例子 basic_usage

    $ ./basic_usage
    1361264794: 6: Dumping Chunk Statistics:
    1361264794: 6: basic-block 4096 bytes, alignment 8 bytes
    1361264794: 6: heap address range: 0x7f7840c63000 to 0x7f7840c69000, 24576 bytes
    1361264794: 6:     user blocks: 3 blocks, 11216 bytes (45%)
    1361264794: 6:    admin blocks: 3 blocks, 12288 bytes (50%)
    1361264794: 6:    total blocks: 6 blocks, 24576 bytes
    1361264794: 6: heap checked 0
    1361264794: 6: alloc calls: malloc 4, calloc 0, realloc 0, free 2
    1361264794: 6: alloc calls: recalloc 0, memalign 0, valloc 0
    1361264794: 6: alloc calls: new 0, delete 0
    1361264794: 6:   current memory in use: 2000 bytes (2 pnts)
    1361264794: 6:  total memory allocated: 3600 bytes (4 pnts)
    1361264794: 6:  max in use at one time: 2000 bytes (2 pnts)
    1361264794: 6: max alloced with 1 call: 1200 bytes
    1361264794: 6: max unused memory space: 1072 bytes (34%)
    1361264794: 6: top 10 allocations:
    1361264794: 6:  total-size  count in-use-size  count  source
    1361264794: 6:        1200      1        1200      1  ra=0x400ede
    1361264794: 6:        1200      1           0      0  ra=0x400eb3
    1361264794: 6:         800      1         800      1  ra=0x400e9b
    1361264794: 6:         400      1           0      0  ra=0x400e70
    1361264794: 6:        3600      4        2000      2  Total of 4
    1361264794: 6: Dumping Not-Freed Pointers Changed Since Start:
    1361264794: 6:  not freed: '0x7f7840c63008|s1' (1200 bytes) from 'ra=0x400ede'
    1361264794: 6:  not freed: '0x7f7840c65c08|s1' (800 bytes) from 'ra=0x400e9b'
    1361264794: 6:  total-size  count  source
    1361264794: 6:        1200      1  ra=0x400ede
    1361264794: 6:         800      1  ra=0x400e9b
    1361264794: 6:        2000      2  Total of 2
    1361264794: 6: ending time = 1361264794, elapsed since start = 0:00:00
    

    很明显,地址0x400ede 0x400e9b这两个地方有memory leak,用addr2line看一下:

    $ addr2line -e ./basic_usage 0x400ede
    /xxx/basic_usage.cpp:18
    $ addr2line -e ./basic_usage 0x400e9b
    /xxx/basic_usage.cpp:12
    

    就很清楚了

    2) tricky_usage, 稍微有点tricky的调试方式,稍微解释一下:
    a. 注册SIGHUP和SIGINT的handler;
    b. 收到一次SIGHUP,调用dmalloc_mark(),标志一下当前的内存使用情况;
    c. 再收到一次SIGHUP, 调用dmalloc_log_changed(),记录从上次mark之后的内存变化;
    d. 收到SIGINT,调用 dmalloc_log_unfreed() 打印所有没有被free的内存

    $ ./tricky_usage&  # get the pid
    $ kill -1 pid  # mark, and call testFunc()
    $ kill -1 pid  # log_changed memory
    Asking dmalloc to log changed
    1361264378: 5: Dumping Not-Freed and Freed Pointers Changed Since Start:
    1361264378: 5: not freed: '0x7f67d2384808|s1' (1200 bytes) from 'ra=0x4010ab'
    1361264378: 5: not freed: '0x7f67d2386c08|s1' (800 bytes) from 'ra=0x40105b'
    1361264378: 5: freed: '0x7f67d2389e08|s2' (400 bytes) from 'ra=0x401046'
    1361264378: 5: total-size count source
    1361264378: 5: 1200 1 ra=0x4010ab
    1361264378: 5: 800 1 ra=0x40105b
    1361264378: 5: 400 1 ra=0x401046
    1361264378: 5: 2400 3 Total of 3
    

    注意”not freed”和”freed”,很明显吧 🙂
    多kill -1几次,可以观察到每一次freedAndNew这个变量会在下一次被free掉,这个并不算leak,真正的leak是notFreed这个变量。

    然后kill -2看看结果。

    $ kill -2 pid  # log all unfreed variables
    1361264409: 18: dumping the unfreed pointers
    1361264409: 18: Dumping Not-Freed Pointers Changed Since Start:
    1361264409: 18: not freed: '0x7f67d2383808|s1' (1200 bytes) from 'ra=0x4010ab'
    1361264409: 18: not freed: '0x7f67d2386408|s1' (800 bytes) from 'ra=0x40105b'
    1361264409: 18: not freed: '0x7f67d2386808|s1' (800 bytes) from 'ra=0x40105b'
    1361264409: 18: not freed: '0x7f67d2386c08|s1' (800 bytes) from 'ra=0x40105b'
    1361264409: 18: total-size count source
    1361264409: 18: 2400 3 ra=0x40105b
    1361264409: 18: 1200 1 ra=0x4010ab
    1361264409: 18: 3600 4 Total of 2
    

    不解释了~
    想真正杀掉这个测试进程,kill -9吧

    总结:
    1) 设置dmalloc的环境变量,link libdmallocxxx,运行完程序会有dmalloc的分析数据;
    2) dmalloc_mark() 和 dmalloc_log_changed() 可以用来分析某一次事件或一段时间内的内存变化情况;
    3) dmalloc_log_unfreed() 可以打印当前所有没有free掉的变量

Share

过年两三事

一晃一个年就这么过去了,有些事情记一下。

· 雪天开车
    放假前一天下午开车回的家,天下着雪,白茫茫一片,感觉像到了东北;
    沪宁高速上4个车道,边上的两个车道都已经有积雪了。大家开车都很小心,基本上只走中间两个道,速度不超过80km/h。尝试开到90km/h,发现车子明显有点打滑了,不过这种无法控制车子轮胎的感觉还挺tricky的——漂移大概也是这样吧?

· 一大家子的年夜饭
    过年的时候第一次喊上了GF的爸妈一起吃年夜饭。GF一家子,大姑姑、姑父,小姑姑一家子,外公外婆,我自己一家子,饭桌挤得满满的,感觉很是热闹。
    之后看春晚,分成三段时间。。。第一段在我家,GF和我陪我爸妈一起看;然后我和GF去她家,陪她爸妈看了会儿;再然后快12点了,我回家,各陪各爸妈看。这安排不错的,哈哈。

· 订婚了
    按我们小镇上的规矩,是要订婚的。初三一早,先去GF家接女方家的媒人来我家,两方的媒人吃鸡蛋点心;然后两媒人背着媒人包和我一起去GF家提亲;包里有各种东西,喜帖,金器,现金,红蛋,花生,等等。
    那喜帖写得不错的样子,很有中国特色。

· 情人节
    2.14正好在过年的时候,想试试在那天领证。
    之前尝试打电话,一直没人接,估计没人,毕竟长假期间;另外,GF的户口本忘在上海了,估计也领不了。但老妈催着说去试试看,只好去堰桥的惠山区政府那边看看。
    到了那儿,ms没人,问了下门卫,说似乎有人拖了人在这天领证,可以进去试试。果然,有一对新人在,唯一的工作人员明显是他们认识的,这真是开了后门的嘛。问了工作人员,说没有户口本,去公交局开户籍证明也行… 但是没有照片,也搞不定领证。。。
    也罢,缺了两样东西,去补也麻烦,还是择日再说吧。

Share

买平板小记…

    前段时间一直长草平板,正好Liu桑在米国,元旦前回来,可以帮忙带,于是可以出手了——

    本想买个Nexus 10,虽然太丑,但鉴于其强大的硬件配置和相对不错的价格,一直想买它。Google Play Store上的硬件不支持中国地区的购买,不过用个自己的翻墙代理,轻车熟路地点开购买的link,用个米国的地址当信用卡的帐单地址,可以顺利地用Google Checkout支付。然而看最终价格,由于Liu桑所在的不是免税的州,东西$399+运费近13刀+税22多刀(粗略记得的数目),一下子贵了200多rmb。觉着亏,不该给美帝交税的,况且Google你丫收13刀的运费,太黑了!不买!

    转而考虑Amazaon的Kindle Fire HD 8.9,更小巧的设备,但又不至于像Nexus7那样太小,感觉可能正合适,299刀的价格,也基本上对得起那个硬件。软件方面,没有Google的服务是个问题,但估计可以自己刷CM,或者也许可以另外装相应的服务,总之可以折腾着搞定,就它了。

    某天上午,点开KindleFireHD8.9的link,填好Liu桑的地址,下单付款,一切顺利,花了$299等收货。
    那天下午,“什么值得买”上看到说Kindle平板系列降价$50了了,我一看,丫还真是,上午的单子下完没几个小时(估计过了中午)amazon上就搞特价给了$50的优惠码,当时感觉那个亏啊。。。

    尝试取消之前的订单,但是系统说因为已经出货了,不能cancel,只能return。好吧,那就填个退货申请,理由写上因为价格变化而“描述不符”,可以原价退货,amazon还会安排UPS上门取货,挺方便的样子;(注意退货原因,要是选了错误的订单,是要被amazon扣掉几刀并且不免UPS上门取货的费用的,选描述不符就啥费用都没了)
    然后重新下单,以$249的价格买了同样的东东,等收货~

    几天后,Liu桑郁闷地说,UPS的小哥们天天上门来取货,但是货还没到,取啥呀。。。
    同时,amazon邮件说,order已经return成功了,refund会在2~3个工作日内退回到俺的信用卡——擦,东西还没退,钱先退了,受宠若惊啊!看来米国人做生意都靠诚信。要是在国内这么搞,估摸着n多东西会找不回来吧?

    再一天之后,发现钱已经顺利地退回到信用卡,Liu桑也已经收到两个货,并且退了一个,一切都很正常。
    嗯,感谢amazon,$249刀的8.9寸平板,算是值了。等Liu桑回国了~

    货还没到,上张图解解馋
kindle-fire-hd-89

Share

2012 – 国庆琐事

· 今年中秋、国庆第一次高速公路免费,知道会很堵,但还是想凑这个热闹——于是从上海到无锡,开了6个多小时。在阳澄湖休息区附近,整个沪宁高速成了一个停车场,甚至有人停车爬下草坪跑到休息区去吃东西。。。倒也是难得的体验。
    后来发现了Google Maps的路况似乎还蛮准的,一看苏州到无锡整个都是拥堵的红色,我算是比较明智地从苏州新区下了高速,走312国道回去了。后来听说有邻居同样是中午出发,走高速晚上9点多才到的无锡,汗。。。

· 小华同学从英国回来,几个初中同学找了这个机会聚一下。在无锡的同学,都住城里了,变化都不大。护士、光伏、装修,各行各业都有。
  几个在堰桥的高中同学也喊聚会,也一起参加了。相比起来,高中同学从事的行业要稍微集中一点了,主要是IT、金融行业了。
  聊到初、高中的老师的时候,我发现自己有印象的老师屈指可数了。。。 初中的班主任,物理,数学老师还记得;高中的班主任*2,馒头,10班的化学老师,也就这些还记得了,sigh。。。

· 在家发现了一个太阳能手电筒——没错,就是“国产零零漆”里传说中的太阳能手电!不过这个还是有蓄电池,还带手摇发电的。
  我一直想找块太阳能电池板给我的Kindle充电的(理想状态下,kindle就永远不需要插电了),果断把手电筒的电池板拆了。量了一下,太阳底下有很稳定的5.x伏电压,感觉有戏。
  回到上海,剪掉根USB线,把电池板的正、负极接到USB的V+,GND线上,试了一下,是有电,不过手机认为似乎是接着电脑——Google一下后发现,充电器(至少moto的)的D+/D-是短接的,这很简单,把USB线的两根线接一下就OK了,然后试试手机上的充电——看上去一切正常。
  ——然而,80%电量的手机,充了一段时间电之后,只剩60%多了,囧。
  然后把线拆开来,接上万用表测电流,很囧的发现在3mA左右,等于没有了;另外Google后发现一般都会接个二极管,以保证不会有逆流(相当于电池给太阳能板供电)。
  好吧,结论:这块板子太小,以后得找块大点的太阳能板才行,另外还得接个二极管才能真正实用。

Share