可参考
https://sourceware.org/gdb/onlinedocs/gdb/Threads.html
gdb
attach 进程id
info thread
(gdb) info thread
Id Target Id Frame
* 1 Thread 0x7f28dbf76f40 (LWP 2563) "ServerService" 0x00007f28da0ba680 in __GI___nanosleep (
requested_time=requested_time@entry=0x7fff2da728d0, remaining=remaining@entry=0x7fff2da728d0)
at ../sysdeps/unix/sysv/linux/nanosleep.c:28
2 Thread 0x7f28d5123700 (LWP 2615) "ServerService" 0x00007f28da97991e in __libc_recv (fd=6, buf=0x7f28d511b690, len=10240, flags=0)
at ../sysdeps/unix/sysv/linux/recv.c:28
3 Thread 0x7f28d4922700 (LWP 2622) "ServerService" 0x00007f28da9797c7 in __libc_accept (fd=7, addr=..., len=0x7f28d4920f84)
at ../sysdeps/unix/sysv/linux/accept.c:26
4 Thread 0x7f28cffff700 (LWP 2653) "ServerService" 0x00007f28da0ba680 in __GI___nanosleep (
requested_time=requested_time@entry=0x7f28cfffebf0, remaining=remaining@entry=0x0) at ../sysdeps/unix/sysv/linux/nanosleep.c:28
5 Thread 0x7f28cf7fe700 (LWP 2669) "ServerService" 0x00007f28da0ba680 in __GI___nanosleep (
requested_time=requested_time@entry=0x7f28cf7fddc0, remaining=remaining@entry=0x0) at ../sysdeps/unix/sysv/linux/nanosleep.c:28```
*切换线程到线程2看看为何卡住
命令 thread 2
(gdb) thread 2
[Switching to thread 2 (Thread 0x7f28d5123700 (LWP 2615))]
#0 0x00007f28da97991e in __libc_recv (fd=6, buf=0x7f28d511b690, len=10240, flags=0) at ../sysdeps/unix/sysv/linux/recv.c:28
28 ../sysdeps/unix/sysv/linux/recv.c: 没有那个文件或目录.
然后info thread 看线程2 卡住在recv 这里我TCP 接收数据 卡这了
查看堆栈调用
命令 bt
(gdb) info thread
Id Target Id Frame
1 Thread 0x7f28dbf76f40 (LWP 2563) "ServerService" 0x00007f28da0ba680 in __GI___nanosleep (
requested_time=requested_time@entry=0x7fff2da728d0, remaining=remaining@entry=0x7fff2da728d0)
at ../sysdeps/unix/sysv/linux/nanosleep.c:28
* 2 Thread 0x7f28d5123700 (LWP 2615) "ServerService" 0x00007f28da97991e in __libc_recv (fd=6, buf=0x7f28d511b690, len=10240, flags=0)
at ../sysdeps/unix/sysv/linux/recv.c:28
3 Thread 0x7f28d4922700 (LWP 2622) "ServerService" 0x00007f28da9797c7 in __libc_accept (fd=7, addr=..., len=0x7f28d4920f84)
at ../sysdeps/unix/sysv/linux/accept.c:26
4 Thread 0x7f28cffff700 (LWP 2653) "ServerService" 0x00007f28da0ba680 in __GI___nanosleep (
requested_time=requested_time@entry=0x7f28cfffebf0, remaining=remaining@entry=0x0) at ../sysdeps/unix/sysv/linux/nanosleep.c:28
5 Thread 0x7f28cf7fe700 (LWP 2669) "ServerService" 0x00007f28da0ba680 in __GI___nanosleep (
requested_time=requested_time@entry=0x7f28cf7fddc0, remaining=remaining@entry=0x0) at ../sysdeps/unix/sysv/linux/nanosleep.c:28
(gdb) bt
#0 0x00007f28da97991e in __libc_recv (fd=6, buf=0x7f28d511b690, len=10240, flags=0) at ../sysdeps/unix/sysv/linux/recv.c:28
#1 0x000055f0eb0eb716 in ServerThread (lpParameter=0x55f0eb6a7e80) at perfmonitor.cpp:393
#2 0x00007f28da96f6db in start_thread (arg=0x7f28d5123700) at pthread_create.c:463
#3 0x00007f28da0f761f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
可以看到 调用顺序:clone ()–>start_thread->ServerThread->_recv
总结一下我的需求和解决办法:
需求:
写了一个守护进程 (主进程里fork()一个出来 )
我要实现一个TCP 服务器 accept客户端
守护进程内容:
while(1)
『
新建监听SOCKET 会开启一个fd
bind
listen
pthread_create(tip,null,)开启一些处理线程 记录线程等
for(;;)
『
新建 接收客户端socket=accept 客户端socket对应一个fd
int err1=pthread_create(&tid[connNum++], nullptr, ServerThread, (void*)&connTemp);
开启新客户端socket的接收线程 recv
usleep(5000);
』
for (int j=0;j<connNum;j++) {
pthread_join(tid[j], nullptr);//pthread_join - join with a terminated thread
}
pthread_join(tidp[0], nullptr);//pthread_join - join with a terminated thread
pthread_join(tidp[1], nullptr);
pthread_join(tidp[2], nullptr);
查看端口号8000 开了4个客户端 均可以接入到服务器
ii@ii-ThinkPad-Edge-E431:~$ sudo lsof -i:8000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ServerSer 3999 ii 5u IPv4 51210 0t0 TCP *:8000 (LISTEN)
ServerSer 3999 ii 8u IPv4 51211 0t0 TCP ii-ThinkPad-Edge-E431:8000->ii-ThinkPad-Edge-E431:56708 (ESTABLISHED)
ServerSer 3999 ii 9u IPv4 49085 0t0 TCP ii-ThinkPad-Edge-E431:8000->ii-ThinkPad-Edge-E431:56710 (ESTABLISHED)
ServerSer 3999 ii 10u IPv4 51313 0t0 TCP ii-ThinkPad-Edge-E431:8000->ii-ThinkPad-Edge-E431:56712 (ESTABLISHED)
ServerSer 3999 ii 12u IPv4 51377 0t0 TCP ii-ThinkPad-Edge-E431:8000->ii-ThinkPad-Edge-E431:56716 (ESTABLISHED)
Demo 4027 ii 5u IPv4 51277 0t0 TCP ii-ThinkPad-Edge-E431:56708->ii-ThinkPad-Edge-E431:8000 (ESTABLISHED)
Demo 4045 ii 5u IPv4 49125 0t0 TCP ii-ThinkPad-Edge-E431:56710->ii-ThinkPad-Edge-E431:8000 (ESTABLISHED)
Demo 4063 ii 5u IPv4 51326 0t0 TCP ii-ThinkPad-Edge-E431:56712->ii-ThinkPad-Edge-E431:8000 (ESTABLISHED)
Demo 4103 ii 5u IPv4 52341 0t0 TCP ii-ThinkPad-Edge-E431:56716->ii-ThinkPad-Edge-E431:8000 (ESTABLISHED)
pthread_join 在调试过程中不知如何使用
程序会在它调用的地方进行阻塞,直至它对应的线程终止返回。 所以如果它前面还有其他线程需要一直运行 它就在最后阻塞不能挡住前面的线程
socket
服务器 bind 8000端口 对应 FD 5u
服务器 accept 接收客户端接入 对应了 客户端 Demo 4027 ii 5u IPv4 51277 0t0 TCP ii-ThinkPad-Edge-E431:56708->ii-ThinkPad-Edge-E431:8000 (ESTABLISHED)
的FD为8u 服务器用8来命名此客户端( accept函数的返回值 )
(accept函数接受一个客户端请求后会返回一个新的SOCKFD值,当有不同的客户端同时有不同请求时,会返回不同的SOCKFD的值。这个不同的值和建立SOCKET 时生成的SOCKFD还是不同的。服务器与客户端之间的通信就是在这些不同的SOCKFD上进行的。)
下载工具 ProcessExplorer 直接双击打开 运行自己的程序
选中ProcessExplorer process列里自己的程序 view—Lower Pane view —dlls 查看dll
handles 看线程等