2020-10-23

记一次内存访问越界的问题查找

开发结束后,测试代码。出现段错误,堆栈全部变成 " ??"了,被冲没了。因为没有堆栈,出问题的代码很难找。心态有点崩了。

后来同事给了一个编译选项 -fsanitize=address-fno-omit-frame-pointer ,在编译的时候加上,堆栈一下子就出现了。
在这里插入图片描述下面这个就是有问题的代码,还是老代码,差点背锅了。代码一眼看过去没啥问题,其实问题出在snprintf的返回值上。
在这里插入图片描述

在这里插入图片描述截图来自百度。

当最后一次往pbuf里写数据时,剩余空间不够了,源字符串被截断,pbuf此时是正常的。但是snprintf这次返回的是源字符串欲写入的长度,不是真实写入的长度。所以下次再去写pbuf的时候,pbuf + uoffset已经越界了,然后ubuflen - uoffset 也成了一个很大的值,内存越界产生了。

AddressSanitizer是google开发一个应用内存检查工具,性能据说比valgrind要好不少,可以配合clang或者GCC编译器使用,GCC需要4.8及以上版本。4.8版本GCC对AddressSanitizer支持有限,功能不太完善,输出的错误信息也不够友好,使用不太方便,建议使用4.9及以上版本。但是我这次使用的是8.3 版本的GCC。详细了解AddressSanitizer信息可以访问其github项目地址:

https://github.com/google/sanitizers/wiki/AddressSanitizer

使用方法很简单,只要在编译程序时加上-fsanitize=address -fno-omit-frame-pointer两个编译选项即可,需要说明的是要使用系统自带的内存管理库,不能使用第三方的内存管理库,因为这个功能要拦截malloc,free等标准函数。gcc几个常用编译选项如下:
-fsanitize=address #开启地址越界检查功能
-fno-omit-frame-pointer #开启后,可以出界更详细的错误信息

可以通过Java中的日期时间类 `LocalDate` 和 `LocalDateTime` 来实现该功能。 首先,我们需要将时间段转换为 `LocalDateTime` 对象,然后将时间部分设置为 00:00:00 或 23:59:59,最后遍历每一天,获取每一天的开始时间和结束时间。 以下是代码示例: ```java import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; public class TimeUtils { public static void main(String[] args) { String startStr = "2020-11-20 09:09:09"; String endStr = "2021-10-09 10:10:10"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime start = LocalDateTime.parse(startStr, formatter); LocalDateTime end = LocalDateTime.parse(endStr, formatter); // 将时间部分设置为 00:00:00 或 23:59:59 LocalDateTime startOfDay = start.with(LocalTime.MIN); LocalDateTime endOfDay = end.with(LocalTime.MAX); // 遍历每一天,获取每一天的开始时间和结束时间 LocalDate startDate = startOfDay.toLocalDate(); LocalDate endDate = endOfDay.toLocalDate(); while (!startDate.isAfter(endDate)) { LocalDateTime startOfDayOfDate = startDate.atStartOfDay(); LocalDateTime endOfDayOfDate = startDate.atTime(LocalTime.MAX); System.out.println("Start time of " + startDate + ": " + startOfDayOfDate); System.out.println("End time of " + startDate + ": " + endOfDayOfDate); startDate = startDate.plusDays(1); } } } ``` 输出结果如下: ``` Start time of 2020-11-20: 2020-11-20T00:00 End time of 2020-11-20: 2020-11-20T23:59:59.999999999 Start time of 2020-11-21: 2020-11-21T00:00 End time of 2020-11-21: 2020-11-21T23:59:59.999999999 ... Start time of 2021-10-09: 2021-10-09T00:00 End time of 2021-10-09: 2021-10-09T23:59:59.999999999 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值