Linux问题定位tips
1,linux系统安装某个软件例如samba失败,但没有更多的定位信息,怀疑是配置文件有问题,可以用如下命令
#testparm
Load smb config files from /etc/samba/smb.conf
rlimit_max: increasing rlimit_max (1024) to minimum Windows limit (16384)
WARNING: Ignoring invalid value 'share' for parameter 'security'
Error loading services.
2,eclipse使用tomcat
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
-Djava.endorsed.dirs=/usr/local/tomcat/apache-tomcat-7.0.96/endorsed is not supported. Endorsed standards and standalone APIs
in modular form will be supported via the concept of upgradeable modules.
解决办法:
3,与或:
read -p "Do you want to load the config into mysql(only for client),y or n:" var3
if [ $var3 == "y" ] && [[ $pcType == "c" ||$pcType == "C" ]]
then
mysql -uroot -pwww.huanxing.com fstgz < ${base_dir}install/mysql-DataSync-install.sql
fi
4,查看Linux系统的各项极限配置
起因:创建绑定了10000个udp端口,但是报错24 /* Too many open files */,于是开始查看以及重新设置
另外调试信息
1.单个进程默认拥有的资源限制
# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 30748 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 //文件描述符最多是1024个,当然也包括socket pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 30748 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
2,针对某个进程的资源限制
# ulimit -a 32758 //32758号进程的资源限制数
1,修改限制数
方式1:使用命令,但是系统重起后参数恢复.(wxy:另外这种修改方式貌似只能再当前控制台生效)
增加文件描述符的个数
# ulimit -n 30000 //设置n号参数即文件描述符,的默认限制数为3万
# ulimit -n 30000 32758 //针对某个进程设置
方式二:直接修改文件:/etc/security/limits.conf
3,开启
5,进程异常退出
现象1:
Nov 30 17:02:48 one2-asm-hx abrt-hook-ccpp: Process 8921 (ASM_agent_v01000001) of user 0 killed by SIGSEGV - dumping core
原因与解决:
[root@one2-asm-hx log]# echo " * soft core 4194304" >> /etc/security/limits.conf [root@one2-asm-hx log]# echo " * hard core 4194304" >> /etc/security/limits.conf
反汇编用法:
#objdump -SCl [二进制文件] > test.txt
当系统日至出错如下:
Nov 25 21:47:02 one1-asm-hx kernel: ASM_agent[12558]: segfault at 1a4 ip 0000000000447c3a sp 00007fab166f9aa0 error 4 in ASM_agent[400000+d0000]
则可结合得到的汇编代码进行定位,判断是哪里出现的问题
如果是debug模式下,可以用:
(gdb) disas //可以显示当前进程死掉时刻,进程执行到的是那个函数,的堆栈信息
6,常看文件描述符信息
netstat -anutp
7,发现进程启动失败,再定位是读取配置文件(.ini格式)失败,why?
代码中是这样读取配置文件的
string str; //str是string类型,预先保存的参数关键字;此处省略其赋值 fgets(buf,1024,file)==0) //buf是从配置文件中读取的 if(memcmp(str.str.c_str(),buf,strlen)) 或 strncmp(...) continue;
定位:根据如下的打印情况可以发现如下现象:
正常打印buf的时候没问题,但是只取buf的固定长度后会发现首三个字符是特殊的:-17,-69,-65,
char test1[64],test2[64]; size_t strlen = str.length(); memcpy(test1,str.c_str(),strlen); memcpy(test2,buf,strlen); printf("strlen:%d; test1:%s; buf:%s, test2:%s\n",strlen, ele.str.c_str(), buf, test2); //结果:strlen:7; test1:pcType:; buf:pcType:1, test2:pcTy for(int i=0; i< strlen; i++) printf("test1[%d]:%c; test2[%d]:%c.\n",i, test1[i], i, test2[i]); 结果: test1[0]:p; test2[0]:�. test1[1]:c; test2[1]:�. test1[2]:T; test2[2]:�. test1[3]:y; test2[3]:p. test1[4]:p; test2[4]:c. test1[5]:e; test2[5]:T. test1[6]::; test2[6]:y.
解决:
//读取失败的错误文件格式 # file localconfig-master.ini localconfig-master.ini: UTF-8 Unicode (with BOM) text //转换格式命令:将utp-8转化成ascii,同时忽略掉非法字符 iconv -c -f UTF-8 -t ASCII localconfig-master.ini -o localconfig-master.ini //确认格式转化结果 # file localconfig-master.ini localconfig-master.ini: ASCII text, with CRLF line terminators
解决:Linux下使用gedit打开后另存为ascii格式,当然应该还有其他命令方式,待实验
小结:
直接原因:配置文件的格式步是ascii编码,则读出的字符串在进行对比的时候,尽管打印出来是一模一样的,但代码比较是不一样的,于是配置文件中的配置都不识别...
根本原因:这里面涉及到编译原理,对于编译器来说,我们的代码源文件都是会被他进行编译成机器码的,
程序中的"pcType:"这个字符串编译成机器码是什么呢?答:这就要看编码格式了,这个一般取决于编译器,于是这7隔字符以固定的010101....存放在内存中(运行时)
而文件呢?文件本身是有编码格式的,即这7个字符再被执行程序读入到内存中时,同样时按照编码规则以1010101...存方在内存中
所以,不同的编码格式,二者在内存中的存在形式就变得不同,于是使用内存比较这样的函数就会出错,所以要保证格式一致,
另外,我尝试了在程序中用sprintf 和%s将读进来文件打印到缓存中,发现是无法解决的,所以是否还有比较好的方法去主动兼容不同文件类型,还是需要研究
===ss5==============================================
概念:
ss5是SOCKS5协议的官方/开源软件实现,SOCKS5是SOCKS的第5个版本,SOCKS是一种代理协议,具体来说就是,代理分为服务端和客户端,
sock5服务器:一个真正能够访问各种网络的服务器,一般处于海外
sock5客户端:首先按照协议要求有会发送协商报文,包括版本号,认证等,然后代理其他应用和服务端通信
整体工作原理:
sock5代理客户端 --------------------------------------------sock5代理服务器........................真正的服务器,比如facebook等
|
客户端,即各种应用(包括shell的curl,wget,浏览器等,有些应用还需要一些插件协助连接到客户端,比如Privoxy,一般这些应用都配置在和sock5客户端同一台设备上)
实现版本:
sock5协议的实现官方代码为ss5,在此基础上,还有一些其他比较成熟的开软软件比如shadow socks,redsocket等
ss5服务端:
ss5执行文件的路径:
/etc/init.d/ss5
配置参数:
/etc/opt/ss5/ --ss5的一些可选配置参数
/etc/sysconfig/ss5 --ss5的系统级配置参数
设置:set SS5_VERBOSE
iptables -I INPUT -p tcp --dport 1122 -j ACCEPT
参考:
坑1:
shadow socks客户端:
# curl --socks5 127.0.0.1:1080 http://httpbin.org/ip
curl: (52) Empty reply from server
服务器端:[25/Dec/2019:10:52:54 CST] [808212224] 115.192.113.24 "" "" ISERROR - - - (-:- -- -:-) (Socks method unknown or bad request)
定位:
打开更详细的日志信息
#vi /etc/sysconfig/ss5 set SS5_VERBOSE
[25/Dec/2019:11:20:19 CST] [3169261312] [DEBU] [METHOD PACKET] Receiving socks version: 95. //有时候是151...
[25/Dec/2019:11:20:19 CST] [3169261312] [VERB] SOCKS protocol version not supported.
[25/Dec/2019:11:20:19 CST] [3169261312] 115.192.113.24 "" "" ISERROR - - - (-:- -- -:-) (Socks method unknown or bad request)
查看ss5的源码:接收到客户端的报文后,会从中提取信息归入一个_SS5ClientInfo类型的变量ci中
...
recv(ci->Socket,(unsigned short *)&ci->Ver,1,0) <= 0 //从socket的buffer中获取一个字节,表示版本号信息,根据代码显示,这个是tcp data报文(PSH)的第一个字段
...
switch( ci->Ver ) { //解析客户端发送的报文中的Ver信息,即版本信息 case SOCKS4_VERSION: //如果是 4 ... return OK; break; case SOCKS5_VERSION: //如果是 5 ... for(i=0;i<(ci->NMeth);i++) { switch(sd->MethodRequest[i]) { case NOAUTH: ci->NoAuth=OK; break; case USRPWD: ci->BasicAuth=OK; break; case S_USER_PWD: ci->SecureBasicAuth=OK; break; } } ...return OK; break; /* WRONG socks version or SS5SRV request */ default: snprintf(logString,sizeof(logString) - 1,"[%u] [VERB] SOCKS protocol version not supported.",pid); //如果版本既不是4也不是5,则出错 ...return ERR_SRV_REQUEST; break; }
说明: 接收到的报文版本必须是4 或者 5,但实际是95,于是出错,95表示什么呢?就是ss5客户端发送的data报文中的第一个字段,正常来说应该是版本信息,但现在不是! 所以可以肯定是客户端在构造报文的时候出现问题了。
解决:于是在widows下安装Proxifier,OK可以连接了
===========================================================================
使用system()挂载产生的问题
整体逻辑:先执行挂载然后解挂载 x 2,之后再执行挂载则报错,此时使用命令行挂载也会报错,一段时间(大概10分钟),就全部恢复。但是直接在命令行下无论多少次执行都不会有问题。
主要代码:
//挂载 string cmdTmp = ; string cmd2 = GetMountCmd() + " > ./"+configManager.cmdOutputFileName+" 2>&1"; //拼接得到一个挂载执行命令 status=system(cmd2.c_str()); //执行命令 //解挂载 string cmdTmp = GetUMountCmd()+" > ./"+configManager.cmdOutputFileName+" 2>&1"; //拼接得到一个解挂载执行命令 system(cmdTmp.c_str()); //执行命令 代码中打印拼接的命令如下: mount.cifs -o username="hx",password="" "//192.168.1.181/test" "mount1" ---用这个挂载 umount "/home/workspace/video-fst/HXManager/mount1" -t "//192.168.1.181/test" ---用这个解挂载 (Details:"umount \"/home/workspace/video-fst/HXManager/mount1\" -t \"//192.168.1.181/test\" > ./CBFB17D9EE684E2E99832829D62DF520 2>&1")
结果:
Dec 24 11:45:13 localhost journal: (Sparql buffer) Error in task 0 of the array-update: Subject `(null)' is not in domain `nfo:FileDataObject' of property `nfo:fileName'
Dec 24 11:45:13 localhost journal: Could not execute sparql: Subject `(null)' is not in domain `nfo:FileDataObject' of property `nfo:fileName'
再次挂载:
Dec 24 11:46:35 localhost kernel: Status code returned 0xc00000d0 NT_STATUS_REQUEST_NOT_ACCEPTED
Dec 24 11:46:35 localhost kernel: CIFS VFS: Send error in SessSetup = -5
Dec 24 11:46:35 localhost kernel: CIFS VFS: cifs_mount failed w/return code = -5
命令行执行,则报错如下:
mount error(5): Input/output error
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)
定位:
网上说,这个是服务端的原因(windows),是他不接收连接导致的,应该看看服务端的日志