debugging - 从 c 中的 popen() 创建的文件描述符读取时出现段错误
问题描述
我正在调试较少的实用程序。它通过调用 popen() 创建一个文件描述符。
fd = popen(scmd, "r");
scmd 是:
(gdb) p scmd
$3 = 0x555555591f00 "/bin/bash -c lessecho\\ -p0x22\\ -d0x22\\ -e\\\\\\\\\\ -n0x3b\\ -n0x20\\ -n0x2a\\ -n0x3f\\ -n0x9\\ -n0xa\\ -n0x27\\ -n0x22\\ -n0x28\\ -n0x29\\ -n0x3c\\ -n0x3e\\ -n0x5b\\ -n0x5d\\ -n0x7c\\ -n0x26\\ -n0x5e\\ -n0x60\\ -n0x23\\ -n0x5c\\ -n0x24\\ -n0x25\\ -n0x3d\\ -n0x7e\\ -n0x7b\\ -n0x7d\\ -n0x2c\\ --\\ 5"
然后少调用 getc(fd) 并崩溃。我尝试在单个文件中执行此 scmd 并从 popen 中读取,它运行良好。所以我不知道为什么它崩溃得更少。
这是崩溃时的堆栈:
#0 malloc_consolidate (av=av@entry=0x7ffff7f74b80 <main_arena>) at malloc.c:4475
#1 0x00007ffff7e23e03 in _int_malloc (av=av@entry=0x7ffff7f74b80 <main_arena>, bytes=bytes@entry=4096) at malloc.c:3699
#2 0x00007ffff7e262d4 in __GI___libc_malloc (bytes=4096) at malloc.c:3058
#3 0x00007ffff7e0de84 in __GI__IO_file_doallocate (fp=0x555555591df0) at filedoalloc.c:101
#4 0x00007ffff7e1e050 in __GI__IO_doallocbuf (fp=fp@entry=0x555555591df0) at libioP.h:948
#5 0x00007ffff7e1ce24 in _IO_new_file_underflow (fp=0x555555591df0) at fileops.c:486
#6 0x00007ffff7e1e106 in __GI__IO_default_uflow (fp=0x555555591df0) at libioP.h:948
#7 0x000055555556539f in readfd (fd=0x555555591df0) at filename.c:538
这是 fd 的信息:
(gdb) p* fd
$6 = {_flags = -72539000, _IO_read_ptr = 0x0, _IO_read_end = 0x0, _IO_read_base = 0x0, _IO_write_base = 0x0,
_IO_write_ptr = 0x0, _IO_write_end = 0x0, _IO_buf_base = 0x0, _IO_buf_end = 0x0, _IO_save_base = 0x0,
_IO_backup_base = 0x0, _IO_save_end = 0x0, _markers = 0x0, _chain = 0x7ffff7f755c0 <_IO_2_1_stderr_>, _fileno = 4,
_flags2 = 0, _old_offset = 2331849978805251629, _cur_column = 0, _vtable_offset = 48 '0', _shortbuf = "x",
_lock = 0x555555591ee0, _offset = -1, _codecvt = 0x205c363278306e2d, _wide_data = 0xffffffffffffffff,
_freeres_list = 0x0, _freeres_buf = 0x205c333278306e2d, __pad5 = 2331847788371930669, _mode = -1,
_unused2 = "24\\ -n0x25\\ -n0x3d\\ "}
解决方案
所以我不知道为什么它崩溃得更少。
目前尚不清楚less
您是指GNU Less还是您编写的内容。
在任何情况下,实现内部的任何崩溃malloc
(如这里发生的那样)都是堆损坏的明确指示(写入分配缓冲区的末尾,free
两次 ing 某事等)。
查找此类堆损坏的标准工具是Valgrind和Address Sanitizer。任何一个都应该直接指出错误。
推荐阅读
- html - 在由 div 组成的类似表格的结构中将列粘贴到左侧和顶部
- angular - 从Angular中的父路由组件向当前子路由添加查询参数
- sql - 有没有办法计算两次相同的日期列?
- angular - ngx-分页中的编号
- c++ - 在 C++ 中为无序映射获取给定输入键的错误值
- javascript - Javascript 将对象值收集到按属性分组的数组中
- vb.net - String() 类型的值无法转换为 ArrayList
- java - 我可以在没有 root 的情况下使用辅助功能 API 在我自己的应用程序之外触发触摸事件吗?
- javascript - 在 d3 图表上拖动时仅更新最后一个 Y 轴
- php - DataTables 警告:table id=datatable - Ajax 错误。使用 laravel