本菜鸟写了一个server,经长时间激烈的测试以后,终于要在测试环境供外部使用了。经过一天激烈的打包,一枚rpm终于诞生了。上传到公司的yum包仓库,当PE同学部署时遇到了问题。程序在启动过程中莫名地core掉了,屡试不爽。使用gdb查看core文件的程序堆栈,发现程序core在了一个我从来没有修改过的类的析构函数中,core的直接原因就是C/C++程序员的老朋友Segmentation fault同学。查看该析构函数,里面只做了两个操作,简单讲,就是释放对象内存的两个delete。其中一个对象是在类的构造函数中创建,另外一个对象是在其他初始化函数startup中创建。析构函数中理所当然地对这两个对象的指针进行判断,非NULL则delete。这个类很特殊,正常情况下需要调用startup进行初始化,然后作为一个持久的对象使用。也可以不进行初始化,调用其他接口,然后销毁。我使用该类的场景就属于后者。在之前的测试过程中,core dump从未发生。

Tags: .

  lsof, LiSt Opened Files, 列出打开的文件, 听起来很简单的样子. 但想*nix中很多其他工具一样, lsof把这件简单的事情做到了炉火纯青. 因为Unix认为”一切皆文件”, 那么”打开的文件”就不仅仅是传统意义上打开的文件了, 还可以是网络/Unix域套接字, 匿名/具名管道, 共享库文件, 目录文件, 设备文件等等. 很多场景下, 查看进程或系统打开的文件会给调试带来极大的帮助. 下面简单地介绍lsof常被使用的功能选项.

  • lsof : 简单地执行lsof会列出当前系统中所有被打开的文件, 但为了看到完整的信息, 通常需要具有root权限;
  • lsof -u dutor : 列出用户dutor打开的文件, 可指定多个用户, 默认是OR的关系;
  • lsof -c tair : 列出名称以tair开头的进程打开的文件, c for command, 可指定多个;
  • lsof -c /^t.*r$/ : 列出名称以t开头, r结尾的进程打开的文件;
  • lsof -p 12315 : 列出进程号为12315的进程打开的文件, 可指定多个;
  • lsof server.log : 列出打开server.log文件的进程, 可指明多个文件;
  • lsof . : 列出打开当前目录的进程;
  • lsof +D . : 递归地列出当前目录中被打开的文件, 当然也可以lsof | grep `pwd`;
  • lsof -i : 列出打开的套接字;
  • lsof -i tcp : 列出打开的tcp套接字;
  • lsof -i :5198 : 列出打开5198端口的进程;
  • lsof -i :ssh : 列出打开22端口的进程;
  • lsof -i tcp:5198 : 列出打开5198号tcp端口的进程;
  • lsof -U : 列出打开Unix域套接字的进程;
  • lsof -d 0-2 : 列出在0到2文件描述符上打开文件的进程;
  • lsof -d mem : 列出打开映射文件的进程;
  • lsof -d txt : 列出打开的可执行文件.
Tags: .

  前几天,在组内分享了关于链接器的一些东西,在这里总结一下。讨论的背景主要是基于C/C++,Linux平台相关。

Tags: ,,.

  关于ssh还有两点需要说明一下。若想登录时免去输入密码,只需要在目标主机上相应用户的~/.ssh/authorized_keys中追加本地主机的公共密钥即可。另外,如果出现登录速度极慢的情况,抛开网络原因,可能是因为目标主机sshd的反向域名解析(由IP查找域名)导致的。反向域名解析可能是出于安全的考虑,但我也没有深究。很多人给出的解决方法是在目标主机上面修改sshd的配置文件/etc/sshd_config,但这对于我来说有些不切实际(大部分主机是很多用户共享的,而且我也不负责主机维护)。试验发现,在本地的~/.ssh/config文件中加入GSSAPIAuthentication no也可以解决这个问题。
  最后,使用这个脚本的使用大概是这个样子滴,

1
2
3
4
5
6
7
local~$ ./mysh.sh 
1) devel
2) test
host to connect> 1
Password:
# here are login messages
remote~$
Tags: .

  Linux中,每个进程有一个pid,类型pid_t,由getpid()取得。Linux下的POSIX线程也有一个id,类型pthread_t,由pthread_self()取得,该id由线程维护,其id空间是各个进程独立的(即不同进程中的线程可能有相同的id)。你可能知道,Linux中的POSIX线程库实现的线程其实也是一个进程(LWP),只是该进程与主进程(启动线程的进程)共享一些资源而已,比如代码段,数据段等。
  有时候我们可能需要知道线程的真实pid。比如进程P1要向另外一个进程P2中的某个线程发送信号时,既不能使用P2的pid,更不能使用线程的pthread id,而只能使用该线程的真实pid,称为tid。
  有一个函数gettid()可以得到tid,但glibc并没有实现该函数,只能通过Linux的系统调用syscall来获取。使用syscall得到tid只需一行代码,但为了加深各位看官的印象,简单提供下面场景。
  有一簇进程,其中一个进程中另外启了一个线程。各进程共享一个数据结构,由shared_ptr指明,其中保存有线程的tid。在各个进程的执行过程中,需要判断线程是否存在,若不存在则(重新)创建。

Tags: ,.

