linux踩内存内存越界,云风的 BLOG

Comments

sprintf_s

Posted by:

Anonymous | (38)

December 29, 2014 01:14 PM

我都是用snprintf

Posted by:

cc | (37)

July 15, 2014 02:42 PM

没看出来和\0有什么关系。

倒是觉得data[sz-1]为负数时,sprintf会写buffer+(sz-1)*2+3 = buffer+2*sz+1才造成的越界。

Posted by:

十年草木 | (36)

April 2, 2014 09:35 PM

应该使用SNPRINTF,STRNCPY这类的函数会稳妥些吧,强烈建议博主能分享下debug的知识,或者推荐相关的blog。

Posted by:

simon | (35)

March 4, 2014 01:17 PM

正好 在用这个,忽然想起来 这篇博客,真的是用起来 才知道 是要这样

Posted by:

ChinaHome | (34)

February 20, 2014 06:21 PM

难道不是%02hhx么?

Posted by:

asdfg | (33)

February 20, 2014 04:20 PM

测试时没有越界不代表测试数据没有负数,而很可能测试数据最后几位不是负数而已,要越界只有碰巧最后几位字符是负数才行,前面的字符有负数只是得不到正确的结果而已。

Posted by:

观雨 | (32)

February 8, 2014 02:41 PM

printf 中的 field length 经常被误用,应该重写一个用来表示最大长度的directive,这样会让错误检查所消耗的时间减少。

Posted by:

marmot | (31)

February 7, 2014 10:26 PM

我们会统一规定所有字节流基本类型为 uint8_t, 这样遇到类似这种 default argument promotions / integer promotions时也能够稍微简单一些。

Posted by:

marmot | (30)

February 5, 2014 09:30 PM

生成字符串转换的坑实在太多。

Posted by:

anthony | (29)

January 22, 2014 12:24 PM

string +=的效率是ostringstream<

这里用 sprintf 感觉效率不高,还不如直接四位一组直接算呢。

Posted by:

cyberscorpio | (27)

January 14, 2014 01:49 AM

一开始怀疑jemalloc里出了问题,后来证实还是自己的代码出了问题。

Posted by:

Liigo | (26)

January 11, 2014 06:09 PM

这里要注意下,以免自己也被坑。

vc下也会这样。

char buf[10] = {0};

sprintf(buf,"%02x",-3);

printf("%s\r\n",buf);

输出:fffffffd

char buf[10] = {0};

sprintf(buf,"%02x",(unsigned char)-3);

printf("%s\r\n",buf);

输出:fd

Posted by:

yanbin | (24)

January 9, 2014 08:17 PM

这种打印16进制,我一般自己写个宏来转换

Posted by:

starshine | (23)

January 8, 2014 11:36 AM

@chengli

刚刚翻了下the c programming language

确实除了%d %i和实数,其他格式化输出都是unsigned

Posted by:

Julius | (22)

January 8, 2014 09:53 AM

@chengli

嗯,奇怪的是我实测居然没有负号...所以我怀疑是不是我的g++抽搐了

Posted by:

Julius | (21)

January 8, 2014 09:42 AM

晓靖同学跪键盘去。。。

Posted by:

Smite | (20)

January 8, 2014 12:05 AM

why not snprintf?

Posted by:

jacky | (19)

January 7, 2014 11:01 PM

alloc分配的堆上面的内存

pathp 指针变成了 NULL 局部变量是在栈上的。 堆区踩内存踩到了栈上么?不懂

Posted by:

yang | (18)

January 7, 2014 11:44 AM

@ Julius

应该是8个字符,跟负号,'\0'什么的没关系。‘%02d’只是说宽度最小为2

Posted by:

chengli | (17)

January 7, 2014 10:51 AM

确实很隐晦的bug

"%02x"在负数char时,输出8个字符,而不是带负号的3个字符

不知是否是我用的g++缘故

Posted by:

Julius | (16)

January 7, 2014 10:36 AM

mark下,这个bug确实很容易蒙人。

@hedengcheng

kern.log 和 dmesg 里有 log

Posted by:

Cloud | (14)

January 7, 2014 09:37 AM

哈哈,点名批评的意思啊,mark警示下

Posted by:

johnzz | (13)

January 7, 2014 09:10 AM

引用:我们上周发现有玩家客户端发过来的数据包解包失败,但不知道原因

我们前段时间也遇到了这个问题,后面根据大量的数据分析,揣测应该是有用户在网络层拦截了CS的包,串改了data 导致和协议结构造成差异 无法解析 对于这样的情况,我们在data第一字段增加包验证信息 可以fix 但是我们最终采取的是验证 客户端的包实际长度和拼包时长度进行验证 只能保证部分被篡改的可能 毕竟他将流中的0修改为1 是可以解析过的,错误让上层逻辑抛出。

Posted by:

injur | (12)

January 7, 2014 08:56 AM

我们上周发现有玩家客户端发过来的数据包解包失败,但不知道原因

我们前段时间也遇到了这个问题,后面根据大量的数据分析,揣测应该是有用户在网络层拦截了CS的包,串改了date 导致和协议结构造成差异 无法解析 对于这样的情况,我们在data第一字段增加包验证信息 可以fix

Posted by:

injur | (11)

January 7, 2014 08:51 AM

也就是最后一个字符是负数的时候 就越界了 超过两个字符 把尾部得0覆盖掉了 所以问题就来了

在java里所有数值类型都是有符号的(char除外), 所以这坑已经铭记于心, 一眼就看出这个问题了...不过java是肯定无法越界的(Unsafe类除外),查bug比C/C++方便太多

sprintf(buffer+i*2, "%02x", (unsigned char)data[i]);

Posted by:

xx | (8)

January 6, 2014 09:01 PM

@Fenng

你不算结束的 \0 么?

Posted by:

Cloud | (7)

January 6, 2014 08:53 PM

第一次崩溃发生在周六凌晨 1:00 左右,没有收集到 core 文件,只有事故现场的寄存器的值。通过 EIP 寄存器最终定位到是在内存分配器中出的错。

我对这个是怎么做的,比较好奇,云风能不能分享下?程序都崩溃了,如何查询寄存器的值?如何根据寄存器的值定位程序出错的调用栈?

@Feng云风的原意是%02x不一定是2个字节,可能是带负号的3个字节。 :D

最后一句话,为什么是输出3个字节?sprintf(buffer+i*2, "%02x", data[i]);每次是格式化2个字节啊!

Posted by:

Fenng | (4)

January 6, 2014 06:56 PM

所以说,sprintf被认为是这样的高危函数,也是有一定的道理的。容易溢出。

这就是不可靠类型的代价

Posted by:

lichking | (2)

January 6, 2014 06:18 PM

还是 golang 可靠。

Posted by:

RVoid | (1)

January 6, 2014 06:03 PM

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值