yanbin's Blog
vim 中使用 cscope 的方法。
Find this global definition:
Find functions called by this function:
Find functions calling this function:
Find this text string:
Change this text string:
Find this egrep pattern:
Find this file:
Find files #including this file:
Find assignments to this symbol:
if filereadable("cscope.out")
cs add cscope.out
elseif $CSCOPE_DB != ""
cs add $CSCOPE_DB
endif
1 or g: Find this definition
2 or d: Find functions called by this function
3 or c: Find functions calling this function
4 or t: Find this text string
6 or e: Find this egrep pattern
7 or f: Find this file
8 or i: Find files #including this file
:cs find 3 vim_free
:cscope find 4 initOnce
# line filename / context / line
1 445 src/liboping.c <<ping_receive_one>>
static int ping_receive_one (pingobj_t *obj, const pinghost_t *ph,
2 706 src/liboping.c <<ping_receive_all>>
if (ping_receive_one (obj, ptr, &nowtime) == 0)
<CTRL-\>g # global: find global definition(s) of the token under cursor
<CTRL-\>c # calls: find all calls to the function name under cursor
<CTRL-\>t # text: find all instances of the text under cursor
<CTRL-\>e # egrep: egrep search for the word under cursor
<CTRL-\>f # file: open the filename under cursor
<CTRL-\>i # includes: find files that include the filename under cursor
<CRTL-\>d # called: find functions that function under cursor calls
if filereadable("cscope.out")
cs add cscope.out
elseif $CSCOPE_DB != ""
cs add $CSCOPE_DB
endif
line 45: E568: duplicate cscope database not added
Hit ENTER or type command to continue
自签发 SSL/TLS 证书的方法以及遇到的一些问题
0. 目的
如果签章是正确的,而用户可以相信签署者,之后用户就知道他们可以使用这个密钥,来与密钥的拥有者进行通信。在X.509中规范了这个认证的过程与标准。①
[ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = CN stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = ShangHai localityName = Locality Name (eg, city) localityName_default = ShangHai 0.organizationName = Organization Name (eg, company) 0.organizationName_default = My Company Name organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName_default = May Project
1. 生成 CA root key (根密钥); CA root key 非常重要。
a) 不仅签发或更新 CA root 证书需要。
b) 签发通信双方数字证书时也需要。
$ openssl genrsa -des3 -out root-ca.key 1024
0) 指定了 -des3 选项,openssl 要求输入 pass phrase;
pass phrase 是 root key 的密码;
CA 签发数字证书时需要输入这个密码,算是一种防范措施吧。
程序使用证书和 key 时, 一般会要求输入密码,可以作为用户密码用吗?
2) FIXME: 1024 是 key 的长度目前也支持 2048, 这两个值有很大的区别吗?
key 的长度为 2048 会耗费更多的 CPU 资源吧。
$ openssl req -new -x509 -days 3650 -key root-ca.key -out root-ca.crt -config openssl.cnf
1) 这条命令将两个步骤合二为一。
a) 使用 private key 生成 certificate request; 需要填写证书持有者的信息;
b) 使用 certificate request 签发证书(singed)或自签发证书(self-signed);
任意创建一个目录,创建配置文件(比如: openssl.cnf),也可以签发根证书。
$ mkdir demoCA && cd demoCA
$ touch index.txt
$ echo 01 > serial
$ mkdir private #指定 private_key=/path/to/demoCA/myCA/private/root-ca.key
$ mkdir myCA # 指定 CA_default:dir=/path/to/demoCA/myCA
$ openssl x509 -noout -text -in root-ca.crt
签发服务器证书
0.生成一个 private key, 并且直接用新生成 private key 创建一个 certificate request.
NOTE: -nodes 参数,使用这个参数生成的 key 不需要密码
$ openssl req -newkey rsa:1024 -keyout server01.key -nodes -config openssl.cnf -out server01.req
Country Name (2 letter code) [CN]: State or Province Name (full name) [ShangHai]: Locality Name (eg, city) [ShangHai]: Organization Name (eg, company) [My Company Name]: Second Organization Name (eg, company) [My Company Name]: Organizational Unit Name (eg, section) [My Project]: Common Name (eg, YOUR name) []:*.example.com #CN Email Address []:server01@example.com
NOTE: CN(common name) 可以是 hostname,IP 或者 domain, 与主机信息对应;
也可以用这种形式: *.example.com
CN 指的是 common name, 别与中国的代码弄混了。
# Using configuration from openssl.cnf
Enter pass phrase for /etc/pki/CA/private/root-ca.key: # 输入root key 文件的密码 DEBUG[load_index]: unique_subject = "yes" Check that the request matches the signature Signature ok Certificate Details: Serial Number: 2 (0x2) Validity # FIXME: 默认是一年的有效期吗? # 默认是 365 days 的有效期, 润年会是 366 days. Not Before: Apr 29 15:18:20 2015 GMT Not After : Apr 29 15:18:20 2016 GMT Subject: countryName = CN stateOrProvinceName = ShangHai localityName = ShangHai organizationName = My Company Name organizationName = My Company Name organizationalUnitName = My Project commonName = *.example.com emailAddress = server01@example.com ....... Certificate is to be certified until Apr 29 15:18:20 2015 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
c)-nodes 不需要 key 文件有密码
Country Name (2 letter code) [CN]: State or Province Name (full name) [ShangHai]: Locality Name (eg, city) [ShangHai]: Organization Name (eg, company) [My Company Name]: Second Organization Name (eg, company) [My Company Name]: Organizational Unit Name (eg, section) [My Project]: Common Name (eg, YOUR name) []:client001 EmailAddress []: client001@example.com
Enter pass phrase for /etc/pki/CA/private/root-ca.key: DEBUG[load_index]: unique_subject = "yes" Check that the request matches the signature Signature ok Certificate Details: Serial Number: 2 (0x2) Validity: Not Before: Apr 29 15:18:20 2015 GMT Not After : Apr 29 15:18:20 2016 GMT Subject: countryName = CN stateOrProvinceName = ShangHai localityName = ShangHai organizationName = My Company Name organizationName = My Company Name organizationalUnitName = My Project commonName = client001 emailAddress = client001@example.com ....... Certificate is to be certified until Apr 29 15:18:20 2015 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
参考:
Regex Unicode 笔记
类型安全的 max(), min()
#define max(a, b) \ ({ __typeof__ (a) (_a) = (a); \ __typeof__ (b) (_b) = (b); \ _a > _b ? _a : _b; }) #define min(a, b) \ ({ __typeof__ (a) (_a) = (a); \ __typeof__ (b) (_b) = (b); \ _a < _b ? _a : _b; })
valgrind 简单使用
自动链接,但是要求有, 如果没有 valgrind 不能正常启动内存检查.
程序用到的其他 C 库也要有 debug 版本的。
也可以使用 gcc 的 -O0 编译选项。据说使用了更好。(大写 O, 数字 0)
-g 是表示编译出的二进制代码中包含调试符号
-O0 是 gcc 的默认选项。可能一些低版本的 gcc 需要加上这个选项。
$ gcc -O0 -g example.c -o example
$ valgrind --leack-check=yes ./example arg1 arg2
下面是一个正常分配并正常释放内存的程序用 valgrind 调试的输出:
==733== Memcheck, a memory error detector
==733== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==733== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright
info
# 以下是重要信息;
==733== Command: ./mkdir_t 1/2/3/4
==733==
# 这里可能会有程序的 stdout/stderr 输出;
==733==
# 内存使用状况的汇总;
==733== HEAP SUMMARY:
==733== in use at exit: 0 bytes in 0 blocks
==733== total heap usage: 3 allocs, 3 frees, 18 bytes allocated
==733==
==733== All heap blocks were freed -- no leaks are possible
==733==
# 错误信息汇总;(这里没有错误)
==733== For counts of detected and suppressed errors, rerun with: -v
==733== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
下面是一个越界使用了动态分配的内存, 没有释放动态分配内存的程序的输出;
程序名字是 example, 程序文件名后面的数字说明了 memory allocated 之类的操作的
代码在文件中的位置, 或者说哪里有 memory allocated.
==1058== Invalid write of size 4
# 这里是堆栈跟踪(stack tracking), stack tracking 从下到上读比较容易;
==1058== at 0x40054A: func (example.c:15)
==1058== by 0x400524: main (example.c:8)
==1058== Address 0x51bc068 is 0 bytes after a block of size 40 alloc'd
# 已经到了 malloc 是内存分配的情况;
==1058== at 0x4C29554: malloc (vg_replace_malloc.c:298)
==1058== by 0x40053D: func (example.c:14) # 后面的数字指示了代码所在行
==1058== by 0x400524: main (example.c:8)
==1058==
==1058==
# 内存(HEAP),使用汇总;
==1058== HEAP SUMMARY:
==1058== in use at exit: 40 bytes in 1 blocks
# N allocs, N frees 才正常, 40 bytes allocated 指示分配了多少字节内存;
==1058== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==1058==
# definitely lost 指示了内存泄漏(memory leak);
==1058== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1058== at 0x4C29554: malloc (vg_replace_malloc.c:298)
==1058== by 0x40053D: func (example.c:14)
==1058== by 0x400524: main (example.c:8)
==1058==
# memory leak 汇总;
# definitely, indirectly, possibly 是三种 memory leadk 方式.
==1058== LEAK SUMMARY:
==1058== definitely lost: 40 bytes in 1 blocks # 明确地
==1058== indirectly lost: 0 bytes in 0 blocks # 间接地
==1058== possibly lost: 0 bytes in 0 blocks # 可能性很大地
==1058== still reachable: 0 bytes in 0 blocks
==1058== suppressed: 0 bytes in 0 blocks
==1058==
# 错误信息汇总
==1058== For counts of detected and suppressed errors, rerun with: -v
==1058== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)
make it bigger.
使用 --track-origins=yes 可以看到有关于此的更多的扩展信息,
但是这样也会让程序变得更慢.
For example, it can't detect out-of-range reads or writes to arrays
that are allocated statically or on the stack.
But it should detect many errors that could crash your program
(eg. cause a segmentation fault).
使用 strtok() 函數要注意,這個函數會改變第一個參數的內容
伪随机数函数 rand(); srand() 的简单实现
static unsigned long next = 1; static unsigned long myrand(void) { next = next * 1103515245 + 12345; return ((unsigned)(next/65536) % 32768); } static void mysrand(unsigned long speed) { next = speed; } /* example */ int main(int argc, char **argv) { int j, r, nloops; unsigned long speed; if (argc < 2) { fprintf(stderr, "usage: %s <speed> <nloops>\n", argv[0]); exit(EXIT_FAILURE); } speed = strtol(argv[1], NULL, 10); nloops = atoi(argv[2]); mysrand(speed); for (j = 0; j < nloops; ++j) { r = myrand(); fprintf(stderr, "%lu\n", r); } exit(EXIT_SUCCESS); }
bash 中的 -n 操作符判断某个变量为空时应该加上引号("")
比 alarm() 分辨率更高的 timer: setitimer()
struct timeval it_interval; /* next value */
struct timeval it_value; /* current value */
};
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
Debian 7.6 Wheezy 安装 Intel® Wireless 7260 wifi 模块驱动和固件的方法。
0. 内核以及发行版 Version 信息
Debian 7.6 Wheezy
Linux fyp-tp 3.2.0-4-amd64 #1 SMP Debian 3.2.60-1+deb7u3 x86_64 GNU/Linux
1. 获得 PCI device numbric ID
$ lspci -nn # 可以显示设备号和subsystem ID
....
04:00.0 Network controller [0280]: Intel Corporation Device [8086:08b2](rev 6b)
在下面的网站可以根据设备号(0x808) 和 subsystem ID(0x08b2) 查找到设备型号:
http://pci-ids.ucw.cz/read/PC
可知 wifi 模块的型号是: Intel Wireless 7260
2. google 可知这个 wifi 模块使用 iwlwifi wireless driver。
这个驱动包在 Debain nofree 源中。 使用 Debian nofree 源:
$ sudo echo '# Debian 7 "Wheezy"' >> /etc/apt/sources.list
安装完驱动后,要安装相应的固件,可以在
http://wireless.kernel.org/en/users/Drivers/iwlwifi
找到相应的固件包, 解压后使用 root 用户安装:
$ cp iwlwifi-*.ucode /lib/firmware
3. 但是,Debian提供的 iwlwifi 驱动模块是 3.2.60 Linux Kernel 版本的,
iwlwifi 驱动支持 7260 wifi 模块要求: 最低 Linux Kernel 版本 3.10+.
但是,在 Debian 升级 Linux Kernel 不是一个好的解决方案。
好消息是:可以使用 linux kernel backports 来编译本应该运行在高版本内核的驱动,
编译的得到驱动可以在低版本的内核上运行, 并且支持 wifi 模块。
"If you need to use the current driver on an older kernel, you can use
the compat-drivers project for that. See https://backports.wiki.kernel.org/
for more information."
4. 下载 backports-3.14-1 在 http://drvbp1.linux-foundation.org/~mcgrof/rel-html/backports/
需要打一个 patch: http://www.mail-archive.com/backports@vger.kernel.org/msg01790.html
配置以及安装,参考: https://backports.wiki.kernel.org/index.php/Documentation
#可以只配置 wifi 模块的驱动:
$ make defconfig-wifi
#可以选择只编译 iwlwifi
$ make menuconfig
[*] Wireless LAN --->
Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi)
$ make
$ sudo make install
5. 在 http://wireless.kernel.org/en/users/Drivers/iwlwifi 下载:
iwlwifi-7260-ucode-22.1.7.0.tgz
iwlwifi-7260-ucode-22.24.8.0.tgz
iwlwifi-7260-ucode-23.214.9.0.tgz
三个固件包并且安装到 /lib/firmware
如果没有安装固件的话, dmesg 信息中会有 iwlwifi-7260-7.ucode 找不到之类的信息.
没有测试是否也需要 iwlwifi-7260-9.ucode. (我在安装 iwlwifi 驱动之前就安装了这个固件)