dazuiniu's blog

cat /dev/dazuiniu/random

Archive for the ‘bug’ tag

my drizzle storage engine silly bug

View Comments

dazuiniu is trying to write a simple plugin for drizzle, while dazuiniu always gets an error of 138 when it tries to create a table on the database. After some efforts, dazuiniu find that dazuiniu initializes the storage engine to a temporary only one, while dazuiniu created the table without specifying the ‘temporary’ syntax. To show you a little bit: here’s my initialization part:

: drizzled::plugin::StorageEngine(name_arg,
                                  HTON_TEMPORARY_ONLY | // the bug

while on the other part, the file(drizzled/plugin/storage_engine.cc) calling the plugin has the code below:

else if (table_message.type() != message::Table::TEMPORARY &&
     share.storage_engine->check_flag(HTON_BIT_TEMPORARY_ONLY) == true)
{
    error= HA_ERR_UNSUPPORTED;
}

So you can see, no matter dazuiniu got the error…

Written by dazuiniu

June 15th, 2010 at 1:37 pm

Posted in bugs

Tagged with , ,

cout的出错

View Comments

看到 Vimer 的博客上有讲到一个有趣的 bug [1],确实是以前没有注意到的问题,很有收获。希望 Vimer 博客能再接再厉,继续写出这么优秀的文章来,特别是这种类型的文章 :-)

光看呢,还不够,大嘴牛要试着去重现这个问题,从该文的截图来看,输出到终端获得了 EPIPE 的错误信息,从而使得无法正确输出。有理由相信,这几行的片段都在一个循环里面,每次的输出的时候都会重定向标准输出的文件描述符,这个重定向可能是程序员手动做的,也可能是 CGI 框架所包含的内容。

怎么才能重现 cout 的这种一次出错之后,如果不清空 cout,那么以后的输出都会有问题的这个 bug 呢?看看大嘴牛攒出来的这个小程序,从里面输出的字符串应该可以猜出来整个流程。

#include <iostream>
using namespace std;

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int ac, char **av)
{
const char *file = "test.out";
if (ac == 2)
file = av[1];

int stdout_backup = dup(1);
int fd = open(file, O_RDWR | O_CREAT, 0644);
if (fd < 0)
{
cerr << "error opening file " << file << endl;
return -1;
}

dup2(fd, 1);
cout << "this string goes to the file." << endl;

// close the fd
close(1);
close(fd);
cout << "this would be an error." << endl;

dup2(stdout_backup, 1);
cout << "this would have gone to stdout, but due to the previous error, it fails." << endl;

cout.clear();
cout << "trying to write to stdout again. Hey! Hello Stdout Again!" << endl;

return 0;
}

cout 在被关闭文件描述符之后发生了错误,随后即使该标准输出已经被恢复,cout 仍然无法正常输出,直到大嘴牛重新清空 cout 流之后。

那么 printf 是怎么样子的呢?看看下面的程序。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int ac, char **av)
{
const char *file = "test.out";
if (ac == 2)
file = av[1];

int stdout_backup = dup(1);
int fd = open(file, O_RDWR | O_CREAT, 0644);
if (fd < 0)
{
printf("error opening file\n");
return -1;
}

if (dup2(fd, 1) < 0)
fprintf(stderr, "error dup");
printf("this string goes to the file.\n");
fflush(stdout);   /* <--- */

// close the fd
close(1);
close(fd);
printf("this would be an error.\n");
fflush(stdout);   /* <--- */

dup2(stdout_backup, 1);
printf("printf is different with cout, it succeeds here.\n");
fflush(stdout);   /* <--- */

return 0;
}

可以看到,当标准被关闭之后,随后的输出出现了问题,但是只要该文件描述符之后又好了,那么 printf 即又可以正常工作了。这里需要注意的一点是 fflush 的公用,如果没有这里的强制 flush,那么 printf 会放到 buffer 里面,当然前面可以加 setbuf 告诉他不要缓冲。

很有意思,大嘴牛可以重现这个问题,但是至于原文中为什么会出现这样的问题,Dante 说到有可能是底层库的问题,这个大嘴牛不敢妄言了,估计只有真正遇到了这么诡异的问题才可能知道了。呵呵

[1]. http://www.vimer.cn/2010/06/qq%E9%A4%90%E5%8E%85%E5%85%AC%E6%B5%8B%EF%BC%8C%E5%85%A5%E5%8F%A3cgi%E7%9A%84%E4%B8%80%E4%B8%AAbug%E5%AE%9A%E4%BD%8D.html

Written by dazuiniu

June 14th, 2010 at 6:39 pm

Posted in all about dev

Tagged with , , ,

软件依赖性

View Comments

有些开源软件的依赖性暴多无比,有些软件则基本没有什么依赖性。这其中有好处,也有坏处,大嘴牛就来侃侃。

好处有:

  1. 很多功能不需要自己实现,只需要找到实现该功能的软件库即可。
  2. 节约了开发的时间成本,不用自己去 reinvent the wheel。

坏处有:

  1. 对最终用户不友好,安装起来很麻烦,有时候某些平台上的软件版本过低,导致无法正常安装。比如 drizzle 就出现了这样的问题,大嘴牛也遇到了问题[1],下面是人家打包 RPM 时说的话[2]:

    Due to a dependency on boost >= 1.38 drizzle no longer builds on RHEL 5 (boost 1.33) at the moment therefore those repositories haven’t been updated.

  2. 调试复杂,由于增加了依赖性,如果 bug 是发生在被以来的软件之中,那么原来使用该软件的好处就荡然无存了,出路只有两个,要么自己动手进行调试,要么像依赖的软件上报 bug,第二种情况听起来很可行,但是要知道,在开源世界中,可不是你说了最大,遇到一些比较成熟的社区那还好说,如果遇到不通情达理的,那么结果也只有两种,要么等待,漫长的等待,要么人家来一句“This’s not a bug, it’s a feature”[3][4][5]。不把你噎死才怪。
  3. 使用别人的软件有风险,首先需要熟悉人家的文档以及 API,另外也需要祈祷人家的 API 没有很 tricky 的东西才行,否则怎么死的都不知道。

说了一些,好像又没说什么。呵呵

[1]. http://www.dazuiniu.com/blog/2010/06/04/install-boost-trunk-version.html

[2]. https://lists.launchpad.net/drizzle-discuss/msg06747.html

[3]. http://en.wikipedia.org/wiki/Undocumented_feature

[4]. http://en.wikipedia.org/wiki/Computer_bug

[5]. http://www.codinghorror.com/blog/2008/11/thats-not-a-bug-its-a-feature-request.html

Written by dazuiniu

June 10th, 2010 at 2:26 pm

Posted in ramblings

Tagged with , , , ,