一个很有意思的Bug

这个Bug源于昨天凌晨的一次版本升级失败。睡了一大觉后,下午回到公司,重现了这个问题并找到了原因,发现这的确是一个'很有意思的Bug'。

系统在从数据库初始化过程中遇到了问题:在读取数据库数据时,提示ORA-24373错误。手册上对ORA-24373的解释是这样的:
ORA-24373: invalid length specified for statement
Cause: The length specified for the statement is either 0 or too large.
Action: Specify a valid length for the statement.

从错误的提示来看,不应该是数据的问题,但是出于对自己程序的信任,还是首先比对了数据,结果证明了数据是无误的;

看来一定是代码的问题了。首先定位到了返回错误的那个接口OCIStmtPrepare(原型: sword OCIStmtPrepare(OCIStmt *stmtp, OCIError *errhp, OraText *stmt, ub4 stmt_len, ub4 language, ub4 mode)),可是怎么看这块也不该出问题。但从ORA-24373的Cause来看,似乎是传
给OCIStmtPrepare的值不太对劲儿。

我们从数据库读取数据的一般流程:
1、获取符合某一特定条件的某一类数据的条数count;
2、读取count条数据From DB。

为了达到上面的两个目的,我们执行了两次sql操作,分别由两个语句完成,这里不妨成为sql1和sql2。sql1和sql2的内容是在代码里形成的。

其分为两部分:select的字段list和where条件部分;由于where条件部分是动态的,所以每次sql操作之前都是需要先生成sql1和sql2的。

保守的我们认为sql语句的长度是有限的,在我们的代码里我们用了一个宏XX_SQL_MAX_LEN来定义了一条语句内容的最长值,而XX_SQL_MAX_LEN

在我们的系统中被赋予512这个整数值。这样我们很容易得到如下的定义:
char sql1[XX_SQL_MAX_LEN]; //遗憾的是结尾''也被我们算进了XX_SQL_MAX_LEN中了。
char sql2[XX_SQL_MAX_LEN];

一般sql语句的前端的select字段list是固定的,其长度也就是固定的;但是后面的where语句中的条件则是由参数指定。在我们的系统里这个条件很简单,就只有一个索引值(index)。

让我们意想不到的是在我们要读取的那个数据表的操作语句中,select字段list的长度就超出我们预想,达到了508个字节,要知道目前我们还不知道这一事实。我们按照一般数据库操作流程:先读count,再读数据。结果呢?我们读出了若干条数据,然后就在某一条数据上出现了上述错误。这个数据没有什么特殊的,除了其index的值的位数变成了四位之外。

警觉的我们发现:系统在读取index是三位整数的记录时都是没有问题的,偏偏到index是四位整数时才会有问题,而问题偏偏又出在执行sql1上。直觉告诉我们又是内存问题。

分析如下:
sql1和sql2在栈上紧挨着,是否生成sql2的时候污染了sql1的数据呢?我们试图打印出sql1的值,结果发现printf的输出居然是空,这更坚定了内存遭受破坏的想法。遂掰手指头数sql2的长度,发现其长度居然恰好512字节。我们拿一个栈图来说明问题:


栈图

正如上图中所示:sql2的数据多的沿着数据的延伸方向一直越过了边界来到了sql1的境地,在sql1第一个字节上留下一个''就结束了。这就是为什么sql1打印为空的原因。同样由于传给OCIStmtPrepare的参数stmt_len的值为strlen(sql1),导致stmt_len变为0,也就恰好与ORA-24373这个错误码的说明一致了。这简直太巧了,太不可思议了。不多不少恰好512。

程序员的想当然造就了这一切,就好比千年虫一样,给你我带来麻烦。

从'即将消失的曼谷'说起

昨晚看了央视二套的一则晚间新闻,说的是由于全球变暖、海平面上升,曼谷靠海一侧的很多原先是居民们赖以生存的环境都被汹涌的海水所淹没了,而且据专家预测:按照如此速度发展,20年后泰国首都曼谷将成为水下城市

不知道最近大家是否发现:各大媒体对'全球变暖'这个字样提及甚多,'全球变暖'已经不再是专家们研究的术语了,它已经直接开始影响到我们普通人的生活了。目前世界各国的经济、政治、生活也越来越多与'全球变暖'牵扯到了一起。很多国家开始修改战略,以适应'全球变暖'带来的一系列影响,譬如澳大利亚新总理陆克文一上任就签署了京都议定书。

除了从媒体上看到的新闻、消息之外,我们切身最直接能感受到的就是灾害性天气频发,干旱、洪涝、鼠害、频发的台风等等。今年年初辽宁的灾害性雨雪也或多或少与气候的变化有着联系。放眼全球:南极深层冰川融化、北冰洋冰川融化、西伯利亚永久冻土层开融、北极爱斯基摩人频频葬身冰下,大自然已经向人类发出了明显的警告信号了。如果人类再放纵下去,电影"后天"中的场景就真的离我们真实的生活不远了。

说这些绝非为了宣传"世界末日论",作为地球人类的普通一员,我们应该思考:我们能为减缓'全球变暖'做些什么呢?我能想到的也只有自觉多做公交车,减少私家车的使用,买节能产品了。减缓'全球变暖',保护我们赖以生存的环境是全人类共同面对的任务,作为世界大家庭的基本单元-国家,应该给予自己的国民以指导,这种指导不应该是空泛的口号,而应该是具体的措施。目前我们国家在这方面的确做得不好。各地都是在形式上做做而已,没有具体的措施。更没有投入人力来做这件事情,最本质的就是没有在思想上给予足够的重视。

虽然国家大力倡导环保、节能减排,但我们不得不承认中国人在环境治理、节能减排方面的滞后和措施不力。譬如我们习以为常的"减少白色污染"的口号都喊了N年了,而我们在沃尔玛、家乐福等大超市买东西之后看到的不还是白花花的塑料袋吗?为什么纸袋或布袋不能推广呢?相关部门是否真正的关心这些看起来很细致的事情呢?也许这些事情与政绩没有太大关系才是部分政府官员对之漠视的真正原因。关于如何保护环境的具体行为这点,也许我们的近邻日本值得我们学习。今年央视的"岩松看日本"中有一期节目说的就是日本一个小镇采用的环保措施,建议大家看看人家是如何做的。另外央视新闻频道的康辉到诺基亚的总部芬兰采访时看到的芬兰人的环保意识和方法也是值得我们学习的。

让国民都有一种危机感,这不是一件见不得人的事情。中国的地大物博,资源丰富早已经一去不复返了,相反的污染严重,保护不力才是现在我们老百姓普遍看到的现象。环保、节能、减排,我们完全就可以从大城市做起(大多数人的看法:大城市的人相对受教育程度高,接受新事物、新方法的能力较强),把环保节能减排工作细至每一个社区、细至每一个家庭、细至每一个家庭成员,细至每一个购物袋、细至每一个垃圾袋,细至每一度电、细至每一滴水。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats