专栏首页皮振伟的专栏[gcc][glibc]va_start嵌套导致的问题

[gcc][glibc]va_start嵌套导致的问题

前言

使用tgt-1.0.75创建好target之后,在initiator端执行login操作大约卡3s~5s左右。同时观察tgt,CPU消耗到达100%。

一度怀疑是glibc的版本问题,在多个发行版上测试,有的发行版上会coredump。

分析

backtrace

用gdb分析coredump文件,拿到backtrace:

Program terminated with signal SIGSEGV, Segmentation fault.
 #0  0x00007f58a410ccc0 in _IO_vfprintf_internal (s=s@entry=0x7ffdec98fdc0, format=<optimized out>,
    format@entry=0x432bc8 "d Mode page %d (0x%02x), index: %d\n", ap=ap@entry=0x7ffdec98ff38) at vfprintf.c:1632
 #1  0x00007f58a41d4896 in ___vsnprintf_chk (s=0x7ffdec990010 "", maxlen=<optimized out>, flags=1,
    slen=<optimized out>, format=0x432bc8 "d Mode page %d (0x%02x), index: %d\n", args=args@entry=0x7ffdec98ff38)
    at vsnprintf_chk.c:63
 #2  0x00007f58a41d47f8 in ___snprintf_chk (s=<optimized out>, maxlen=<optimized out>, flags=<optimized out>,
    slen=<optimized out>, format=<optimized out>) at snprintf_chk.c:34
 #3  0x000000000041f6e7 in scsi_sprintf (str=<optimized out>, size=<optimized out>, format=0x432a88 "%-*s",
    format=0x432a88 "%-*s") at util.h:255
 #4  0x000000000042043a in spc_inquiry (host_no=<optimized out>, cmd=0x123ff40) at spc.c:343
 #5  0x000000000041935a in target_cmd_perform (tid=<optimized out>, cmd=0x123ff40) at target.c:1168
 #6  0x000000000040a66b in iscsi_target_cmd_queue (task=0x123fe70) at iscsi/iscsid.c:1387
 #7  iscsi_scsi_cmd_execute (task=task@entry=0x123fe70) at iscsi/iscsid.c:1407
 #8  0x000000000040a93e in iscsi_task_execute (task=task@entry=0x123fe70) at iscsi/iscsid.c:1527
 #9  0x000000000040b817 in iscsi_task_queue (task=0x123fe70) at iscsi/iscsid.c:1614
 #10 iscsi_task_rx_done (conn=0x123b360) at iscsi/iscsid.c:1744
 #11 iscsi_rx_handler (conn=conn@entry=0x123b360) at iscsi/iscsid.c:2222
 #12 0x0000000000411f48 in iscsi_tcp_event_handler (fd=<optimized out>, events=1, data=0x123b360)
    at iscsi/iscsi_tcp.c:278
 #13 0x00000000004152df in event_loop () at tgtd.c:432
 #14 0x0000000000407191 in main (argc=<optimized out>, argv=<optimized out>) at tgtd.c:624

backtrace正常,相关的参数也是正常的,和预期的现象不符合。

gcc & glibc的版本问题

一共测试了三个版本,分别是:

gcc-5.4/glibc-2.23 --> coredump

gcc-6.3/libc-2.24 --> CPU 100%

gcc-7.3/libc-2.27 --> coredump

不同的版本的gcc和glibc的情况,并非完全一致。

tgt的版本对比

考虑到tgt是一个比较稳定的软件,尝试回退到上一个版本1.0.74,发现login操作瞬间完成。

在两个版本之间,除了README更新,只有一个代码更新的commit : https://github.com/fujita/tgt/commit/2de8bebe132e3b998bf4848d0bd22b50367ad4b8

发现这里有改动导致的问题。

va_start嵌套的问题

va_start经常被用来处理可变参数的情况,经过测试发现,在处理"%-*s"这个特定的格式情况下,如果父函数先调用va_start处理,子函数再调用va_start处理,就会出现上述的bug。因为sprintf函数本身也是使用了va_start,而且tgt封装的函数也使用了va_start,导致了这个问题。

采用了walk around的方式来修复这个问题,避免va_start的嵌套即可。

给maintainer发送了patch,maintainer接受并push到了upstream。

https://github.com/fujita/tgt/commit/0bf3f6915282dc8df2f02e6da30814951e52d179

最新的upstream和下一个版本,将会修复这个问题。

本文分享自微信公众号 - AlwaysGeek(gh_d0972b1eeb60),作者:AlwaysGeek

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [kvm][virt]PIO技术分析

    前言: 基于KVM的设备虚拟化,就从这里开始吧。 分析: 1,PIO Port IO,所谓端口IO,x86上使用in、out指令进行访问。和内存的地址空间完...

    皮振伟
  • [linux][memory]内存映射技术分析

    前言: KVM的设备虚拟化,除了前文《PIO技术分析》,还有另外一个核心概念---MMIO。原计划这里分析一下KVM的MMIO虚拟化。考虑到MMIO比PIO复杂...

    皮振伟
  • [linux][kernel]dev random生成随机数慢的问题

    前言: 一般生成随机数,可以用glibc提供的random()函数,不过这个是伪随机的函数,所以一般会在使用使用random函数之前初始化种子:srandom(...

    皮振伟
  • blink的一处断言错误

    --url=http://music.yule.sohu.com/20170926/n514522612.shtml 里有断言错误

    龙泉寺扫地僧
  • 深入Go的错误处理机制(一)使用

    程序运行过程中不可避免的发生各种错误,要想让自己的程序保持较高的健壮性,那么异常,错误处理是需要考虑周全的,每个编程语言提供了一套自己的异常错误处理机制,在Go...

    阿伟
  • 编程思想 之「对象漫谈」

    在「语言导论」中,我们曾提到过「万物皆对象」,事实上,也确实如此。在面向对象编程的世界中,我们创建对象、操作对象、销毁对象,我们所做的一切动作都离不开对象。在本...

    CG国斌
  • 震惊!无人问津的文章竟然是这样写出来的No.98

    大蕉
  • 实用工具 | 强大的自动驾驶模拟器CARLA

    随着人们对安全、舒适的驾驶体验的不断追求,自动驾驶成为汽车研发的新方向。与此同时,自动驾驶相关技术在人工智能领域也是如火如荼的研究方向,吸引了大批来自产业界和学...

    马上科普尚尚
  • How to find where settype DB table COMM_PRMAT is accessed without debugging

    We know settype table COMM_PRMAT is used to store attribute data modelled in pro...

    Jerry Wang
  • 百度发布全新 NLG 训练模型 ERNIE-GEN,获 5 项 SOTA!

    5月20日,百度ERNIE重磅发布全新的语言生成预训练模型ERNIE-GEN,解决自然语言处理领域“生成”方向的难题,让机器不但能“理解”人类的意思,还能完成更...

    代码医生工作室

扫码关注云+社区

领取腾讯云代金券