内存访问越界:这是最常见的原因之一。例如,试图访问数组边界之外的内存,或者对已经释放的内存进行访问。 比如,定义了一个数组 int arr[5],但却尝试访问 arr[10]。
空指针解引用:当程序尝试对一个空指针(未初始化或已被赋值为 NULL 的指针)进行解引用操作时,会导致段错误。 例如: c int *ptr = NULL; *ptr = 10;
栈溢出:如果函数调用层次过深,或者在函数内部使用了过大的局部变量,可能导致栈空间不足,引发段错误。
非法的内存操作:例如,使用 free() 释放了一块内存后,又再次尝试访问或释放它。
指针类型错误:将一种类型的指针强制转换为另一种不兼容的类型,并进行访问操作。
下面我们使用gdb来调试程序,看看详细的错误输出,使用 gdb 运行程序:
1 2 3
$gdb ./out/bin/mqtt Reading symbols from ./out/bin/mqtt... (gdb)
直接使用 run 运行程序:
1 2 3 4 5 6 7
(gdb) r Starting program: /home/sunhuashan/workplace/my_mqttclient/ours/out/bin/mqtt
Program received signal SIGSEGV, Segmentation fault. __memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:259 259 ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S: No such file or directory. (gdb)
(gdb) b main Breakpoint 1 at 0x30cb: file test/main.c, line 51. (gdb) b mqtt_init Breakpoint 2 at 0x182c: file mqtt/mqtt.c, line 135. (gdb) b mqtt_connect Breakpoint 3 at 0x1b30: file mqtt/mqtt.c, line 228. (gdb) b mqtt_disconnect Breakpoint 4 at 0x1cca: file mqtt/mqtt.c, line 280. (gdb) b mqtt_pingreq Breakpoint 5 at 0x1dbe: file mqtt/mqtt.c, line 312.
(gdb) r Starting program: /home/sunhuashan/workplace/my_mqttclient/ours/out/bin/mqtt
Breakpoint 1, main () at test/main.c:51 51 { (gdb) c Continuing.
Breakpoint 2, mqtt_init (session=0x0, init_params=0x7fffffffdd00) at mqtt/mqtt.c:135 135 { (gdb) c Continuing.
Breakpoint 3, mqtt_connect (session=0x7ffff7eaddfe <__sleep+62>) at mqtt/mqtt.c:228 228 { (gdb) c Continuing.
Program received signal SIGSEGV, Segmentation fault. __memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:259 259 ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S: No such file or directory. (gdb)
(gdb) b mqtt_connect Breakpoint 1 at 0x1b30: file mqtt/mqtt.c, line 228. (gdb) r Starting program: /home/sunhuashan/workplace/my_mqttclient/ours/out/bin/mqtt
Breakpoint 1, mqtt_connect (session=0x7ffff7eaddfe <__sleep+62>) at mqtt/mqtt.c:228 228 { (gdb) l 223 memory_free(conn_opts); 224 return retval; 225 } 226 227 int mqtt_connect(struct mqtt_session *session) 228 { 229 int retval = 0; 230 unsigned char *wbuf; 231 unsigned int buflen; 232 // struct timer_t conn_timer = {0}; (gdb) 233 struct timer_t conn_timer; 234 struct connack_options ack_opts = {0}; 235 236 if (!session) 237 return -1; 238 239 if (!timer_init(&conn_timer)) 240 return -1; 241 timer_cutoff(&conn_timer, session->net_timeout); 242 (gdb) 243 wbuf = session->write_buf; 244 buflen = session->write_buflen; 245 246 retval = network_connect(session->network); 247 if (retval < 0) 248 goto destory_timer; 249 250 buflen = serialize_connect(wbuf, buflen, session->conn_opts); 251 retval = mqtt_send_packet(session, buflen, &conn_timer); 252 if (retval < 0) (gdb) 253 goto destory_timer; 254 255 retval = wait_connack(session, &conn_timer); 256 if (retval < 0) 257 goto destory_timer; 258 259 retval = deserialize_connack(&ack_opts, session->read_buf, session->read_buflen); 260 if (!retval) { 261 retval = -1; 262 goto destory_timer; (gdb) 263 } 264 265 if (ack_opts.return_code != ACK_RC_SUCCESS) { 266 printf("error:\tCONNACK return_code is:\t%d\n", ack_opts.return_code); 267 retval = -1; 268 goto destory_timer; 269 } 270 271 session->state = SESSION_CONNECTED; 272 printf("connect to server successful!\n"); (gdb) b 239 Breakpoint 2 at 0x555555555b6d: file mqtt/mqtt.c, line 239. (gdb) b 246 Breakpoint 3 at 0x555555555bb2: file mqtt/mqtt.c, line 246. (gdb) b 250 Breakpoint 4 at 0x555555555bcf: file mqtt/mqtt.c, line 250. (gdb) c Continuing.
Breakpoint 2, mqtt_connect (session=0x55555555b2a0) at mqtt/mqtt.c:239 239 if (!timer_init(&conn_timer)) (gdb) c Continuing.
Program received signal SIGSEGV, Segmentation fault. __memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:259 259 ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S: No such file or directory. (gdb)
上面的具体操作是,重新启动了 gdb 调试,在 mqtt_connect 函数入口打上断点,然后运行程序,使用 list (l) 命令查看该函数的代码,选择一些合适的地方打上断点,然后 c 继续运行。功夫不负有心人,我们又进一步确认了问题函数 timer_init ,继续打断点调试,由于 timer_init 函数比较短,这次我们单步运行即可:
(gdb) b mqtt_connect Breakpoint 1 at 0x1b30: file mqtt/mqtt.c, line 228. (gdb) r Starting program: /home/sunhuashan/workplace/my_mqttclient/ours/out/bin/mqtt
Breakpoint 1, mqtt_connect (session=0x7ffff7eaddfe <__sleep+62>) at mqtt/mqtt.c:228 228 { (gdb) l 223 memory_free(conn_opts); 224return retval; 225 } 226 227intmqtt_connect(struct mqtt_session *session) 228 { 229int retval = 0; 230unsignedchar *wbuf; 231unsignedint buflen; (gdb) 233structtimer_tconn_timer; 234structconnack_optionsack_opts; 235 236if (!session) 237return-1; 238 239if (!timer_init(&conn_timer)) 240return-1; 241 timer_cutoff(&conn_timer, session->net_timeout); 242 (gdb) b 239 Breakpoint 2 at 0x555555555b6d: file mqtt/mqtt.c, line 239. (gdb) c Continuing.
Breakpoint 2, mqtt_connect (session=0x55555555b2a0) at mqtt/mqtt.c:239 239if (!timer_init(&conn_timer)) (gdb) s timer_init(t=0xffffffffffffff80) at system/linux/timer.c:10 10 { (gdb) n 11structtimeval *timeval = (struct timeval*)t->timer; (gdb) n 13if (!timeval) (gdb) 15if (!timeval) (gdb) 18memset(timeval, 0, sizeof(struct timeval)); (gdb)
Program received signal SIGSEGV, Segmentation fault. __memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:259 259 ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S: No such file or directory. (gdb)