分类目录归档:开发

编译chromium的一些记录

这两个命令用来编译release版本的二进制文件

gn gen out/release –args=”is_component_build=false is_debug=false”

ninja -C out/release nginx-1.18.0_ipdb

默认系统头文件和依赖库

build/linux/debian_sid_amd64-sysroot 这个目录相当于根目录, usr/lib和usr/include 分别放了依赖库和头文件

chromium移除了这两个文件,不知道为何, 会导致nginx 编译失败,目前解决办法是从旧版本拷贝过去

build/linux/debian_sid_amd64-sysroot/usr/lib/x86_64-linux-gnu/libcrypt.so

build/linux/debian_sid_amd64-sysroot/usr/include/crypt.h

修改编译参数

build/config/compiler/BUILD.gn, 比如nginx 可能需要把这个特性关掉

if (!is_nacl && !use_libfuzzer) {
#cflags += [ “-Wunreachable-code” ]
}

编译方式

executable(“fssnginx-1.18.0_ipdb”) {
sources = [
“/root/fssnginx/nginx-1.18.0/objs/ngx_modules.c”,
“/root/fssnginx/nginx-1.18.0/src/core/nginx.c”,

….

]

include_dirs = [
“/root/fssnginx/nginx-1.18.0/src/core”,
“/root/fssnginx/nginx-1.18.0/src/event”,
“/root/fssnginx/nginx-1.18.0/src/event/modules”,
“/root/fssnginx/nginx-1.18.0/src/os/unix”,
“/root/fssnginx/nginx-1.18.0/nginx_upstream_check_module-master”,
“/root/fssnginx/nginx-1.18.0/ngx_devel_kit-0.3.0/objs”,
“/root/fssnginx/nginx-1.18.0/objs/addon/ndk”,
“/root/fssnginx/nginx-1.18.0/lua-nginx-module-0.10.13/src/api”,
“/root/fssnginx/nginx-1.18.0/pcre-8.42”,
“/root/fssnginx/nginx-1.18.0/zlib-1.2.11”,
“/root/fssnginx/nginx-1.18.0/objs”,
“/root/fssnginx/nginx-1.18.0/src/http”,
“/root/fssnginx/nginx-1.18.0/src/http/modules”,
“/root/fssnginx/nginx-1.18.0/src/http/v2”,
“/root/fssnginx/nginx-1.18.0/src/http”,
“/root/fssnginx/nginx-1.18.0/ngx_devel_kit-0.3.0/src”,
“/root/fssnginx/nginx-1.18.0/ngx_devel_kit-0.3.0/src”,
“/root/fssnginx/nginx-1.18.0/ngx_devel_kit-0.3.0/objs”,
“/root/fssnginx/nginx-1.18.0/objs/addon/ndk”,
“/root/fssnginx/nginx-1.18.0/luajit/include/luajit-2.0”,
“/root/fssnginx/nginx-1.18.0/quic_module/chromium”,
]
deps = [
“:epoll_quic_tools”,
“:epoll_server”,
“:net”,
“:simple_quic_tools”,
“//base”,
“//third_party/boringssl”,
]
lib_dirs = [
“/root/fssnginx/nginx-1.18.0/json-c/lib”,
“/root/fssnginx/nginx-1.18.0/luajit/lib”,
]
libs = [
“/root/fssnginx/nginx-1.18.0/pcre-8.42/.libs/libpcre.a”,
“/root/fssnginx/nginx-1.18.0/zlib-1.2.11/libz.a”,
“luajit-5.1”,
“json-c”,
“crypt”,
]
cflags_c = [
“-D_FORTIFY_SOURCE=2”,
“-DTCP_FASTOPEN=23”,
“-DNDK_SET_VAR”,
]
}

chromium指定tags 版本下载

线上有个业务需要使用到指定版本的chromium源代码, 这里记录下

一、安装 depot_tools 项目构建工具

  1. 克隆 depot_tools git仓库
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

  1. 添加环境变量
$ export PATH="$PATH:/path/to/depot_tools"

Tip: /path/to/depot_tools, 为你 depot_tools 本地的路径

