Bug经典回放(一)

原创 2006年06月26日 11:22:00
写程序有些年头了,Bug是从来都没有荒废过, 唯一不同的是刚开始写程序的时候,bug都比较简单.而伴随着年龄的增大,岁月的磋跎.Bug也越来越狡猾了. 当然bug分很多种,有程序设计上的bug,算法设计上的bug,还有架构设计上的bug.后两种bug不是一时半会讲的清楚的. 这里就讲讲程序设计上因为"不慎"而碰到的bt事情吧.

一): 本月经典bug.
       做游戏做的累了,就跑出来做应用软件了. 在这里的任务就是和同事完成一个GUI,这个GUI基本就是一个for Game的GUI ,所以我用了OpenGL.  大家都知道绘制GUI有个根本的函数就是drawRectangle, 这个函数正常心里的都会定义个drawRectangle(Image, x , y , w , h )或者类似的版本,.而正常的调用者都会使用w,h > 0的参数来调用. 所以正常的运行情况下,w,h为0的时候显然是出现问题了(废话).而且这是一个视频播放器软件.我需要一个可以lockable的texture,交给视频的decoder,让它来给我创建纹理大小,并往里填充数据.现在问题出现了:
    先来看看drawRectangle函数 ,它的逻辑是这样的.
    drawRect(ITexture* pImage, int x , int y ,int w , int h)
   {
            pImage->bind(0);  // texture , so we must call such a function(glBindTexture eg.)
           glBegin();
                ....................
           glEnd();
   }
  非常正常的一段函数.
   接着我们来看看LockAble的texture是如何工作的.
   CLockableTexture::onCreate(int pixelFormat , int w , int h)
   {
           onDestory();//先删除前面的数据
           m_Pixels = new char [w * h * 4];
           m_GLTexID = 0;// 纹理ID为0
           m_W = w ;
           m_H  = h;         
   }
   这个函数在decoder启动的时候,才会调用. 因为只有这个时候才会知道需要多大的纹理.
  
bool CLockableTexture::getTextureDim(int& w , int& h)
   {     
           w = m_W; ....
           if(glIsTexture(m_GLTexID) == false) return false;
           .....
   }

  bool
CLockableTexture::bind(int texStage)
  {
              //纹理数据存在了.但是OpenGL的texture ID不存在
              if(
glIsTexture(m_GLTexID) == false  && m_Pixels !=NULL)
                    __createGLTexture();
              ................
  }
     大家看最后那个函数,似乎有点蹊跷. 为什么不在onCreate的时候就把textureID创建好呢?原因是这样的. openGL是一个线程相关的东西.如果函数不在create OpenGL Context的同一个thread里调用. 会出现不可预测的错误的(其实无非也是没效果而已). 而onCreate函数是由视频解码器调用.视频解码器通常十一个独立的线程.所以这个函数的目的就是在bind的时候,判断一下是不是刚才有人调用过onCreate.因为调用过的话,就会把TexID清除掉.而bind函数肯定是在创建OpenGL的那个线程里调用的.
     现在这三个函数是非常正常的: 应用程序创建一LockableTexture.并把指针给decoder.decoder开始播放后,就onCreate这个texture . ...   程序不停的调用这个texture的bind.当它知道onCreate函数调用过后就__createGLTexture(); 并把数据upload到显卡中.
    前天晚上, 天才的我认为性能是一点点的省出来的. bug是一行行的if堵上的.于是我就在drawRect上下毒手.,把它改成这样了:
  
drawRect(ITexture* pImage, int x , int y ,int w , int h)
   {
            if(w == 0 || h == 0)
            {
                   log<<"warning .... w/h==0"<<endl;
                   return ;
            }
            pImage->bind(0); 
            glBegin();
                ....................
            glEnd();
   }

 前面说过w = 0 或者 h = 0 的时候,是不正常的. 这个时候,就应该警告和return . 非OpenGL渲染的时候,有时候是会挂的. 似乎这一切也天经地义.而且改完后我在debian下编译后也能正常运行. 非常的正常.但是把这个程序放到笔记本上的时候,经常放视频的时候,是黑的. log出来的drawRect的wh经常是w=1024 h = 0 . 非常的神奇.
   经过逐步排查.我最终还是把目光定位到了这个曾经被我认为是绝对不会产生问题的改动上: 我在bind函数里下了log. 竟然从来没有输出过. 而下在getTextureDim的函数里的log永远都log出警告: 我的纹理没有创建. ...... 这个纹理竟然一直没有纹理对象!!!!!!
    我的老天!!!
    郁闷了我好久. 比较了一下两台机器. 我的机器是Debian/Testing 台式机.笔记本
