vim的设置和gdb调试使用

文件描述符

Posted by chensong on 2017-06-16 11::58::53

前言

C++服务器经常要分析core文件, 找到错误问题

正文

一, vim

1, vim的配置

  set nu             // 在左侧行号

  set tabstop        //tab 长度设置为 4

  set nobackup       //覆盖文件时不备份

  set cursorline      //突出显示当前行

  set ruler          //在右下角显示光标位置的状态行

  set autoindent     //自动缩进
  set stal=2        //显示文件名

2, vim使用

  1, 行首 : o           行未: $
  2,  文件的首: gg       文件的未 : 大G
  3, 查询多少行  : ?G     列子: 220G
  4,  删除前一个: x        删除后面一个 : 大X
  5,  d + o    , d + $ , d + d , n + d
  6,粘贴: p  (下一行)            大P  (当前行)
  7,复制: yy                    nyy (n行)
  8,可视行 : v
  9, 查找  : /        ?
  10, 高亮: #
  11, 替换: r
  12,       shouj     : << >>
  13: 查看文档: n + 大k  (K)  n(第几章)
  14:创建一行: o(下面一行)   大o (上面一行)
  15: 删除 s(一个字)   大S (整行)
  16:水平分屏:sp     vsp 

二, gdb

1,core的信号

core的信号处理方式:终止进程+产生core文件

  1. 设置生成core:ulimit -c unlimited
  2. 取消生成core:ulimit-c 0

2,gdb调试的使用

①, 生成core文件名称(正常开放中使用不到)

设置core文件格式:/proc/sys/kernel/core_pattern 
文件不能vi,可以用后面的套路 ,使用root权限 echo "core-%e-%p-%t" > /proc/sys/kernel/core_pattern

参数说明:

以下是参数列表 :
    %p - insert pid into filename 添加 pid
    %u - insert current uid into filename 添加当前 uid
    %g - insert current gid into filename 添加当前 gid
    %s - insert signal that caused the coredump into the filename 添加导致产生 core 的信号
    %t - insert UNIX time that the coredump occurred into filename 添加 core 文件生成时的 unix 时间
    %h - insert hostname where the coredump happened into filename 添加主机名
    %e - insert coredumping executable name into filename 添加命令名

②, core文件查询程序断点错误(开放中经常使用)

看这个core文件要是程序员的经验水平越高分析问题越快

参数列表

命令 命令缩写 命令说明
list l 显示多行源代码
break b 设置断点,程序运行到断点的位置会停下来
info i 描述程序的状态
run r 开始运行程序
display disp 跟踪查看某个变量,每次停下来都显示它的值
step s 执行下一条语句,如果该语句为函数调用,则进入函数执行其中的第一条语句
next n 执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句)
print p 打印内部变量值
continue c 继续程序的运行,直到遇到下一个断点
set var name =v 设置变量的值
start st 开始执行程序,在main函数的第一条语句前面停下来
file 文件名 装入需要调试的程序
kill k 终止正在调试的程序
watch x 监视变量值的变化
backtrace bt 产看函数调用信息(堆栈)
frame f 查看栈帧
quit q 退出GDB环境
#!/bin/bash

# 挂载进程
gdb attach PID  

# show threads

info threads

# 切换线程

thread 3

# 设置断点
# 在main.cpp文件第100行处为所有经过这里的线程设置断点。
break main.cpp:100   

# break main.cpp:100 thread all  --> [ERROR]

#backtrace 查看当前运行到第几行。
backtrace


# finsh推出当前调试的函数
#finsh


# 执行下一条语句,如果该语句为函数调用,则进入函数执行其中的第一条语句
step

#执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句)
next

#detach

detach

# 调试

#set scheduler-locking off|on|step,这个是问得最多的。在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。
#off 不锁定任何线程,也就是所有线程都执行,这是默认值。
#on 只有当前被调试程序会执行。
#step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。
 

简单的事例

#include <cstdio>
#include <cstdlib>
#include <cstring>
int main(int argc, char *argv[])
{
	const char * str = "llllllllllll";
    void *p = malloc(343);
    if (p)
    {
            free(p);
            p = NULL;
    }
   	// 非法内存访问 str
    void * ptr = memcpy(p, str, strlen(str));  
    if (!ptr)
    {
            printf("memcpy error\n");
    }

    return 0;
}

gdb 二进制文件 core

3, 查看 进程的文件描述符

  • 设置文件描述符命令

ulimit -n 999999

  • 查看每一个进程的信息

ls -la /proc/32189/fd

4, ps -aux命令详解

Linux ps aux指令詳解

①, linux上进程有5种状态:
  1. 运行(正在运行或在运行队列中等待)
  2. 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号)
  3. 不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生)
  4. 僵死(进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放)
  5. 停止(进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行运行)