二、使用 depot_tools 下载源码

  1. 创建一个用于存在 chromium 的目录 (您可以任意命令,并存放在任何您喜欢的位置,只要是路径路径并且没有空格即可)
$ mkdir chromium && cd chromium

  1. 使用 depot_tools 的 fetch 命令,来检查代码及其依赖关系。
$ fetch  chromium
//Don't use fetch --no-history chromium, 我们需要切换到历史版本

Tip: –no-history: 代表不需要历史记录, 完整仓库大约40G 源码大小大概 8G 左右,下载时间因网速而议,请耐心等待

三、切换到指定的tags

# Make sure you are in 'src'.
# This part should only need to be done once, but it won't hurt to repeat it. The first
# time checking out branches and tags might take a while because it fetches an extra
# 1/2 GB or so of branch commits. 
gclient sync --with_branch_heads --with_tags

# You may have to explicitly 'git fetch origin' to pull branch-heads/
git fetch

# Checkout the branch 'src' tree.
git checkout -b branch_$BRANCH tags/$BRANCH

# Checkout all the submodules at their branch DEPS revisions.
gclient sync --with_branch_heads --with_tags

到这一步做完就可以校验下了

$cat chrome/VERSION

参考文档:

https://www.chromium.org/developers/how-tos/get-the-code/working-with-release-branches

https://github.com/aidevjoe/ChromiumBuild

bind 筛选记录query_log

这边有个需求, 让bind 的query_log 只记录ipv4的A记录请求

解决办法:

修改代码query.c 里边记录query_log的部分, 增加一个 客户端query.qtype的判断

