HarryWei / cloudxy

Automatically exported from code.google.com/p/cloudxy
6 stars 3 forks source link

a goto statement error in snapshot api #7

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
bug总述
========
最近在编译一段c程序(一个文件中有很多函数)时,出现了一��
�错误,这个错误是有关c语言中goto语句
的,但是奇怪的是,同一个文件中其他函数中的goto语句没有�
��错误(我把这个报错函数中的
goto语句替换掉,进行了测试,运行正常)。具体如下。

bug测试环境
==========
gcc  version
------------------
jiawei@jiawei-laptop:~/workshop15/snapshot/build$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' 
--with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs 
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared 
--enable-multiarch --enable-linker-build-id --with-system-zlib 
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix 
--with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls 
--enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc 
--enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic 
--enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu 
--target=i486-linux-gnu
Thread model: posix
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) 

os  relevance 
-----------------------
Distributor ID: Ubuntu
Description:    Ubuntu 10.04.3 LTS
Release:    10.04
Codename:   lucid
Linux jiawei-laptop 2.6.32-37-generic #81-Ubuntu SMP Fri Dec 2 20:35:14 UTC 
2011 i686 GNU/Linux
cmake version 2.8.1
- Hide quoted text -

bug复原
========
1, 下载snapshot 分支
svn checkout http://cloudxy.googlecode.com/svn/trunk/  snapshot
2,    编译libhlfs
cd snapshot/build && cmake ../src && make all

这时候就会出现如下错误
jiawei@jiawei-laptop:~/workshop15/snapshot/build$ make all
Makefile:103: 警告:覆盖关于目标“all”的命令
Makefile:69: 警告:忽略关于目标“all”的旧命令
Scanning dependencies of target hlfs
[  3%] Building C object CMakeFiles/hlfs.dir/storage/hlfs_stat.c.o
[  7%] Building C object CMakeFiles/hlfs.dir/storage/hlfs_close.c.o
[ 11%] Building C object CMakeFiles/hlfs.dir/storage/hlfs_read.c.o
[ 15%] Building C object CMakeFiles/hlfs.dir/storage/init_hlfs.c.o
[ 19%] Building C object CMakeFiles/hlfs.dir/storage/deinit_hlfs.c.o
[ 23%] Building C object CMakeFiles/hlfs.dir/storage/hlfs_ctrl.c.o
[ 26%] Building C object CMakeFiles/hlfs.dir/storage/log_write_task.c.o
[ 30%] Building C object CMakeFiles/hlfs.dir/storage/hlfs_open.c.o
[ 34%] Building C object CMakeFiles/hlfs.dir/storage/hlfs_write.c.o
[ 38%] Building C object CMakeFiles/hlfs.dir/common/logger.c.o
[ 42%] Building C object CMakeFiles/hlfs.dir/backend/hdfs_storage.c.o
[ 46%] Building C object CMakeFiles/hlfs.dir/backend/local_storage.c.o
[ 50%] Building C object CMakeFiles/hlfs.dir/clean/clean_route.c.o
[ 53%] Building C object CMakeFiles/hlfs.dir/utils/segment_cleaner.c.o
[ 57%] Building C object CMakeFiles/hlfs.dir/utils/storage_helper.c.o
[ 61%] Building C object CMakeFiles/hlfs.dir/utils/misc.c.o
[ 65%] Building C object CMakeFiles/hlfs.dir/utils/address.c.o
[ 69%] Building C object CMakeFiles/hlfs.dir/snapshot/snapshot_helper.c.o
/home/jiawei/workshop15/snapshot/src/snapshot/snapshot_helper.c: In function 
‘load_all_ss’:
/home/jiawei/workshop15/snapshot/src/snapshot/snapshot_helper.c:144: error: 
jump into scope of identifier with variably modified type
make[3]: *** [CMakeFiles/hlfs.dir/snapshot/snapshot_helper.c.o] 错误 1
make[2]: *** [CMakeFiles/hlfs.dir/all] 错误 2
make[1]: *** [CMakeFiles/all.dir/rule] 错误 2
make: *** [all] 错误 2

bug分析
=========
首先给出部分源码(都在snapshot_helper.c中)
[.....]
int load_all_ss(struct back_storage *storage, GHashTable *ss_hashtable)
{
    int ret = 0;
    int i = 0;
    g_message("%s -- 77 dbg", __func__);
    if (-1 == storage->bs_file_is_exist(storage, SNAPSHOT_FILE)) {
        HLOG_ERROR("snapshot.txt is not exist");
        ret = -1;
        goto out;                // 这里的goto 语句报错,错误信息如上所示    
    }
    bs_file_info_t *file_info = storage->bs_file_info(storage, SNAPSHOT_FILE);
    if (NULL == file_info) {
        HLOG_ERROR("get snapshot info error!");
        ret = -1;
        goto out;
    }
    uint32_t file_size = file_info->size; 
    g_free(file_info);
    HLOG_DEBUG("file_size : %u", file_size);
    char buf[file_size];
    memset(buf, 0, file_size);
    bs_file_t file = storage->bs_file_open(storage, SNAPSHOT_FILE, BS_READONLY);
    if (file == NULL) {
        HLOG_ERROR("open snapshot.txt error");
        ret = -2;
        goto out;
    }
.......
[snip]
........
    g_strfreev(sss);
    storage->bs_file_close(storage, SNAPSHOT_FILE); 
#if 1
out:
    if (NULL != file) {
        storage->bs_file_close(storage, file);
    }
#endif
    return ret;
}
[.....]

