创作人QQ:851301776,邮箱:[email protected],欢迎大家一起技术交流,本博客主要是自己学习的心得体会,只为每天进步一点点!
个人座右铭:
1.没有横空出世,只要厚积一定发。
2.你可以学历不高,你可以不上学,但你不能不学习
一、错误展示
Thread 3 "onvif" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff1c4e700 (LWP 8982)]
0x00007ffff3d3ecd0 in _IO_vfprintf_internal (s=0x7ffff40b5620 <_IO_2_1_stdout_>, format=<optimized out>,
format@entry=0x7a073d "% %d %s xADDR:%s\n", ap=ap@entry=0x7ffff1c4da18) at vfprintf.c:1632
1632 vfprintf.c: 没有那个文件或目录.
查看堆栈:
(gdb) bt
#0 0x00007ffff3d3ecd0 in _IO_vfprintf_internal (s=0x7ffff40b5620 <_IO_2_1_stdout_>, format=<optimized out>,
format@entry=0x7a073d "% %d %s xADDR:%s\n", ap=ap@entry=0x7ffff1c4da18) at vfprintf.c:1632
#1 0x00007ffff3e06aef in ___printf_chk (flag=flag@entry=1, format=format@entry=0x7a073d "% %d %s xADDR:%s\n") at printf_chk.c:35
#2 0x000000000075c168 in printf (__fmt=0x7a073d "% %d %s xADDR:%s\n") at /usr/include/x86_64-linux-gnu/bits/stdio2.h:104
#3 NVR_camera_channel_num_que_node_exists_XAddr (p=p@entry=0xc67eb8,
nvr_XAddr=0x7fffe00466a0 "http://192.168.3.110:80/onvif/device_service ") at NVR_camera_channel_num_que.c:158
#4 0x0000000000453416 in p_onvif_server_udp (arg=0xc67e00) at pthread_onvif_server_udp.c:303
#5 0x00007ffff7bc16ba in start_thread (arg=0x7ffff1c4e700) at pthread_create.c:333
#6 0x00007ffff3df751d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
确定代码出错位置:
二、解决
1.在错误的函数中增加断点
(gdb) b NVR_camera_channel_num_que.c:158
Breakpoint 1 at 0x75c13d: file NVR_camera_channel_num_que.c, line 158.
2.重启并且单步调试
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /mnt/hgfs/project/visual_gateway/software/src_intra_20220618/onvif
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[2022/06/21 15:02:29]: vivsual gateway is starting
[2022/06/21 15:02:29]: [2022/06/21 15:02:29]: para file already exist!
[2022/06/21 15:02:29]: parameter config file init succeed!~
[2022/06/21 15:02:29]: init complete!
[2022/06/21 15:02:29]: Redis_host_port:6379
[2022/06/21 15:02:29]: Redis_protocol_type:tcp
[2022/06/21 15:02:29]: Redis_protocol_type:127.0.0.1
[2022/06/21 15:02:29]: Redis_whether_use:YES
[2022/06/21 15:02:29]: Redis_channel_name:pubtoplat
[2022/06/21 15:02:29]: MySQL_host_port:3306
[2022/06/21 15:02:29]: MySQL_user_name:root
[2022/06/21 15:02:29]: MySQL_pass_word:1
[2022/06/21 15:02:29]: MySQL_host_ip:127.0.0.1
[2022/06/21 15:02:29]: MySQL_database:demo1
[2022/06/21 15:02:29]: MySQL_charset:utf8
[2022/06/21 15:02:29]: MySQL_protocol_type:tcp
[2022/06/21 15:02:29]: UDP_active:YES
[2022/06/21 15:02:29]: TCP_active:YES
[2022/06/21 15:02:29]: TCP_passivity:YES
[2022/06/21 15:02:29]: up_sip_id:34020000002000000001
[2022/06/21 15:02:29]: up_Realm:34020000002
[2022/06/21 15:02:29]: up_Password:123456789
[2022/06/21 15:02:29]: up_Username:admin
[2022/06/21 15:02:29]: up_Nonce:1622614946
[2022/06/21 15:02:29]: up_host:192.168.1.2
[2022/06/21 15:02:29]: up_port:6100
[2022/06/21 15:02:29]: UDP_AC_SIP_id:34020000002000000001
[2022/06/21 15:02:29]: UDP_AC_Realm:3402000000
[2022/06/21 15:02:29]: UDP_AC_Password:123456789
[2022/06/21 15:02:29]: UDP_AC_Username:root
[2022/06/21 15:02:29]: UDP_AC_Nonce:1622614945
[2022/06/21 15:02:29]: UDP_ListenHost_buff:eth0
[2022/06/21 15:02:29]: UDP_ListenPort:5800
[2022/06/21 15:02:29]: TCP_AC_SIP_id:34020000002000000004
[2022/06/21 15:02:29]: TCP_AC_Realm:3402000001
[2022/06/21 15:02:29]: TCP_AC_Password:123456789
[2022/06/21 15:02:29]: TCP_AC_Username:root
[2022/06/21 15:02:29]: TCP_AC_Nonce:1622614945
[2022/06/21 15:02:29]: TCP_ListenHost_buff:eth1
[2022/06/21 15:02:29]: TCP_ListenPort:5900
[2022/06/21 15:02:29]: TCP_PS_SIP_id:34020000002000000005
[2022/06/21 15:02:29]: TCP_PS_Realm:3402000002
[2022/06/21 15:02:29]: TCP_PS_Password:123456789
[2022/06/21 15:02:29]: TCP_PS_Username:root
[2022/06/21 15:02:29]: TCP_PS_Nonce:1622614945
[2022/06/21 15:02:29]: TCP_SerHost_buff:eth2
[2022/06/21 15:02:29]: TCP_SerPort:6000
[2022/06/21 15:02:29]: msg_conf_file:../msg/msg_file.txt
[2022/06/21 15:02:29]: SIP_connect_STA_file:../para/platform_para.txt
ptr->msg_qid:0
[New Thread 0x7ffff7fc0700 (LWP 9045)]
[2022/06/21 15:02:29]: Create Pthread (p_data_deal) ok
[New Thread 0x7ffff1c4e700 (LWP 9046)]
[2022/06/21 15:02:29]: Create Pthread (p_onvif_server_udp) ok
[2022/06/21 15:02:29]: p_data_deal stack size: 1052672
pthread_onvif_server_udp.c 269 p_onvif_server_udp suc
pthread_onvif_server_udp.c 278 p_onvif_server_udp recv
================= + dump__wsdd__ProbeMatches + >>>
wsdd__ProbeMatches: (0x7fffe8047da0)
|- __sizeProbeMatch: 1
|- ProbeMatch: (0x7fffe8047da8)
|- 0
|- wsa__EndpointReference: (0x7fffe80466f0)
|- Address: urn:uuid:055e81bd-1787-49f8-bb60-3cda6d9939da
|- ReferenceProperties: (null)
|- ReferenceParameters: (null)
|- PortType: (null)
|- ServiceName: (null)
|- __size: 0
|- __any: (null)
|- __anyAttribute:
|- Types: tdn:NetworkVideoTransmitter tds:Device
|- Scopes: (0x7fffe8047f80)
|- __item: onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/type/audio_encoder onvif://www.onvif.org/type/ptz onvif://www.onvif.org/Profile/Streaming onvif://www.onvif.org/hardware/hisi onvif://www.onvif.org/mfr/ipcamera onvif://www.onvif.org/location/country/china onvif://www.onvif.org/location/city/tianjin onvif://www.onvif.org/mac onvif://www.onvif.org/firmware/APP_V3.3.0.20200713 onvif://www.onvif.org/name/ipcamera
|- MatchBy: (null)
|- XAddrs: http://192.168.3.110:80/onvif/device_service
|- MetadataVersion: 1
================= - dump__wsdd__ProbeMatches - <<<
pthread_onvif_server_udp.c 283 p_onvif_server_udp suc
pthread_onvif_server_udp.c 301 p_onvif_server_udp count:1
[Switching to Thread 0x7ffff1c4e700 (LWP 9046)]
Thread 3 "onvif" hit Breakpoint 1, NVR_camera_channel_num_que_node_exists_XAddr (p=p@entry=0xc67eb8,
nvr_XAddr=0x7fffe80466a0 "http://192.168.3.110:80/onvif/device_service ") at NVR_camera_channel_num_que.c:160
160 if(SUC_RET == memcmp(tmp_node->nvr_XAddr, nvr_XAddr, MAX(strlen(tmp_node->nvr_XAddr), strlen(nvr_XAddr))) )
单步调试:
Thread 3 "onvif" hit Breakpoint 2, NVR_camera_channel_num_que_node_exists_XAddr (p=p@entry=0xc67eb8,
nvr_XAddr=0x7fffe00466a0 "http://192.168.3.110:80/onvif/device_service ") at NVR_camera_channel_num_que.c:148
148 if((!p) || (!nvr_XAddr))
(gdb) n
147 {
(gdb)
153 if(p->head.p_next == &(p->tail)) return 1;
(gdb) n
147 {
(gdb) n
153 if(p->head.p_next == &(p->tail)) return 1;
(gdb) n
156 for(tmp_node = &(p->head.p_next);tmp_node != &(p->tail); tmp_node = tmp_node->p_next)
(gdb) n
153 if(p->head.p_next == &(p->tail)) return 1;
(gdb) n
Thread 3 "onvif" hit Breakpoint 1, NVR_camera_channel_num_que_node_exists_XAddr (p=p@entry=0xc67eb8,
nvr_XAddr=0x7fffe00466a0 "http://192.168.3.110:80/onvif/device_service ") at NVR_camera_channel_num_que.c:160
160 if(SUC_RET == memcmp(tmp_node->nvr_XAddr, nvr_XAddr, MAX(strlen(tmp_node->nvr_XAddr), strlen(nvr_XAddr))) )
(gdb) n
158 printf("% %d %s xADDR:%s\n", __FILE__, __LINE__, __func__, nvr_XAddr);
(gdb) n
Thread 3 "onvif" received signal SIGSEGV, Segmentation fault.
0x00007ffff3d3ecd0 in _IO_vfprintf_internal (s=0x7ffff40b5620 <_IO_2_1_stdout_>, format=<optimized out>,
format@entry=0x7a073d "% %d %s xADDR:%s\n", ap=ap@entry=0x7ffff1c4da18) at vfprintf.c:1632
1632 vfprintf.c: 没有那个文件或目录.
(gdb)
问题基础确认为:
基础解决:屏蔽对应的函数
继续重新调试:
Thread 3 "onvif" hit Breakpoint 2, NVR_camera_channel_num_que_node_exists_XAddr (p=p@entry=0xc67eb8,
nvr_XAddr=0x7fffe00466a0 "http://192.168.3.110:80/onvif/device_service ") at NVR_camera_channel_num_que.c:148
148 if((!p) || (!nvr_XAddr))
(gdb) n
147 {
(gdb) n
153 if(p->head.p_next == &(p->tail)) return 1;
(gdb) n
147 {
(gdb) n
153 if(p->head.p_next == &(p->tail)) return 1;
(gdb) n
156 for(tmp_node = &(p->head.p_next);tmp_node != &(p->tail); tmp_node = tmp_node->p_next)
(gdb) n
153 if(p->head.p_next == &(p->tail)) return 1;
(gdb) n
Thread 3 "onvif" hit Breakpoint 1, NVR_camera_channel_num_que_node_exists_XAddr (p=p@entry=0xc67eb8,
nvr_XAddr=0x7fffe00466a0 "http://192.168.3.110:80/onvif/device_service ") at NVR_camera_channel_num_que.c:160
160 if(SUC_RET == memcmp(tmp_node->nvr_XAddr, nvr_XAddr, MAX(strlen(tmp_node->nvr_XAddr), strlen(nvr_XAddr))) )
(gdb) n
164 printf("%s %d %s \n", __FILE__, __LINE__, __func__ );
(gdb) n
NVR_camera_channel_num_que.c 164 NVR_camera_channel_num_que_node_exists_XAddr
156 for(tmp_node = &(p->head.p_next);tmp_node != &(p->tail); tmp_node = tmp_node->p_next)
(gdb) n
Thread 3 "onvif" hit Breakpoint 1, NVR_camera_channel_num_que_node_exists_XAddr (p=p@entry=0xc67eb8,
nvr_XAddr=0x7fffe00466a0 "http://192.168.3.110:80/onvif/device_service ") at NVR_camera_channel_num_que.c:160
160 if(SUC_RET == memcmp(tmp_node->nvr_XAddr, nvr_XAddr, MAX(strlen(tmp_node->nvr_XAddr), strlen(nvr_XAddr))) )
(gdb) n
Thread 3 "onvif" received signal SIGSEGV, Segmentation fault.
strlen () at ../sysdeps/x86_64/strlen.S:106
106 ../sysdeps/x86_64/strlen.S: 没有那个文件或目录.
(gdb) bt
#0 strlen () at ../sysdeps/x86_64/strlen.S:106
#1 0x000000000075c14c in NVR_camera_channel_num_que_node_exists_XAddr (p=p@entry=0xc67eb8,
nvr_XAddr=0x7fffe00466a0 "http://192.168.3.110:80/onvif/device_service ") at NVR_camera_channel_num_que.c:160
#2 0x0000000000453416 in p_onvif_server_udp (arg=0xc67e00) at pthread_onvif_server_udp.c:303
#3 0x00007ffff7bc16ba in start_thread (arg=0x7ffff1c4e700) at pthread_create.c:333
#4 0x00007ffff3df751d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
这里的问题为调用strlen函数导致的段错误,这时候就需要分析:
memcmp(tmp_node->nvr_XAddr, nvr_XAddr, MAX(strlen(tmp_node->nvr_XAddr), strlen(nvr_XAddr))) )
其实经常调试的就知道,其实这种问题就是代码逻辑的错误,已分配内存但是未写入数据的访问造成的
代码中增加:
Thread 3 "onvif" hit Breakpoint 1, NVR_camera_channel_num_que_node_exists_XAddr (p=p@entry=0xc67eb8,
nvr_XAddr=0x7fffe00466a0 "http://192.168.3.110:80/onvif/device_service ") at NVR_camera_channel_num_que.c:148
148 if((!p) || (!nvr_XAddr))
(gdb) n
147 {
(gdb) n
153 if(p->head.p_next == &(p->tail)) return 1;
(gdb) n
147 {
(gdb) n
153 if(p->head.p_next == &(p->tail)) return 1;
(gdb) n
156 for(tmp_node = &(p->head.p_next);tmp_node != &(p->tail); tmp_node = tmp_node->p_next)
(gdb) n
153 if(p->head.p_next == &(p->tail)) return 1;
(gdb) n
158 printf("tmp_node->nvr_XAddr:%p \n", tmp_node->nvr_XAddr);
(gdb) print tmp_node->nvr_XAddr
$1 = '\000' <repeats 16 times>, "pubtoplat", '\000' <repeats 55 times>, "\353\030\000\000\000\000\000\000\321\000\000\000\000\000\000\000YES\000\377\177\000\000xK\v\364\377\177", '\000' <repeats 17 times>
(gdb) n
tmp_node->nvr_XAddr:0xc682c0
159 printf("nvr_XAddr:%p\n", nvr_XAddr);
(gdb) print Quit
(gdb) print nvr_XAddr
$2 = 0x7fffe00466a0 "http://192.168.3.110:80/onvif/device_service "
说明: tmp_node->nvr_XAddr对应的空地址,这个时候就需要查看源码了
这个问题为代码逻辑的错误。
最后查明为这个简单的链表未初始化,造成地址为空,循环判断造成的错误。
修改完成代码后,上一波调试如下:
解决了。
三、核心点
(1)printf函数底层会调用malloc函数,如果程序陷入死循环,会不停的调用malloc
(2)gdb调试,其实这种调试主要是:断点、单步、打印(print)