是Fedora Core 5.Intel T2300CPU. 貌似比台式机要先进. 但是它的CDROM的DMA没有开. 我的DMA是打开的. 所以当我调用decoder的play的时候,decoder很快就创建了我的lockable的纹理.我的应用程序第一次调用drawRect来绘制这个视频的时候,就知道了它的正确大小.所以传递到drawRect里的w h都是正常的.. 于是.bind函数就开始创建OpenGL texture ID .  而当DMA没有打开的时候, lockAble的纹理在第一次drawRect的时候还是个无效的纹理.所以得到的w , h  都是0........
    天啊, 这个纹理成了没人要的孩子了.......

    问题到这里就比较的明显了. w == 0 h == 0的这个判断,永久的阻止了__createGLTexture的调用. 这个显然是会黑屏的.....
  
反思:
   一:  多线程+OpenGL是可恶的
   二:  并非一台机器能正常运行你的程序就意味着你的程序是正常的.
   三:  看似正常的代码 往往不一定是正常的!!!
   四: 一定要注意分析代码的流程,下断点或者log

to be continue

2006-6-26
xheartblue

  

Bug经典回放(二)

continue....二)今年最经典的bug。准确的说。我还不知道这个是谁的bug。bug的发现是源于给别人做的一个外包程序。这是一个OpenGL应用程序。初始化代码是我写于2001年。并且一直沿用...
  • Nhsoft
  • Nhsoft
  • 2006年06月26日 20:25
  • 3573

Bug经典回放(三)

Continue三) 去年最经典的Bug     这个Bug的父亲不是我,是我的一个同事, 不过最终bug是被我抓到,也算是非常经典的一个bug,. 当时我在SBXF开发那个该死的休闲游戏.大家知道动...
  • Nhsoft
  • Nhsoft
  • 2006年06月28日 13:44
  • 2417

Bug经典回放(四)

Bug现象:    还是调试别人的程序. 这次是GUI.  我们的GUI是基于SDL OpenGL的. 程序运行以后进行视频播放.在出现的工具条上不停的点击几下后. 整个GUI系统均停止响应.    ...
  • hejishan
  • hejishan
  • 2007年12月18日 05:43
  • 133

Bug经典回放(四)

Bug现象:    还是调试别人的程序. 这次是GUI.  我们的GUI是基于SDL OpenGL的. 程序运行以后进行视频播放.在出现的工具条上不停的点击几下后. 整个GUI系统均停止响应.    ...
  • Nhsoft
  • Nhsoft
  • 2006年09月11日 22:38
  • 2234

经典功能缺陷Function Bug

Bug#1:oricity网站链接出现404错误 example: 缺陷标题:城市空间网站>”图片链接“出现404错误。({在什么网页}-{什么区域}-{出现什么问题}) 测试平台与浏览器:Wi...
  • Liuhaiyan6
  • Liuhaiyan6
  • 2016年09月01日 09:50
  • 974

一直播回放视频下载到电脑

直播回放视频下载
  • ZHKBlog
  • ZHKBlog
  • 2017年01月01日 19:41
  • 26969

OFFICE 2007 的BUG?

我也下载了OFFICE 2007的专业版,选择性安装了word、excel、powerpoint和publisher。刚打开界面的时候感觉非常不习惯,所以什么也没干又关上了。今天回家打算发个帖子,突然...
  • unimoon
  • unimoon
  • 2006年12月05日 18:53
  • 1253

工作BUG总结(一)

好记性不如烂笔头,以往也遇到很多问题心里默默的告诉自己以后要注意,但往往不出两天就回忆不起来。。。现在依然记不起来,翻看了自己在禅道上提交的bug,现在总结记录一些,之后再来精简。(移动端)     ...
  • vickywtt
  • vickywtt
  • 2017年05月10日 18:43
  • 212

struts2.1的一个小bug

最近搞了三天,那个File类里面的路径和标签的src属性的路径问题,的src属性好像只能用相对路径,但是这都不是主题,我把图片写到tomcat的webapp的项目下,然后通过的src属性显示图片,但是...
  • ya_1249463314
  • ya_1249463314
  • 2016年07月28日 21:40
  • 556

神奇的一件事:::::--------struts2的BUG

我要向后台传一个对象User,利用OGNL表达式在前台赋值。   正常的情况时这样:                         后台 :private User user; 然后get   se...
  • woshiwu
  • woshiwu
  • 2011年03月30日 01:45
  • 894
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Bug经典回放(一)
举报原因:
原因补充:

(最多只允许输入30个字)