昨天在跟踪busybox中一个后台进程源码的启动问题时,由于不确定输出有没有被重定向,为了快速解决问题,信手拈来写了一个一样的log宏,放在源码中一些关键的位置,跟踪源码的走向非常有用,且高效,一下子就找到问题症结所在了。
#include <stdio.h>
#include <stdlib.h>
#define LOG_LINE() do{char a[99]={0};snprintf(a,sizeof(a),"echo %d > /dev/console",__LINE__);system(a);}while(0)
然后在一下想要跟踪的关键位置使用
LOG_LINE()
编译运行程序,就可以根据打印的行号来跟踪问题出在哪里了,可以在echo
后面添加一些容易识别的标识,以方便在众多log中一眼认出。
该宏短小精炼,问题跟踪解决后清理代码也很方便。
Jacob Pan ( jacobpan3g.github.io/cn )
Qt是一个跨平台的GUI库,接口用C++呈现,支持Windows,Linux,Mac,据说还支持Android,若开发桌面应用需要考虑支持跨平台,Qt是一个不错的解决方案。
需要在windows下搭建qt开发环境,有以下几种选择:
qt-opensource-windows-x86-msvc201x-x.x.x
qt-win-opensource-x.x.x-mingw.exe
我比较偏向选择方案2,因为qtCreator本身就是用qt实现的IDE,用其来设计qt应用更加有qt的感觉,同时,熟悉了qtCreator后,以后转到Linux或Mac开发qt程序,也可以继续使用qtCreator。而编译器方面,在windows下开发,个人比较推荐还是用微软提供的visual studio里的编译工具,而方案3的MinGw编译器是一套windows下的gcc,若你更加偏向于gcc,也可以采用方案3。
qt包的下载地址是:download.qt.io
我采用vs2013作为编译器,选用qt5.6,因此下载的qt包是: qt-opensource-windows-x86-msvc2013-5.6.3.exe
ps: qt5.9是长期支持版本,不过比较大,要2G,大家可以选择按需选择
在安装qt包之前,需要先在PC安装好visual studio,再安装qt包,安装完成后会自带qtCreator,并且会自动检测当前系统下所有qt版本与编译器版本,在“Tool” - “Options” - “Build & Run”页面可以查看到,如下如:
同理,在同页面下的”Compilers”标签里可以看到本系统所安装的编译器。
若这已安装的qt版本和比那一起,但这两个页面里没有出现,可以通过右边的Add
来添加。
ps: 这里需要提一下“Kits”标签页,这个是可以自定义”qt版本+编译器”组合,即当你系统安装多个不同qt版本或不同的编译器,可以通过kits设置你需要的组合,用来编译qt应用。
环境搭好后,新建一个qt工程,“File” - “New File or Project”, 点击“Choose”按钮,输入工程名字并选好路径,点击“Next”,这里就可以选择相应的kits(ps:第二节的ps提到),然后一路点击”Next”按钮,新工程建立完成。
点击左下角的三角形编译运行,弹出一个空白的窗口,就证明qt环境搭建成功。
入门:看完这个就可以基本了解如何使用QT开发GUI程序,完成入门
进阶:不过这个是基于Qt4的,与Qt5有一定的差距,网上有《C++ GUI Qt5 编程》的英文版,有需要的话可以找来看看。由于Qt5比较新,目前大部分资料都是Qt4的
syslog是linux下内置的一种log工具,十分实用。实现了log到文件,log到内存,循环打印log,log优先级,开发程序过程借助其来定位bug非常方便,比单纯的printf()
强大多了,特别对于输出被重定向的后台进程。
这里我会采用busybox 1.19.4的syslog来示范,由于这个版本是专门给嵌入式设备使用的,因此有一些功能被精简掉了,如syslog.conf,该版本不支持配置文件,所有配置都在启动syslogd守护进程时通过参数输入。
要使用syslog需要启动一个后台进程syslogd,可以通过多种方式打印log
log到文件里
syslogd -O /tmp/syslog.log
请注意这个log文件会随着log增加而越来越大,需要和logrorate的配合来控制log文件的大小,对于没有logrorate的嵌入式设备,有可能被占据所有空间,因此不太推荐
log到内存
syslogd -C4
这样可以通过制定特定大小的内存来保存log,存满了会自动把最旧的那一条删去,通过logread
可以把log读取出来。比较推荐这种方式,一则可以制定固定大小的内存(单位是kb,-C4
代表为log预留4kb的缓存空间),不用担心把所有内存耗掉,二则通过logread
可以实时观测log(下文会介绍logread
的使用)
log到服务器,这个需要和局域网内的log服务器配合使用,具体本文先不涉及
log一共有8个不同优先级,方便在不同场景下的过滤显示:
一般情况下,用得最多的是err,notice,info,debug这四种信息,在release版本,info和debug信息不会被打印。其中err和debug信息不言而喻,根据个人的经验,notice和info消息的区别是:
设置syslogd打印log过滤可以在启动守护进程时通过选项-l N
设置, N的范围是1-8
syslogd -C4 -l 6
上述命令只答应notice或以上(<6)的信息,这是release时的设置,一旦设置后就不能修改,因此,当开发或debug时可重启syslogd守护进程,通过-l 8
把所有的log都打印。
ps: 更多的syslogd参数可参看syslogd -h
守护进程通过syslogd -C4
启动后,可以通过logread读取log
logread
logread -f
在程序中,可以通过一下接口使用syslog
#include <syslog.h>
void openlog(const char *ident, int option, int facility);
void syslog(int priority, const char *format, ...);
void closelog(void);
void vsyslog(int priority, const char *format, va_list ap);
其中,syslog()
第二个参数就是log的内容,而第一个参数priority
就是上述的八个优先级,对应下面的8个宏:
LOG_EMERG
LOG_ALERT
LOG_CRIT
LOG_ERR
LOG_WARNING
LOG_NOTICE
LOG_INFO
LOG_DEBUG
还有,openlog()
中第一个参数ident
一般传入进程名作为log标识,而第二、三个参数一般会使用LOD_PID
和LOD_USER
,具体可以通过man openlog
查看。
#include <syslog.h>
int main()
{
openlog("log_test",LOG_PID,LOG_USER);
syslog(LOG_INFO,"PID information, pid=%d\n",getpid());
syslog(LOG_DEBUG,"debug message");
closelog();
return 0;
}
编译运行后,通过logread就可以看到以下的log
Dec 8 15:23:42 jpei user.info log_test[6741]: PID information, pid=6741
Dec 8 15:23:42 jpei user.debug log_test[6741]: debug message
logger是syslog提供的shell工具,通过logger可以设置优先级,进程名,把log打印到缓存区中,与通过C接口的log一样,可以通过logread读取出来,具体可以参看logger -h
。
syslogd守护进程无法启动
在busybox源码添加打印,经分析,原来是syslogd守护进程的PID路径问题,源码中默认PID路径是/var/run/syslogd.pid
,在我开发的嵌入式设备中文件系统是只读的,只有/tmp
可写,把PID路径改成/tmp/syslogd.pid
就syslogd就可以运行了。
Jacob Pan ( jacobpan3g.github.io/cn )
Ubuntu下
# apt-get install subversion
# update-alternatives --config editor
会出现下面选项供选择:
There are 4 choices for the alternative editor (providing /usr/bin/editor).
Selection Path Priority Status
------------------------------------------------------------
0 /bin/nano 40 auto mode
1 /bin/ed -100 manual mode
2 /bin/nano 40 manual mode
* 3 /usr/bin/vim.basic 30 manual mode
4 /usr/bin/vim.tiny 10 manual mode
Press <enter> to keep the current choice[*], or type selection number:
选择自己想要的编辑器,再按回车便可。
也可以通过svn配置文件~/.subversion/config
修改默认编辑器,找到editor-cmd
注释的位置,新增一行editor-cmd=vim
默认情况下so文件是不提交的,在配置文件~/.subversion/config
找到global-ignores
,把注释去掉,同时把里面的*.so *.so.[0-9]*
去掉。
这样就可以通过svn命令查看,添加,提交so文件了。
Jacob Pan ( jacobpan3g.github.io/cn )
Ubuntu下的工作区功能感觉挺有用的,可以多个桌面同时切换
在ubuntu16.04中默认没有打开,通过 Settings
-> Appearabce
-> Behavior
中勾选Enable workspaces
<ctrl alt> 方向键
可以直接切换工作区<win> s
先预览全部工作区,再通过方向键切换Jacob Pan ( jacobpan3g.github.io/cn )
# apt-get install jekyll
# apt-get install openssh-server
Jacob Pan ( jacobpan3g.github.io/cn )