--- bind-9.11.14/bin/named/query.c      2019-12-12 13:17:55.000000000 +0800
 +++ bind-9.11.14.mod/bin/named/query.c  2020-03-05 16:57:31.766000000 +0800
 @@ -9548,8 +9548,6 @@
                 return;
         }
 if (ns_g_server->log_queries)
 log_query(client, saved_flags, saved_extflags);
 /*  * Check for meta-queries like IXFR and AXFR.
 @@ -9559,6 +9557,10 @@
     client->query.qtype = qtype = rdataset->type;
     dns_rdatatypestats_increment(ns_g_server->rcvquerystats, qtype);
 if ( (ns_g_server->log_queries) && (client->query.qtype == dns_rdatatype_a) ){
 log_query(client, saved_flags, saved_extflags);
 }
 +
     log_tat(client);
 if (dns_rdatatype_ismeta(qtype)) { 

qtype 分以下种类

enum {
	dns_rdatatype_none = 0,
	dns_rdatatype_a = 1,
	dns_rdatatype_ns = 2,
	dns_rdatatype_md = 3,
	dns_rdatatype_mf = 4,
	dns_rdatatype_cname = 5,
	dns_rdatatype_soa = 6,
	dns_rdatatype_mb = 7,
	dns_rdatatype_mg = 8,
	dns_rdatatype_mr = 9,
	dns_rdatatype_null = 10,
	dns_rdatatype_wks = 11,
	dns_rdatatype_ptr = 12,
	dns_rdatatype_hinfo = 13,
	dns_rdatatype_minfo = 14,
	dns_rdatatype_mx = 15,
	dns_rdatatype_txt = 16,
	dns_rdatatype_rp = 17,
	dns_rdatatype_afsdb = 18,
	dns_rdatatype_x25 = 19,
	dns_rdatatype_isdn = 20,
	dns_rdatatype_rt = 21,
	dns_rdatatype_nsap = 22,
	dns_rdatatype_nsap_ptr = 23,
	dns_rdatatype_sig = 24,
	dns_rdatatype_key = 25,
	dns_rdatatype_px = 26,
	dns_rdatatype_gpos = 27,
	dns_rdatatype_aaaa = 28,
	dns_rdatatype_loc = 29,
	dns_rdatatype_nxt = 30,
	dns_rdatatype_srv = 33,
	dns_rdatatype_naptr = 35,
	dns_rdatatype_kx = 36,
	dns_rdatatype_cert = 37,
	dns_rdatatype_a6 = 38,
	dns_rdatatype_dname = 39,
	dns_rdatatype_opt = 41,
	dns_rdatatype_apl = 42,
	dns_rdatatype_ds = 43,
	dns_rdatatype_sshfp = 44,
	dns_rdatatype_ipseckey = 45,
	dns_rdatatype_rrsig = 46,
	dns_rdatatype_nsec = 47,
	dns_rdatatype_dnskey = 48,
	dns_rdatatype_dhcid = 49,
	dns_rdatatype_nsec3 = 50,
	dns_rdatatype_nsec3param = 51,
	dns_rdatatype_hip = 55,
	dns_rdatatype_spf = 99,
	dns_rdatatype_unspec = 103,
	dns_rdatatype_tkey = 249,
	dns_rdatatype_tsig = 250,
	dns_rdatatype_dlv = 32769,
	dns_rdatatype_keydata = 65533,
	dns_rdatatype_ixfr = 251,
	dns_rdatatype_axfr = 252,
	dns_rdatatype_mailb = 253,
	dns_rdatatype_maila = 254,
	dns_rdatatype_any = 255
};

参考文档:

https://users.isc.org/~each/doxygen/bind9/structns__query.html

https://ri.co.cr/training/dccom/bind-9.8.2/lib/dns/include/dns/enumtype.h

谈谈 XOPEN_SOURCE

最近维护一个古老代码的时候,在AS7里边编译的时候出现了不少错误,比如:

warning: comparison between pointer and integer, 这是代码 strptime(current_time, “%a%n%b%n%d%n%H:%M:%S%n%Y”, &tm) == NULL) 产生的

还有, warning: incompatible implicit declaration of built-in function ‘snprintf’, 这是类似 snprintf(path, sizeof(path), “%s/arc_%s”, archdir, com->cat) 的代码产生的

查了下,strptime的异常返回值确实是NULL, http://man7.org/linux/man-pages/man3/strptime.3.html

If strptime() fails to match all of the format string and therefore an error occurred, the function returns NULL.

一般来说, 类似的snprintf错误 添加 #include<stdlib.h>就好,但是这个古老代码里边已经有这个了

在代码的开头发现了这个东西

define _XOPEN_SOURCE

       _XOPEN_SOURCE
              Defining this macro causes header files to expose definitions as
              follows:

              o  Defining  with  any  value  exposes definitions conforming to POSIX.1, POSIX.2, and XPG4.

              o  The value 500 or greater additionally exposes definitions for SUSv2 (UNIX 98).

              o  (Since  glibc  2.2)  The  value  600  or greater additionally exposes  definitions  for   SUSv3   (UNIX   03;   i.e.,   the POSIX.1-2001  base  specification plus the XSI extension) and C99 definitions.

              o  (Since glibc 2.10) The  value  700  or  greater  additionally exposes  definitions  for  SUSv4 (i.e., the POSIX.1-2008 base specification plus the XSI extension).

https://linux.cn/man7/feature_test_macros.7.html, 初略的说,大概是不同的值会影响某些函数和库的一些标准行为,而默认的_xopen_soure 不带参数会被认为是<500

#define _XOPEN_SOURCE        /* or any value < 500 */

所以需要修正这个模式,添加一个标准即可,由于代码比较古老,修改为500和600都可以编译通过

nginx spdy patch for 1.14.0 1.13.12

spdy 协议由于安卓碎片化的存在 暂时还是需要保留一段时间的兼容性

准备升级到nginx1.14的时候发现 work process 会自动 退出, 同时系统日志有 nginx segfault的信息

修改配置,抓取coredump信息,需要做以下内容
nginx 增加

worker_rlimit_core 5000M;
working_directory /path/to/cores/;
$> ulimit -c unlimited
$> mkdir /opt/coredump/ && chown nobody.nobody /opt/coredump/ # 先建目录,还要确认nginx用户可以写此目录
$> echo “/opt/coredump/core-%e-%p-%h-%t” > /proc/sys/kernel/core_pattern

拿到coredump文件后使用gdb分析

gdb /path/to/nginx /path/to/cores/nginx.core
backtrace full

发现问题指向了
src/http/ngx_http_spdy.c:ngx_http_spdy_state_read_data 的
buf->last = ngx_cpymem(buf->last, pos, size);

