我怀疑是不是cf所有bugg都让我遇上了

这些年,我们遇到的Bug们!
嵌友们,你们碰到过的Bug们,有没有记忆犹新的!先看看他们碰到的奇葩Bug,是否跟你的有一拼?
给大家讲一个有关功耗的bug。那是我在前东家所参与的第一个重点的芯片设计项目。那个项目之初的设计目标就是低功耗,当时市面上竞争对手的最低休眠功耗在1.1V电压下可以做到1uA,但是他们用了较为旧的工艺,所以芯片面积大。而我们选择了更新的工艺,面积可以减小一半多,但是由于新工艺的漏电流较大,经过初期的估算,我们的目标是接近1uA。最后在前端设计完成后,用PTPX后仿真的结果就是1.5uA。老大觉得达到了预期,于是就送出去流片了。芯片回来后bring up,在基本功能正常, 无线收发的指标都达到预期之后,组里的老板,director,甚至部门的VP就关心一个东西:休眠状态下的静态功耗。当我们满怀期待地接上电流表之后,电流表稳定在了6uA,是预期值的整整4倍,足足大了4.5uA!换了5块板子,都是这个数,换了socket 板子,再测了三四颗芯片,都没有比6uA低的。这可要了命了,我们的芯片主打就是面积小低功耗,现在这功耗简直被竞争对手吊打啊,director下了死命令,必须在下一次流片之前把问题找出来,而下一次流片就是量产流片了。组里所有人开始行动起来开始找原因。我并不是always on模块的设计者,但是是我跑的PTPX仿真,我于是先又跑了一遍仿真,重新检查了各种设置,没有发现任何问题,仿真就是告诉我是1.5uA。同时跑其他非休眠状态的仿真,仿真功耗值和实测值可以对得上,证明设置是正确的,工艺库的值也是准确的。接下来怀疑是板子上哪里有漏电或者是板子设计的问题,但是经过将近一周的重新排查,PCB板设计并没有问题,那么就是芯片内部的问题了。always on模块的设计者也和大家重新review了design,各种猜想被提出,但是又各种被实测否定。比如说,猜测某个isolation cell没有插入对,于是我们和模拟团队坐在一起,把上千个信号又一起review了一遍,最后发现都是正确的。类似这样的头脑风暴几乎每天都在进行,每次大家满怀希望以为找到一个合理解释,但是最终都是失望而归。这里要和大家讲述一下silicon debug的难度。 软件debug通常有日志,有调试器的帮助,单步运行足以找出绝大多数bug。但是小小的芯片就难了,封装好的芯片还没有小拇指甲盖大,上面的引脚比头发丝也粗不了多少,GPIO一共也就二三十个,每个IO后面能mux出来的信号也是有限的几个,要是动态的信号好歹可以利用示波器和逻辑分析仪看波形,但是这种静态功耗的debug,示波器和逻辑分析仪也只能抓瞎。我们测算过,4.5uA说大也大,说小也很小,一个transistor短路就足以引起这么大的short circuit current,可是小小芯片里面几千万上亿个transistor,找出这个无异于大海捞针。大海捞针也得捞啊,在我们大家都想不出其他解释之后,老大批准了给芯片照热成像和FIB。给芯片照热成像是啥意思,因为芯片在运行的时候是有功耗,那么在有电流流过的地方就会有功耗,那么相应的温度就比周边稍稍高一点点,这个时候用专用的热成像仪照一个照片,只要看到哪一个地方比其他地方红一些,那么就大概可以定位出功耗大的区域,然后再在layout上找到那片区域对应的模块。
但是照回来的结果是,热成像分布非常均匀,完全看不出有哪个地方过热。想想也是,4.5uA的电流,换算成功率也就是几uW,太难了。然后又在几个怀疑的点做了FIB,简单说就是把封装打开,在die上面重新用仪器去把metal wire断开,这个因为难度高,做一次就要好几千美金,我们前后做了好几次,每次都是没有效果,上万美金就这样打了水漂。真是心疼啊,我们几个年终奖加起来也不到这个数。这样大概折腾了2个月,下至工程师,上至director,我们都觉得要放弃了。只能猜测是厂家工艺的原因,随着量产芯片tape out日期的临近,我们只能寄希望于下一批次回来的芯片能够功耗第一些。直到有一天,我和另一个项目的后端工程师一起开会,review placement 和 critical timing path时,他给我们看了当前的placement, 我发现standard cell之间还有一些空位,就像下面这个图,所有的单元应该是按行摆放,但是中间会有空位。
我之前知道filler cell是用来填满空隙的, 可以去平衡metal density,可是decap cell是个什么东东?这玩意有功耗吗?开完会立马打开lib文件一查,我擦,decap cell这玩意居然是有leakge power的!而且x2, x4, x8 (就是不同大小)的功耗也是不一样。 我隐约觉得自己发现金矿了!于是检查后端给我们的netlist, 没有filler cell, 没有decap cell!难怪前端功耗仿真偏小,因为这些cell压根就不存在。在后端给前端返回netlist的时候,因为decap cell和filler cell属于没有任何功能,没有任何connection的cell, 他们通常的做法是在写出netlist的时候不包括这些cell。 于是我们重新让后端写出带这些cell的netlist, 再跑功耗仿真,非常准的6uA, 问题解决!进一步分析表明,绝大多数的decap cell被放置在了always on的区域。这里面插一句,现代SoC低功耗设计的一个常用方法是将芯片划分成不同的power domain,有的power domain可以开可以关。在关闭的时候连power都关掉,这样连漏电流就都没有了,是最省功耗的做法。但是芯片睡眠后必须有一部分电路还是工作的,准备随时唤醒整个芯片,这一部分always on的电路因为power rail不同,在版图上通常是划定一个特定的区域。我们的芯片由于always on逻辑很少,这片区域function cell比较稀疏,而后端在放置decap cell的时候是全局铺放,当tool看见这部分空位比较多的时候,将大部分的decap cell都放在了always on区域里,这样引入了多余的4.5uA功耗。这个bug坑的地方在于,前端拿到的netlist里没有decap cell,而我们前期也压根没有往这方面想,花了大量时间去检查看function上是不是有问题。
回想起这个bug,仍然让我有些痛苦。作为一个程序员,在发现bug时,你学会了首先在自己代码中找问题,或许在测试一万次之后,你会把问题归咎于编译器。只有在这所有的都不起作用之后,你才会把问题归咎于硬件。这是我遭遇一个硬件bug的故事。抛开别的不说,我曾为《Crash Bandicoot》写存储卡(读写)代码。对于一个自大的游戏程序员,这就像是在公园里散步一样轻松愉快,我认为只要几天就写完了。我中止调试六个礼拜。在此期间我做一些其他的事情,但我一直回来处理这个bug——几天内每天几个小时。这个bug实在烦人。这个bug的症状是,当你需要保存你的进度时,代码会访问存储卡,而大部分情况下没有什么问题…但是偶尔读写会超时…没有任何明显的原因。一个短小的写入经常毁掉存储卡。玩家要保存进度,我们不仅不保存,还擦除他们存储卡上的全部东西。天哪。过了一段时间,我们在Sony的制作人Connie Booth慌了。我们显然不能带着这个bug发布游戏,而六个星期之后我对于问题出在哪一点线索都没有。通过Connie我们向其他 PS1 开发者求助:有没有人出现过像我们这样的情况?没有。绝对没有任何人在存储卡系统上出现任何问题。在你绞尽脑汁之后,你能做的唯一一个调试方法就是分而治之:一点点去除程序中的代码,直到留下的代码很少但你仍然出问题。像木雕一样去除没有问题的代码,留下的就是你的bug所在。在这样的背景下挑战在于,视频游戏是很难去除某一部分的。在你删除模拟重力或者显示字符的代码后,如何运行游戏?你必须做的是用一个假装做真正的事情,但实际上只是做很简单的不会出现bug事情的东西来替换掉整个模块。你必须写新的支撑代码来让这些玩意正常工作。这是一个缓慢而痛苦的过程。长话短说:我做完了。我移除了大片大片的代码,相当多,只留下了初始化代码——就是准备游戏运行系统,初始化底层硬件等等。当然,我不能显示加载/保存菜单,因为我截除了所有的图像代码。但是我能够假装用户使用(不可见的)加载/保存屏幕并且请求保存,然后写入卡中。我最终以一个带有这个bug的很少量的代码结束——但问题仍然随机出现!在大多数情况下没啥问题,但是偶尔会失效。基本上所有的Crash的实际代码都被移除了,但还是这样。这实在是莫名其妙:留下来的代码基本上都没做什么事。在那时——估计是凌晨3点——一个想法蹦了出来。读写(I/O)涉及精确定时。无论是硬盘、存储卡、蓝牙发送器——随便啥——做读写的底层代码都是根据时钟来的。时钟让不直接连接到CPU的硬件设备和cpu运行的代码同步。时钟决定了波特率——数据从一头传到另一头的速率。如果计时有什么问题,硬件或者软件或者两者都会乱七八糟的。这真的,真的很糟糕,并且通常导致数据损坏。如果我们的初始化代码以某种方式
弄乱了计时会怎么样?我又看了一遍测试程序中和计时有关的代码,并注意到我们将PS1上的可编程计时器设置到了1kHz(1000跳每秒)。这是比较快了,当PS1启动的时候,默认状态大概是100Hz。因此,大多数游戏将他们的计时器设置为100Hz。这个游戏的带头(和除我外的唯一)开发者Andy,将计时器设置为1kHz,使得Crash的动作计算更加准确。Andy喜欢矫枉过正,如果我们要模拟重力,我们应该尽可能的提高精度!然而如果提高计时器频率莫名其妙的干扰了整个程序的计时,故而将这个计时器设置到存储卡的波特率上会怎样呢?我将计时器代码注释掉。然后我就无法复原这个bug了。但是这并不表示bug被修复了,这个问题是随机发生的。万一我只是运气好呢?几天过去了,我还是在玩我的测试程序。Bug没有再出现。我回到全部的Crash代码中,修改了加载/保存代码,在访问存储卡之前将可编程计时器重置为默认设置(100Hz),之后设置回1kHz。从此之后没有发现问题再次出现。但是…为什么?我重新回到测试程序上,试着检测当计时器设置为1kHz时出现的那些错误的模式。终于,我注意到这些错误出现在使用PS1手柄的人身上。因为我自己很少这样做,所以我没有注意到(为啥我要在测试加载/保存代码的时候用手柄)。但是有一天我们的美工等我去完成测试(我确定那时候我在爆粗口),而他紧张的摆弄着手柄。卡损坏了。“等下,怎么回事?喂,再来一次!”一旦我发现了这两件事是联系着的,就很容易重现bug:开始写入存储卡,动一下手柄,存储卡损坏。在我看来完全是硬件bug。我去找Connie告诉他我的发现。她转述给设计过PS1的硬件工程师。她被告知:“不可能,这不可能是硬件问题。”我跟她说问一下我能不能直接和他说。那个工程师给我打电话了,他用着他的烂英语,我用着我更烂的日语,我们争论一会。我最后说:“我给你一个30行的测试程序,让你在动手柄的时候能够出现这问题。”他答应了。他向我保证,这是浪费时间,而他正在一个新项目上很忙,但因为我们是Sony很重要的开发者,他会试的。第二天晚上(我们在洛杉矶,而他在东京,所以对于我来说是晚上而他是到了第二天),他给我打电话,不好意思的向我道歉。这是个硬件问题。我还是没有完全搞清楚问题到底在哪,但是我的印象中,从Sony总部的反馈听到的是,如果将可编程计时器设置到足够高的时钟频率,会影响到主板上时钟晶振附近的一些东西。这些东西之一就是存储卡的波特率控制器,同时也设置手柄的波特率。我不是搞硬件的,所以对于细节我相当模糊。但是主旨是主板上两个独立部分的串扰,以及手柄接口和存储卡接口数据发送的结合在1kHz的时钟频率下会导致丢位,从而数据丢失,以致卡损坏。这是我全部编程生涯中,唯一一次因为量子力学debug的问题。
一批试制PCB,收到后开始手焊。第一块焊好,烧程序,一切正常。第二块焊好,烧程序,不正常,后确认是电源问题,飞线、换件……一时无法解决。狠心(狠心的原因是器件不便宜,焊上去不能用再吹下来也不保险了)焊好第三块,烧程序,不正常,与第二块差不多。软件组不耽误事,反复调第一块板子就好了,但硬件组很蛋疼。某日,终于决定一根线一根线地量,翻出发给厂家的PCB图,一打开就发现一个特不自然的地方:电源浮地。马上测量,证实了这一点。板子需要重做是没啥问题的了,程序倒也已经调了个差不多,基本上没耽误。所以在等待新板子的过程中,我们思考了两件事:第一,为啥电源还浮地,就把这图发出去了——以那时的认知来看,只有这一处问题。第二,为啥第一块板子能用。所以,我认为最难调试修复的bug是:一次成功,但正常运行的是因为有bug,不正常的才是正常的。
这个我一定要怒答!当年在IBM 的CellBE上 (就是PS3上那块)做了不少图像处理、视频编解码的工作。这个奇葩的异构体系结构有如下几个特性:虽然号称一个芯片上有9个核,但是只有一个是通用核,普通程序只能在这个核上跑,没法和x86一样直接多线程!另外的8个运算核只有一种模式那就是128位的向量运算,只能跑一些及其精简的指令,需要在C程序中嵌入伪汇编来编程。啊?加减乘除运算符?在运算核上放多了那个会被开除吧!通用核与运算核并不共享内存空间, 他们之间所有的数据共享和同步都必须完全手工管理,想要传数据得自己调用硬件DMA,然后自己同步!因为代码全部展开能最大增加优化潜力,基本一切函数都被变成了宏!要想发挥性能一定把程序并行、向量化。用trick,gotcha一堆!人能看懂的程序都不是好程序!8个运算核上跑的程序不能用gdb debug,唯一靠谱的调试手段就是printf,但是因为运算核上printf也是通过DMA跑去通用核打印到终端,所以不同核之间的printf并不能保证同步!只有terminal access都不算问题了,至少还有vim!这一年我需要在上面从头写一个MJPEG编解码器。视频编码过的二进制流你们见过的!!!大年三十在家加班debug看dump出来的二进制流再调这种坑爹的程序你们脑补下!!!不行了我一定要贴段代码恶心下你们,哼!!这段566行气势恢宏的代码有且只有一个功能,那就是把rgba转成了yuv!!!!
大一时候参加ABU Robocon机器人大赛,我不懂机械也不懂电子,只会写写C++,于是就负责编写机器视觉的闭环控制程序,大部分时间做图像处理,小部分时间调用串口驱动电机。结果有一天机器人突然一动不动了。赶紧改代码,改了一会儿。正当我怀疑是不是把板子烧了的时候,F5一跑发现,机器人居然又能动了!以为修复了bug,赶紧保存。继续写程序不到半个小时,机器人再次罢工。我又以为自己把刚才修好的bug又触发了。再赶紧回头改。如此,在“我操(四声)”和“我操(二声)”中不断往复。调bug大家都懂的,吃饭睡觉都得尽量避免,必须得通宵才有感觉。当折腾到第三天我人都快熬死了的时候,做硬件的师兄过来发现,有块电容他忘了接地了。。。于是电容充满电,机器人就罢工。断电呆半个小时,等这块儿质量不怎么好的电容放干净电,就可以继续正常调试了。。。
做科研用Theano在GPU上编程。没法debug,出现运行时错误(如矩阵相乘纬度不匹配)还好解决。但是出现了逻辑错误就苦逼了:"到底是我的想法有错误?还是我的代码有错误?"总结:最难改的bug不是你不知道怎么改,也不是你找不到bug,而是在你不知道应该得到什么结果时根本就不知道程序有没有bug!
我来个经历过的神奇bug一个嵌入式设备,没有操作系统,支持tcp协议,有过几百个实施案例。在某用户那里上线后发现网络死活不通。用一个双网卡的linux做网桥,接在嵌入式设备前做tcpdump分析。在嵌入式设备上现场编程烧入,用各个不同颜色的灯调试,最后发现问题:嵌入式设备的arp表只有五个entry,每收到一个数据包就把这个数据包的mac地址和ip地址更新到arp表中。这个用户是与互联网隔离的,所有人电脑上的搜狗输入法连不到搜狗的某个服务器上,就全内网发广播包,结果把嵌入式设备里的网关的arp entry给冲掉了。知道了原因,解决方案就简单了,判断一下收到的数据包,目的ip不是自己就不更新arp表就好。
免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。
责任编辑:
声明:本文由入驻搜狐号的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
今日搜狐热点2014年10月 C/C++大版内专家分月排行榜第三2014年4月 C/C++大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。今年十月份,我曾发布一篇文章《》,不过那个BUG在最新的 Chrome 54 中已经修正。
而今天即将发布的Chrome弱智BUG:
仅 Chrome 53 - Chrome 55(发布的)中存在问题
国内双核浏览器&Chrome 45 中没有问题
Firefox,Edge,IE11-IE8浏览器中都没有问题
最近在和客户沟通中,发现一个奇怪问题:
1. 页面中存在一个选项卡控件,选项卡里面是IFrame,页面初始显示时有纵向滚动条出现
2. 来回切换选项卡一次,原来选项卡页面的滚动条居然消失了!!
3. 奇怪的时,此时在选项卡页面内滑动鼠标滚轮,还是能够上下滚动页面的
页面打开时的样子:
来回切换一次选项卡后的样子:
奇怪的是,此时鼠标滚动还能上下滚动页面:
当然首先怀疑的就是自己写的代码问题,但是查了一遍居然毫无头绪。在此期间我们还发现如下问题:
1. FineUIPro从最新版v3.3,到之前v3.2,v3.1,v3.0.... 无一例外都有这个问题。这就有点不可思议了,我们开源版有 1300 多位捐赠用户,专业版有 100 多个企业客户,如此明显的一个BUG不可能这么多版本都没有被发现!!
假设之前的版本根本就没有这个问题,那么就是浏览器版本升级引入的BUG了。
2. 在Firefox,Edge,IE11,IE10,IE9,IE8下测试都没有这个问题,只有Chrome下才出现问题!!
由于,我们不得不怀疑是新版 Chrome 引入的BUG,为了验证这个想法,我们需要一个非常简单的可重现例子。
由于FineUIPro本身的客户端代码还是很复杂了,为了避免其他代码的影响,我们需要一个可重现的简单的例子:
&!DOCTYPE html&
&meta http-equiv="Content-Type" content="text/ charset=utf-8" /&
&input type="button" value="页面二" onclick="document.getElementById('frame1').style.display = 'block'; document.getElementById('frame2').style.display = 'none';" /&
&input type="button" value="页面三" onclick="document.getElementById('frame1').style.display = 'none'; document.getElementById('frame2').style.display = 'block';" /&
&div style="border:solid 1width:400height:200"&
&iframe id="frame1" style="width:100%;height:100%;border:" src="./page2.html"&&/iframe&
&iframe id="frame2" style="width:100%;height:100%;border:display:" src="./page3.html"&&/iframe&
这个页面代码非常简单,两个按钮,两个IFrame,默认显示第一个IFrame,通过按钮来切换两个IFrame的显示。
&!DOCTYPE html&
&meta http-equiv="Content-Type" content="text/ charset=utf-8" /&
&!DOCTYPE html&
&meta http-equiv="Content-Type" content="text/ charset=utf-8" /&
&br /&&br /&&br /&&br /&&br /&&br /&&br /&&br /&&br /&&br /&
&br /&&br /&&br /&&br /&&br /&&br /&&br /&&br /&&br /&&br /&
&br /&&br /&&br /&&br /&&br /&&br /&&br /&&br /&&br /&&br /&
&br /&&br /&&br /&&br /&&br /&&br /&&br /&&br /&&br /&&br /&
下面分别在不同浏览器下运行效果:
Chrome&55.0.2883.75
FireFox 50.0.2
毫无疑问,这个是Chrome的BUG,那么到底是从哪个版本开始才出现的呢,这个就不好追踪。
我们也没有那么多精力把每个Chrome版本都测试下,所以就安装了两款国内的双核浏览器,分别用Chrome内核测试:
第一款产品是 360安全浏览器,极速模式下 Chrome 版本是 45,比较老,正好用来测试:
哈哈,看来 Chrome v45 还没有这个BUG,这就好办,说明这个BUG是Chrome新版才引入的!!
第二款产品是 QQ 浏览器,Chrome内核是 53
看来 Chrome 53 版本已经引入了这个BUG。
所以我们可以大致把引入这个BUG的Chrome版本限定在 v53 - v55(这个是 才发布的)。
既然那么多Chrome版本都存在这个问题,要么是Google开发人员没发现,要么是不想修正了。
这里也顺便吐槽一下Chrome:虽然Chrome的运行速度最快,开发工具也非常方便,但是长期坚持在JavaScript编码第一线,居然发现了好多个仅在Chrome下出现的问题,让人恍惚有点IE6的感觉。仅仅是在 FineUIPro 就有好几处是 Chrome Only 的代码,有空我会再分享几个出来。
不管Google怎么办,这个问题还是要解决,又要是 Chrome Only 的代码了,哎!
1. 首先怀疑是 iframe 的 width:100% 和 height:100% 搞的鬼
由于代码结构太简单,没有多少让人怀疑的地方,就先把这个宽度和高度改为固定值试下:
&!DOCTYPE html&
&meta http-equiv="Content-Type" content="text/ charset=utf-8" /&
&input type="button" value="页面二" onclick="document.getElementById('frame1').style.display = 'block'; document.getElementById('frame2').style.display = 'none';" /&
&input type="button" value="页面三" onclick="document.getElementById('frame1').style.display = 'none'; document.getElementById('frame2').style.display = 'block';" /&
&div style="border:solid 1width:400height:200"&
&iframe id="frame1" style="width:400height:200border:" src="./page2.html"&&/iframe&
&iframe id="frame2" style="width:400height:200border:display:" src="./page3.html"&&/iframe&
运行一下,问题依旧!
这时如果用Chrome调试工具查看,发现滚动条的位置还在,只是不显示:
2. 之前遇到类似的问题,我们可以强制浏览器重新渲染
网络上早已有相应的解决版本:
&!DOCTYPE html&
&meta http-equiv="Content-Type" content="text/ charset=utf-8" /&
function fixSize() {
var container1 = document.getElementById('container1');
container1.style.overflow = 'hidden';
container1.scrollW
container1.style.overflow = 'auto';
&input type="button" value="页面二" onclick="document.getElementById('frame1').style.display = 'block'; document.getElementById('frame2').style.display = 'none'; fixSize();" /&
&input type="button" value="页面三" onclick="document.getElementById('frame1').style.display = 'none'; document.getElementById('frame2').style.display = 'block'; fixSize();" /&
&div style="border:solid 1width:400height:200" id="container1"&
&iframe id="frame1" style="width:400height:200border:" src="./page2.html"&&/iframe&
&iframe id="frame2" style="width:400height:200border:display:" src="./page3.html"&&/iframe&
运行,问题依旧!
怪了,这个强制Chrome重新渲染的代码之前验证过的,这次居然也不行了。
郁闷中。。。。。先出去散步。。。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
散步中。。。。
3. 散步回来,觉得还是应该从强制Chrome渲染入手,这次我们来改变高度
&!DOCTYPE html&
&meta http-equiv="Content-Type" content="text/ charset=utf-8" /&
function fixSize() {
var container1 = document.getElementById('container1');
container1.style.height = '199px';
container1.scrollW
container1.style.height = '200px';
&input type="button" value="页面二" onclick="document.getElementById('frame1').style.display = 'block'; document.getElementById('frame2').style.display = 'none'; fixSize();" /&
&input type="button" value="页面三" onclick="document.getElementById('frame1').style.display = 'none'; document.getElementById('frame2').style.display = 'block'; fixSize();" /&
&div style="border:solid 1width:400height:200" id="container1"&
&iframe id="frame1" style="width:100%;height:100%;border:" src="./page2.html"&&/iframe&
&iframe id="frame2" style="width:100%;height:100%;border:display:" src="./page3.html"&&/iframe&
帅呆了,这次居然可以了!!!现在Chrome 55下能正常运行了。
4. 优化一下,可以改变iframe的高度,而不是外部容器的高度,这样就不用硬编码了,代码更通用
&!DOCTYPE html&
&meta http-equiv="Content-Type" content="text/ charset=utf-8" /&
function fixSize(iframeId) {
var iframe = document.getElementById(iframeId);
iframe.style.height = '99%';
iframe.scrollW
iframe.style.height = '100%';
&input type="button" value="页面二" onclick="document.getElementById('frame1').style.display = 'block'; document.getElementById('frame2').style.display = 'none'; fixSize('frame1');" /&
&input type="button" value="页面三" onclick="document.getElementById('frame1').style.display = 'none'; document.getElementById('frame2').style.display = 'block'; fixSize('frame2');" /&
&div style="border:solid 1width:400height:200" id="container1"&
&iframe id="frame1" style="width:100%;height:100%;border:" src="./page2.html"&&/iframe&
&iframe id="frame2" style="width:100%;height:100%;border:display:" src="./page3.html"&&/iframe&
这样也行,也算是解决了这个Chrome Only的BUG!!
每次给老婆说起这样的稀奇古怪事,老婆都会嘲笑我是代码泥瓦匠,只能从外部修修补补。不过能修补上也算是阿弥陀佛了。
谁让咱一直坚持在代码一线呢。
页面一(原始页面,Chrome下存在BUG):
页面四(仍然有问题):
页面五(仍然有问题):
页面六(修正了Chrome下的问题):
页面七(修正了Chrome下的问题):
阅读(...) 评论()

我要回帖

更多关于 全民枪战所有bug视频 的文章

 

随机推荐