网站建设 长沙,如何做好区县外宣网站建设,旅游wordpress,创建网站的目的是什么根据排查软件异常问题的经历和经验#xff0c;简单的总结一下软件异常的场景和原因#xff0c;以供参考。
1、野指针问题 可能是指针没初始化就使用。也有可能是指针指向的内存已经被释放#xff0c;但是指针没置为NULL#xff0c;一旦访问这样的指针就会出问题。在很多情…根据排查软件异常问题的经历和经验简单的总结一下软件异常的场景和原因以供参考。
1、野指针问题 可能是指针没初始化就使用。也有可能是指针指向的内存已经被释放但是指针没置为NULL一旦访问这样的指针就会出问题。在很多情况包括访问空指针的情况下可能会访问64KB以内的系统禁止访问的NULL指针内存区系统直接将程序终止掉。此处是某个变量没有初始化也有可能某个dll库没初始化就调用库中的接口了。
2、空指针问题 有可能内存已经释放指针已经置为NULL但是后面还是访问了空指针。比如在某个库已经unInitialize之后还调用库中的接口或者库中运行的代码访问了空指针。也有可能是调用接口返回了空指针调用者没有添加指针是否为空判断。
3、堆内存被释放两次 已经释放了但是又调用free或delete释放了一次即释放了两次。对于空指针释放多次也没问题。
4、栈内存被当做堆内存来释放 比如在类的函数中自动释放当前类对象的内存即delete this但是在用类定义的对象时使用的栈内存使用delete释放栈内存就有问题了。
5、内存访问越界 将相邻的内存中的内容破坏了即将相邻的内存中的内容篡改了会出现各种意想不到的问题。比如就会触发访问访问NULL指针内存区的异常、后续内存拷贝因为长度被篡改导致另一个内存越界操作。不管是堆内存越界还是栈内存越界都可能导致异常。最直接的异常可能就是在越界的时候发生内存访问违例。
6、不同编译器对STL的实现不同 例如VS和MinGW在std::string\std::map均是不兼容的。
7、类对象没有初始化就直接访问问题 比如临界区对象没调用初始化接口就直接enter了就会出异常。有可能代码中跳出异常将初始化的代码跳过去。
8、内存泄漏 堆内存未释放。 指针赋值时托管另外一块内存未释放、管理之前的内存。 内存分配器C:malloc、calloc、realloc、freeCnew、delete、new[]、delete[]混用、乱用。
9、系统内存不足 处理方法 1程序中尽量早释放不使用的内存、释放暂时空闲的内存 2减少多余的拷贝 3设置对内存不足的处理方法std::set_new_handler 4使用内存池 5使用虚拟内存 6使用64位系统增加物理内存大小
10、栈溢出 1原因递归过程的局部变量过多、递归深度过大是造成系统栈溢出的原因特别是递归列循环时肯定会发生系统栈溢出。 2处理方法 尾部递归优化 大内存的对象由栈改用堆
11、函数调用约定不一致引起的栈不平衡的问题 比如在给dll库中设置回调函数回调函数没指定调用约定使用VS默认的C调用。但是当dll被C#调用时包含dll的头文件C#中默认使用标准调用。回调函数在C#层实现时被设置为标准调用函数内部负责清理栈但是在dll中调用到回调函数dll认为函数是C调用dll中在调用回调函数时会在函数外部清理栈这样在回调函数被调用后多清理了一次栈这样栈就不平衡了。
12、调用虚函数时的二次寻址 C的虚函数存放在虚函数表中。如果要调用一个类对象的虚函数需要通过类对象首地址得到虚函数表首地址然后根据调用的虚函数名称到虚函数中找到虚函数的地址然后call这个地址。在汇编代码中能看到二次寻址的详细过程。
13、debug和release库混用的问题 可能dll导出接口在dll内部申请的堆内存需要调用者在外部释放。如果该dll是release版本的而调用者是debug版本的这个在调用者释放内存时就会出现异常。因为debug和release下的内存管理是不同的。debug下包含调试信息申请的内存较大。
14、死循环问题 死循环一般会导致系统的CPU占用会比较高。如果是UI主线程则比较好办就是0号线程切换到0号线程然后多go几次查看堆栈是否一样。如果一样可以使用bp设置堆栈中的多个断点看到底死循环发生在哪个函数中。一般是循环体中出现了较大的循环次数导致的或者是循环条件设置有问题一直为TRUE。可以看一下堆栈中的与循环条件相关的局部变量的值从而定位问题。如果是远端传过来的值作为循环次数可能要添加上限保护放置传过来的是异常值。如果是底层的线程可以借助Process Explorer查看一下堆栈找到线程id和堆栈到windbg中切换到目标线程中设置断点判断是否有死循环。也可以直接在windbg中使用!runaway命令查看哪个线程占用CPU较高有必要时可能还要看看是内核态的占用多还是用户态的占用的多。
15、数据类型使用违规引起的问题 比如没有搞清楚某类的约束条件随意使用其接口导致使用违规触发异常。
16、抛出异常后导致部分代码被跳过的问题 类中遇到异常数据抛出异常程序仍在运行但是有部分代码被跳过导致代码逻辑出现异常。比如初始化CTime对象时传入了异常值报出异常。还比如新人对stl中的vetctor等类对象执行了memset的操作破坏了stl内部的结构数据导致stl内部产生异常。当然还有一种场景直接抵CString进行memset操作破坏了类中的维护结构的数据一般都会触发异常。一般memset是对结构体操作的但如果结构体中包含非基本数据类型比如类对象就要注意了只能在构造函数中初始化不能直接进行memset。所以在使用memset时遇到类对象就要注意了。
17、静态、全局对象的创建和释放有先后依赖关系 例如静态对象A和B由系统创建所以无法确定创建先后顺序。但A的构造函数中调用了B对象。
18、共享指针shared_ptr的循环引用 参考[C弱引用智能指针weak_ptr的用处]二(https://blog.csdn.net/qq_43148810/article/details/122540820)
19、多线程存在数据竞争未同步问题 多线程加锁该知识设计很深在这这展开。
20、一个线程维护变量值另外一个线程通过循环去读取 1)问题: 热访问不加延时造成CPU资源占用. 每次循环加入延时容易遗漏变量变化过程任务频繁切换效率低 2处理方法 条件变量事件机制
21、死锁问题排查 VS的“并行堆栈”窗口工具可直接分析 日志等工具 目前用windbg排查关键代码的死锁相对简单因为关键代码段是用户态的对象。 如果是内核对象的锁则需要进行内核态的调试不过内核态的调试比较复杂。
如有错误或不足欢迎评论指出创作不易转载请注明出处。如有帮助记得点赞关注哦(⊙o⊙) 更多内容请关注个人博客https://blog.csdn.net/qq_43148810