如何在 C 运行时获取哪些有问题的源代码和行?

问题描述

我正在使用这个 codeuthash(在 ubuntu 中使用 uthash-dev

// uthash.c
#include <string.h>  /* strcpy */
#include <stdlib.h>  /* malloc */
#include <stdio.h>   /* printf */
#include "uthash.h"

const int MAX_DATA = 1230000;

struct kv {
    char *key;
    double val;
    UT_hash_handle hh;
};

char i2ch[] = {'0','1','2','3','4','5','6','7','8','9','a','B','c','D','e','F'};

int get_first_digit(double d) {
    while(d > 10) {
        d /= 10;
    }
    return (int)(d);
}
char* to_rhex(int v) {
    char* hex = malloc(sizeof(char)*9); // because INT_MAX can be divided by 16 maximum 8 times
    memset(hex,9);
    int ctr = 0;
    do {
        hex[ctr++] = i2ch[v%16];
        v /= 16;
    } while(v > 0);
    return hex;
}

char* to_str(int v) {
    int len = snprintf(NULL,"%d",v);
    char *res = malloc(len+1);
    snprintf(res,len+1,v);  
    return res;
}

int set_or_inc(struct kv** m,char* key,int set,int inc,int *ctr) {
    struct kv* item = 0;
    HASH_FIND_STR(*m,key,item);
    if(!item) {
        item = malloc(sizeof(*item));
        item->key = key;
        item->val = (double)(set);
        HASH_ADD_KEYPTR(hh,*m,item->key,strlen(item->key),item) ;
        return 0;
    } else {
        item->val += (double)(inc);
        *ctr += 1;
        return 1; // key not used
    }
}
int main() {
    struct kv *m = NULL;
    int dup1 =0,dup2 =0,dup3 =0;
    for(int z = MAX_DATA; z > 0; z--) {
        int val2 = MAX_DATA - z;
        int val3 = MAX_DATA*2 - z;
        char *key1 = to_str(z);
        char *key2 = to_str(val2);
        char *key3 = to_rhex(val3);
        if(set_or_inc(&m,key1,z,val2,&dup1)) free(key1);
        if(set_or_inc(&m,key2,val3,&dup2)) free(key2);
        if(set_or_inc(&m,key3,&dup3)) free(key3);
    }
    printf("%d %d %d\n",dup1,dup2,dup3);
    int total = 0,verify = 0,count = 0;
    struct kv *tmp,*item;
    HASH_ITER(hh,m,item,tmp) {
        total += get_first_digit(item->val);
        verify += strlen(item->key);
        count += 1;
        HASH_DEL(m,item);
        free(item->key);
        free(item);
    }
    printf("%d %d %d\n",total,verify,count);
}

当使用带有边界检查的 tcc 时:

time tcc -b -g -run uthash.c
bcheck.c __bound_ptr_indir8: 0x7fff3cd67ec8 is outside of the region
Runtime error: dereferencing invalid pointer
at 0x5626cfebe9b5 set_or_inc()
by 0x5626cfec15e9 main()
Command exited with non-zero status 255

CPU: 0.00s      Real: 0.00s     RAM: 3480KB

直接运行(用valgrind -s --track-origins=yes --keep-stacktraces=alloc-and-free检查没有问题):

time tcc -run uthash.c
637912 641149 67002
3808703 14182513 2343937
Command exited with non-zero status 25

CPU: 2.52s      Real: 2.60s     RAM: 292144KB

使用 gcc 时(使用 -fstack-protector-all 标志时也没有运行时错误):

gcc uthash.c && time ./a.out
637912 641149 67002
3808703 14182513 2343937

CPU: 2.47s      Real: 2.57s     RAM: 290492KB

使用 clang 时(使用 -fsanitize=address 标志时也没有运行时错误):

clang uthash.c && time ./a.out
637912 641149 67002
3808703 14182513 2343937

CPU: 2.50s      Real: 2.59s     RAM: 290448KB

只有在使用 tcc 时才在运行时显示错误,我怎么知道是哪个行号造成的?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)