FastCGI

  于是,FastCGI,另一种类似的协议被提出了。顾名思义,该协议的提出就是要克服普通CGI程序性能低下的缺点,同时又具备普通CGI的所有优点。通信方式上,FastCGI与CGI大同小异,主要区别在于:

  • FastCGI程序通常以Daemon方式运行,只启动一次,接下来便可以持续地接受来自WebServer的请求;
  • FastCGI程序与WebServer以网络方式通信,FasCGI监听TCP服务端口或建立Unix Socket,WebServer将请求转发给FastCGI;
  • 由于采用网络方式通信,因而允许WebServer和FastCGI程序的分布式部署;

  接口方面,有很多针对不同语言的FastCGI开发套件,保证了FastCGI与普通CGI具有很大的兼容性,普通CGI程序作极小的改动便可以以FastCGI的形式运行。

Tags: ,.
  • 外向(E)与内向(I) 外向的人乐于与人交往并参加社会活动。内向的人则不是,他们具有领地意识,需要私人的精神和环境空间。内向的人从独立的活动中获取力量,厌倦社会活动。百分之七十五的人偏向于外向型,剩下百分之二十五的人则希望单独呆着。
  • 感觉(S)与直觉(N) 你如何获取信息?在所有人格特质中,这条轴线可能最容易产生误传和误解。感觉型的人强调可行性和事实,完全基于当时的细节。直觉型的人非常富有想象力,喜欢比喻,创新力强,能够看到多种可能性——生活总是在下一个拐角等着我们。直觉型可能还没有等到完成手头上的事情就跳到一项新任务上去了。感觉型的人认为这种做法浮躁,直觉型的认为感觉型迂腐。百分之七十五的人属于感觉型的。
  • 思考(T)与情感(F) 你如何做决定?思考型的人基于规则。情感型的人除了考虑适当的规则之外,还会评估个人情感的影响。对于情感型的人来说,思考型的人对规则的严格遵守看起来十分冷血。而思考型的人却认为情感型的人太感情用事。两种类型的人在人群中各占一半。不过在性别方面有些倾向性,即较多女性是F型,男性则更多是T型。
  • 判断(J)与知觉(P) 你的决定是封闭的还是开放的?即,你是快速做出判断还是持续感知?如果你非常喜欢早下定论,你就是J型。J型直到做出结论才会感觉舒服。P型则是会在做出决定之后感到不安。两种类型的人在人群中各占一半。
Tags: .

  场景是这样的。我在写一个Nginx模块,该模块使用了MySQL的C客户端接口库libmysqlclient,当然mysqlclient还引用了其他的库,比如libm, libz, libcrypto等等。对于使用mysqlclient的代码来说,需要关心的只是mysqlclient引用到的动态库。大部分情况下,不是每台机器都安装有libmysqlclient,所以我想把这个库静态链接到Nginx模块中,但又不想把mysqlclient引用的其他库也静态的链接进来。
  我们知道gcc的-static选项可以使链接器执行静态链接。但简单地使用-static显得有些’暴力’,因为他会把命令行中-static后面的所有-l指明的库都静态链接,更主要的是,有些库可能并没有提供静态库(.a),而只提供了动态库(.so)。这样的话,使用-static就会造成链接错误。
  在StackOverflow上面提了How to do partial linking这个问题,但两天都没人搭理我,大概那些哥们儿也像中国人一样,圣诞狂欢呢吧。但最后一个叫Employed Russian的哥们给了一个链接,和我的问题相似(你很少能遇到独一无二的问题)。这个帖子唯一的一个解答解决了问题。
  我之前的链接选项大致是这样的,

1
CORE_LIBS="$CORE_LIBS -L/usr/lib64/mysql -lmysqlclient -lz -lcrypt -lnsl -lm -L/usr/lib64 -lssl -lcrypto"
Tags: .

  这两天研究Nginx模块的实现机制,目的是写一个自己的module。调试过程中遇到一个诡异的问题,解决后发现是一个极小的失误,但这个’小臭虫’花掉我将近四个小时。
  最终发现,问题起因于ngx_snprintf函数,这是Nginx自己实现的,类似C标准库中snprintf的一个函数(这是一个用户空间的函数 )。ngx_snprintf的原型为,

1
2
3
//~ core/ngx_string.h
u_char * ngx_cdecl
ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...);

  问题确实很简单,调试并找出问题本也不应该太难。但遇到问题时,我首先想到的是自己对Nginx不是太熟悉,将注意力放在了周边环境,以为是对Nginx各模块的调用链不熟悉导致的。调试真是门学问,更多的是靠大量的代码经验和由此获得的面对问题的一种’直觉’。对,’直觉’,小工没有太多经验,需要很多规则来参照,专家却站在规则之上,靠直觉就可快速地定位、解决问题。

Tags: .

  甚至可以可以使用nc建立文件的中转站。比如,从host1无法直连到host3,只能先连到host2再间接连到host3。如果想从host1向host3传输文件,可以在host2上面建立中转。每次直接传输是client/server还是server/client,都可以实现(当然,如果两台机器有防火墙相隔时,就另说了):

1
2
3
4
dutor@host2 $ nc -l 5198 | nc -l 5191
dutor@host2 $ # 使用 while true; do nc -l 5198 | nc -l 5191; done 可以建立持久的'中转站'
dutor@host1 $ nc host2 5198 < stuff.tgz
dutor@host3 $ nc host2 5191 | tar xzvf -

  nc是一个简单,强大,又可以信手拈来的工具,尽情发挥你的想象力吧。

Tags: ,.
Page 3 of 3312345678910...2030...Last »