通常,调试比编码的时间长。
好的编码习惯可以减少bug发生,从而节省时间。
即使是赶时间,也不能偷工减料。基本的编程规范还是要遵守的!
下面是一个教训:
我在调试一个简单的程序时,由于在第一个版本上加了一点点东西,
结果
遇到一个奇怪的段错误:在 main 函数 return 0; 时发生段错误。
通常段错误发生时,查看堆栈可知具体的位置。而这次,提示似乎不明显
-
Program received signal SIGSEGV, Segmentation fault.
-
0xb6bcffdc in ?? () from /lib/arm-linux-gnueabihf/libc.so.6
-
(gdb) bt
-
#0 0xb6bcffdc in ?? () from /lib/arm-linux-gnueabihf/libc.so.6
-
#1 0x0000a498 in main (
-
argc=<error reading variable: Cannot access memory at address 0x67344569>, argv=<error reading variable: Cannot access memory at address 0x67344565>)
-
at main.c:476
-
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
-
(gdb)
奇怪,main 函数执行完,却出错了。
显然问题就出在 main 中,就是新添加的那一点点东西引来的。
加了什么东西呢? 上代码前,先交待下背景。
我写了一个访问某IM平台用户注册(RESTfull)的接口验证程序。
编码分2步:
编码实现 http 请求,调用用户注册接口。
添加注册回调函数,用于获取结果。
相关代码如下
-
// 在回调函数中解析并保存结果
-
int imcb_regClient(cJSON *resp, void *puser)
-
{
-
// ...
-
if (puser)
-
{
-
strcpy(puser, cJSON_GetStringItem(cli, "loginToken"));
-
}
-
return 0;
-
}
-
-
int main(int argc, char *argv[])
-
{
-
// ...
-
// 设置用户注册回调函数
-
char loginToken[128] = {0};
-
imctx.rest_cb.pfun = imcb_regClient;
-
imctx.rest_cb.puser = loginToken;
-
// 执行注册操作
-
ret = regClient(&imctx, uid, friendlyName, mobile);
-
if (ret == 0)
-
{
-
// 打印结果
-
printf("regClient => loginToken=%s\n", loginToken);
-
}
-
// ...
-
return 0;
-
}
第一步很顺利。第二步添加 rest_cb 后发生段错误。
同学,你能找出 bug 吗?
TIP:
很明显,段错误发生在 main 中,并且是由新添加的代码引起的!
前几天写一一篇“编译器的惩罚:warning-to-crash”,今天又遇到一个“没道理啊”错误。
每次遇到这种有意思的bug,我都会先想一想,然后叫jim同学来瞧一瞧看一看。
什么,他在忙,抽不开身 -- 好吧,他大概是看惯我们这些低级bug了。
好吧,我再想一想。
哈哈,灵光一闪,想到了。
常量 [128] ! 这家伙嫌疑最大。
看看打印出的 loginToken 值,177字节!
锁定罪犯 -- 就是说你啊,C语言菜鸟!
别不接受菜鸟这个称呼,当你随意使用常量时你有想过数组会越界吗?
嗯,有想过,但这只是一个简单的测试程序,所以没在意。
狡辩!如果你是老鸟,会连这个常识都没有吗!
好吧,你赶时间。
我也赶时间,所以抓紧时间补漏:
-
#define MAX_USER_DATA 256
-
-
char loginToken[MAX_USER_DATA] = {0};
-
-
// 在回调函数中解析并保存结果
-
int imcb_regClient(cJSON *resp, void *puser)
-
{
-
// ...
-
if (puser)
-
{
-
//strcpy(puser, cJSON_GetStringItem(cli, "loginToken"));
-
strncpy(puser, MAX_USER_DATA, cJSON_GetStringItem(cli, "loginToken"));
-
}
-
return 0;
-
}
阅读(2704) | 评论(0) | 转发(0) |