Posts

Showing posts from January, 2024

如何快速调试并找到在std::thread子线程中抛出的C++异常问题!

Image
C++11标准库新增的std::thread类可以方便地开启子线程。然而有个奇怪的现象是,如果在这些子线程中抛出了未处理的C++异常而导致程序崩溃,那么在生成的dump文件中将还原不出异常发生时的调用栈。可以通过下面的方法来展示这个现象。 首先使用以下代码生成一个控制台程序: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # include <thread> # include <vector> std::thread* g_thread; void ThreadEntry () { std::vector< int > v; v. at ( 0 ); } int main () { g_thread = new std:: thread (ThreadEntry); g_thread-> join (); } 这段代码很简单,就是通过std::thread创建一个子线程,并且在这个子线程中访问一个空的std::vector中的元素,让它抛出C++异常。务必要使用Release配置来生成程序,不能使用Debug配置。 接下来,在资源管理器中直接运行该程序,注意不要通过调试器来运行。一般会在第二次运行的时候,出现下面的Windows错误报告窗口: 在详细信息中的C:\Users\Zplutor\AppData\Local\Temp\WERBF98.tmp.mdmp文件即是Windows错误报告为崩溃的程序生成的dump文件,里面包含了程序崩溃时的一些信息,例如函数调用栈。该文件在关闭了错误报告窗口时即被删除,所以要先把这个文件复制出来。 最后,用WinDbg打开这个dump文件,先用.ecxr命令切换到异常环境,再用k命令显示调用栈,结果显示如下: 1 2 3 4 5 6 7 8 9 10 11 0:002> k *** Stack trace for last set context - .thread/.cxr resets it ChildEBP RetAddr 0095f07c 6ba8dc5f msvcr120!abort+0x38 [f:\dd\vctools\crt\crtw32\misc\abort.c @ 90] 009

net.ipv4.ip_local_port_range 的值究竟影响了啥,和UDP connect之间的关系是什么?

前言 网上关于  net.ipv4.ip_local_port_range  的值的效果众说纷纭(下面所说的连接都假定使用的是相同的协议(都是 TCP 或 UDP)): 大部分文章都说这个值决定了客户端的一个 ip 可用的端口数量,即一个 ip 最多只能创建 60K 多一点的连接(1025-65535),如果要突破这个限制需要客户端机器绑定多个 ip。 还有部分文章说的是这个值决定的是 socket 四元组中的本地端口数量,即一个 ip 对同一个目标 ip+port 最多可以创建 60K 多一点连接,只要目标 ip 或端口不一样就可以使用相同的本地端口,不一定需要多个客户端 ip 就可以突破端口数量限制。 文档  中的介绍也很模糊: ip_local_port_range - 2 INTEGERS Defines the local port range that is used by TCP and UDP to choose the local port. The first number is the first, the second the last local port number. If possible, it is better these numbers have different parity. (one even and one odd values) The default values are 32768 and 60999 respectively. 下面就通过TCP来做一些实验来确认这个选项的实际效果。 实验环境: $ uname -a Linux vagrant 4.15.0-29-generic #31-Ubuntu SMP Tue Jul 17 15:39:52 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux 相同目标 ip 和相同目标端口下的端口数量限制 先设置 ip_local_port_range 的值为非常小的范围: $ echo "61000 61001" | sudo tee /proc/sys/net/ipv4/ip_local_port_range 61000 61001 $ cat /proc/sys/ne