当我把如上函数中的所有goto 
语句替换掉(直接return),那么就会一切正常,
但是奇怪的是,snapshot_helper.c文件中还有其他函数,他们中也
有goto
语句,为什么他们没有报错呢?? 
以下给出这个文件中另一个函数的
源码

[.....]
int dump_snapshot_delmark(struct back_storage *storage, const char 
*snapshot_file, \
        const char *ssname){
    if(snapshot_file == NULL || ssname == NULL || storage == NULL){
        return -1;
    }
    int ret = 0;
    int len = 0;
    bs_file_t file = NULL;
    if (-1 == storage->bs_file_is_exist(storage, snapshot_file)) {
        HLOG_DEBUG("cp file not exist, create cp file");
        file = storage->bs_file_create(storage,snapshot_file);
        if (NULL == file) {
            HLOG_ERROR("can not create cp file %s", snapshot_file);
            goto out2;
        }
        storage->bs_file_close(storage, file);
    }
    file = storage->bs_file_open(storage, snapshot_file, BS_WRITEABLE);
    if (NULL == file) {
        HLOG_ERROR("can not open ss file %s", snapshot_file);
        goto out2;
    }
    char snapshot_delmark_text[1024];
    memset(snapshot_delmark_text, 0, 1024);
    len = snapshot_delmark2text(ssname, snapshot_delmark_text);
    HLOG_DEBUG("cp text is %s", snapshot_delmark_text);
    if (len != storage->bs_file_append(storage, file, snapshot_delmark_text, len)) {
        HLOG_ERROR("write cp file error, write bytes %d", ret);
        ret = -1;
        goto out2;
    }
out2:
    if (NULL != file) {
        storage->bs_file_close(storage, file);
    }
    return ret;
}
[.....]

这个函数中也有goto语句,但是当我把load_all_ss函数中的goto语�
��替换掉,编译
一切正常,也就是说 dump_snapshot_delmark 
以及这个文件中的其他函数
中的goto语句都是合法的。

具体snapshot_helper.c的所有源码,可以通过以下链接访问
http://cloudxy.googlecode.com/svn/branches/snapshot/src/snapshot/snapshot_helper
.c

注意执行以上测试步骤可能需要安装一些软件,详见:
http://code.google.com/p/cloudxy/wiki/HlfsUserManual

bug修复
========
这个bug,可以很快的修复,也很简单,只需把相应的load_add_ss
函数中的所有goto语句
都提换掉,那么就不会出现错误了。但是我不清楚这个错误��
�原因,所以希望大家都看
一下,集思广益,搞清楚这个问题的本质。我也google过这个��
�题,有个人和我出现一样的错误
但是,他们讨论的,我没太看懂,给大家参考一下,链接如��
�:
http://objectmix.com/c/251271-error-undefined-behaviour.html

注意:这个bug,我已经按照替换goto语句的方案修复了,如果�
��想复原,只需要把load_all_ss
          函数中相应注视goto语句去掉注视,然后把相应的return语句进行注视即可。

指导人: 陈莉君老师,康华老师
测试人:贾威威
后期负责人:贾威威

Original issue reported on code.google.com by harryxi...@gmail.com on 1 Jan 2012 at 4:09

GoogleCodeExporter commented 9 years ago
这个问题已经解决了,主要原因是,数组初始化使用了变量��
�修复如下:
157     -       char buf[file_size];
158     -       memset(buf, 0, file_size);
159     -       bs_file_t file = storage->bs_file_open(storage, SNAPSHOT_FILE, 
BS_READONLY);
164 +       char *buf = (char *)g_malloc0(sizeof(char) * file_size);
165 +       if (NULL == buf) {
166 +           HLOG_ERROR("Allocate error!");
167 +           ret = -1;
168 +           goto out1;
169 +       }
170 +       bs_file_t file = NULL;
171 +       file = storage->bs_file_open(storage, SNAPSHOT_FILE, BS_READONLY);

同时我也对snapshot_helper.c文件中,资源释进行了fix,详见如下
链接
http://code.google.com/p/cloudxy/source/detail?r=278#

Original comment by harryxi...@gmail.com on 1 Jan 2012 at 6:55