②, ps 参数
  1. ps a 显示现行终端机下的所有程序,包括其他用户的程序。
  2. ps -A 显示所有程序。
  3. ps c 列出程序时,显示每个程序真正的指令名称,而不包含路径,参数或常驻服务的标示。
  4. ps -e 此参数的效果和指定”A”参数相同。
  5. ps e 列出程序时,显示每个程序所使用的环境变量。
  6. ps f 用ASCII字符显示树状结构,表达程序间的相互关系。
  7. ps -H 显示树状结构,表示程序间的相互关系。
  8. ps -N 显示所有的程序,除了执行ps指令终端机下的程序之外。
  9. ps s 采用程序信号的格式显示程序状况。
  10. ps S 列出程序时,包括已中断的子程序资料。
  11. ps -t <终端机编号>  指定终端机编号,并列出属于该终端机的程序的状况。
  12. ps u   以用户为主的格式来显示程序状况。
  13. ps x   显示所有程序,不以终端机来区分。
  14. ps -l 較長,較詳細的顯示該PID的信息

ps -lA |more


F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 1 0 0 76 0 - 1193 109952 ? 00:00:03 init
1 S 0 2 1 0 -40 - - 0 migrat ? 00:00:03 migration/0
1 S 0 3 1 0 94 19 - 0 ksofti ? 00:00:00 ksoftirqd/0
1 S 0 4 1 0 -40 - - 0 migrat ? 00:00:02 migration/1
1 S 0 5 1 0 94 19 - 0 ksofti ? 00:00:00 ksoftirqd/1
1 S 0 6 1 0 -40 - - 0 migrat ? 00:00:02 migration/2
1 S 0 7 1 0 94 19 - 0 ksofti ? 00:00:00 ksoftirqd/2
相關信息的意義:
F 進程的標誌(flag),4表示用戶為超級用戶
S 進程的狀態(stat),各STAT的意義見下文
PID 進程的ID
C CPU使用資源的百分比
PRI priority(優先級)的縮寫,
NI Nice值,
ADDR 核心功能,指出該進程在內存的那一部分,如果是運行的進程,一般都是“-”
SZ 用掉的內存的大小
WCHAN 當前進程是否正在運行,若為“-”表示正在運行
TTY 登陸者的終端位置
TIME 用掉的CPU的時間
CMD 所執行的指令
# ps aux |more
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 4772 564 ? S Sep22 0:03 init [3]
root 2 0.0 0.0 0 0 ? S Sep22 0:03 [migration/0]
root 3 0.0 0.0 0 0 ? SN Sep22 0:00 [ksoftirqd/0]
root 4 0.0 0.0 0 0 ? S Sep22 0:02 [migration/1]
root 5 0.0 0.0 0 0 ? SN Sep22 0:00 [ksoftirqd/1]
root 6 0.0 0.0 0 0 ? Ss+ Sep22 0:02 [migration/2]
root 7 0.0 0.0 0 0 ? SN Sep22 0:00 [ksoftirqd/2]
root 8 0.0 0.0 0 0 ? S Sep22 0:00 [migration/3]
root 9 0.0 0.0 0 0 ? SN Sep22 0:00 [ksoftirqd/3]
root 10 0.0 0.0 0 0 ? S< Sep22 0:00 [migration/4]

上述各位解释:

参数 说明
USER 进程的属主;
PID 进程的ID;
PPID 父进程;
%CPU 进程占用的CPU百分比;
%MEM 占用内存的百分比;
NI 进程的NICE值,数值大,表示较少占用CPU时间;
VSZ 进程使用的虚拟內存量(KB);
RSS 该进程占用的固定內存量(KB)(驻留中页的数量);
TTY 该进程在那個終端上運行(登陸者的終端位置),若與終端無關,則顯示(?)。若为pts/0等,则表示由网络连接主机进程
WCHAN 当前进程是否正在進行,若为-表示正在進行;
START 該進程被觸發启动时间;
TIME 該进程實際使用CPU運行的时间;
COMMAND 命令的名称和参数;
STAT 狀態位常見的狀態字符

STAT狀態字符:

D 无法中断的休眠状态(通常 IO 的进程);
R 正在运行可中在队列中可过行的;
S 处于休眠状态;
T 停止或被追踪;
W 进入内存交换 (从内核2.6开始无效);
X 死掉的进程 (基本很少見);
Z 僵尸进程;
< 优先级高的进程
N 优先级较低的进程
L 有些页被锁进内存;
s 进程的领导者(在它之下有子进程);
l 多进程的(使用 CLONE_THREAD, 类似 NPTL pthreads);
+ 位于后台的进程组;

configure配置:

./configure –enable-shared=no –enable-static=yes

cmake配置:

cmake -DBUILD_SHARED_LIBS=NO -DCMAKE_BUILD_TYPE=release

Windows

vs2015 x64编译器为例,cmake命令如下:

Xml代码 收藏代码 cmake -G “Visual Studio 14 Win64” path\to\source\dir
去掉Win64,就是32bit:

Xml代码 收藏代码 cmake -G “Visual Studio 14” path\to\source\dir

另外一种等价方式,用命令行参数-A来指定架构(x64或者ARM):

Xml代码 收藏代码 cmake -A x64 path\to\source\dir

结语

总要讲core文件 分析找错误分析