简单调试发现buf->last是个0, ngx_cpymem会因为内存越界导致coredump

而分析代码 + gdb 断点调试 看到初始化r->request_body->buf的部分: ngx_http_spdy_init_request_body(r) 并未执行

打印r->request_body 内容发现这块被初始化了,对比nginx1.12.2和1.10.3版本发现旧版本则是未做初始化

翻了下调用的部分:ngx_http_request_body: ngx_http_read_client_request_body 可以看到在nginx 1.13.12版本开始会对r->request_body 做了初始化操作,这部分直接导致了SPDY 补丁 的不兼容

所以答案就很简单了,修改下判断条件即可

新补丁放在了:https://github.com/favortel/nginx_patch/blob/master/nginx-1.14.0_spdy_h2.patch
参考文档:
https://toontong.github.io/blog/nginx-gdb-coredump-segfault.html
https://www.nginx.com/resources/wiki/start/topics/tutorials/debugging/
http://lxr.nginx.org/source/src/http/ngx_http_request_body.c
http://lxr.nginx.org/source/src/http/ngx_http_request_body.c?v=nginx-1.12.2

gcc 与 ld 的lib顺序

事情是这样子的,有个编译出来的.so文件,死活在找一个诡异版本的libcrypto.so,而我检查过环境变量和编译参数还有ldconfig,并未包含这些东西
绕了一个大圈子,查找编译文件并未包含这些路径,最后在简化测试的时候发现了问题所在
#ld -shared -o test.so -lcrypto
极为简单的一个测试,发现在故障机器上编译出来的.so还是包含了错误的libcrypto.so
strace下发现了问题,这是因为ld有个依赖顺序:
“/usr/x86_64-redhat-linux/lib64/”,”/usr/local/lib64/”, “/lib64/”,/usr/lib64/, /usr/x86_64-redhat-linux/lib/ , /lib/ , /usr/lib/

而刚巧,这机器在/usr/local/lib64/被不知名土人放了个错误版本的libcrypto.so

另外,补充下,如果用了-L参数指定路径,那么这个路径则是最优先的

而LD_LIBRARY_PATH 则是执行时查找的动态链接库位置,跟ldconfig功能一样,不影响编译,因此以上例子查找ldconfig是不必要的

而最重要的是解决问题的思路,分割问题==>缩小范围==>定位问题!

python 替换\n

一般来说,python可以通过strip() 或者replace(‘\n’,”)的方式来替换掉\n 字符

不过改动某个功能代码的时候异常的发现两种替换方式都失败了,debug定位了下,发现数据是通过readlines()的方式读取进来的
而readlines 会自动的把字符中的\r\n 更改为 \\r\\n,从而导致替换失败

嗯,如果是readlines的数据,只能用replace(‘\\n’,”)了
当然,不要用readlines比较好

半吊子的程序员之: python 抓不到的execpt

最近写了个try except的时候,发现每次都出现except,但是注释掉try except代码却不出错
try:
code line 1
code line 2

except:
excpet code …

查了下文档,可以用sys.exc_info()[0]把excpet信息打印出来
我的这个例子中刚好是在函数块中直接sys.exit(X),导致了exceptions.SystemExit
于是改了下代码,在main函数中处理了下,才sys.exit(X),错误自然也就没了

恩恩,我是半吊子的程序猿

python mysql乱码问题

最近临时有个需求需要用python 爬点中文数据,结果悲催的发现乱码了

查了下资料,这里做下总结:

1. 首先python的代码需要是UTF-8的

# -*- coding: utf-8 -*-

2.确认mysql的数据库和表编码是UTF8的

show create database …

show create table…

如果不是,alter table或者database设置下编码(请注意alter database编码造成的影响)

3.pytho mysql连接时确认使用UTF8

MySQLdb.connect (…,charset=’utf8′)

4.暂时来说,应该是正常的了,如果还不行,请尝试如下操作:

修改/etc/my.cnf

[client]default-character-set = utf8

[mysqld]default-character-set = utf8

在python代码中增加:

reload(sys)

sys.setdefaultencoding(‘utf-8’)