生成CA私钥及证书: 参考Example #1 Creating a self-signed certificate 使用上面的方法可以生成CA证书并使用,但是如果使用上面的方法直接生成的自签名域名证书,即使你把(CA)证书加入到了受信任的根证书列表,也不会受浏览器信任: NET::ERR_CERT_COMMON_NAME_INVALID 此服务器无法证实它就是 localhost – 它的安全证书没有指定主题备用名称。这可能是因为某项配置有误或某个攻击者拦截了您的连接。 你还需要把域名加入到SAN。 首先生成OpenSSL的配置文件: [crayon-60123deb70a8a4 […]
分类: 编程
ERROR: failed to retrieve TCP_INFO for socket: Protocol not available (92)
1 2 3 |
php_source_dir="/usr/src/php-7.2.12" sed -i "s/#define HAVE_LQ_TCP_INFO 1/\/\/ #define HAVE_LQ_TCP_INFO 1/g" ${php_source_dir}/main/php_config.h make -j32 clean && make -j$(cat /proc/cpuinfo | grep "processor" | wc -l) && make -j32 install |
PHP 7.2 compile on Debian Stretch
Libraries:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
apt -y install \ libcurl4-openssl-dev \ libgd-dev \ libsodium-dev \ libxml2-dev \ libpcre3-dev \ libssl-dev \ libsqlite3-dev \ libzip-dev \ libbz2-dev \ libedit-dev \ libxmlrpc-epi-dev \ libxmlrpc-core-c3-dev \ libxslt1-dev \ libwebp-dev \ libreadline-dev |
Configure:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
./configure \ --prefix=/usr/local/php-7.2 \ --build=x86_64-linux-gnu \ --host=x86_64-linux-gnu \ --config-cache --cache-file=$(pwd -P)/config.cache \ --with-libdir=lib/x86_64-linux-gnu \ --enable-cli \ --enable-fpm \ --with-config-file-path=\${prefix}/etc \ --with-config-file-scan-dir=\${prefix}/etc/conf.d \ --with-fpm-user=www-data \ --with-fpm-group=www-data \ --disable-debug \ --with-pic \ --with-layout=GNU \ --with-pear \ --enable-filter \ --with-openssl=yes \ --with-pcre-regex=/usr \ --enable-hash \ --with-mhash=/usr \ --enable-libxml \ --enable-session \ --with-sodium \ --with-zlib=/usr \ --with-zlib-dir=/usr \ \ --enable-opcache \ --enable-opcache-file \ --enable-huge-code-pages \ \ --enable-mysqlnd \ --enable-mysqlnd-compression-support \ --with-zlib-dir=/usr \ --with-mysqli=mysqlnd \ --with-pdo-mysql=mysqlnd \ \ --with-sqlite3=/usr \ --with-pdo-sqlite=/usr \ \ --enable-json \ \ --enable-intl \ \ --with-curl=/usr \ \ --with-bz2=/usr \ \ --with-gd=/usr \ --with-jpeg-dir=/usr \ --with-xpm-dir=/usr/X11R6 \ --with-png-dir=/usr \ --with-freetype-dir=/usr \ --with-webp-dir=/usr \ \ --enable-mbstring \ --enable-mbregex \ --enable-mbregex-backtrack \ \ --with-libedit=/usr \ \ --enable-wddx \ --enable-xml \ --with-xsl=/usr \ \ --with-xmlrpc=/usr \ --with-libxml-dir=/usr \ \ --enable-zip \ --with-zlib-dir=/usr \ --with-libzip=/usr \ \ --enable-calendar \ --enable-ctype \ --enable-exif \ --enable-fileinfo \ --enable-ftp \ --with-openssl-dir=/usr \ --with-gettext=/usr \ --with-iconv \ --enable-pdo \ --enable-phar \ --enable-pcntl \ --enable-posix \ --enable-shmop \ --enable-sockets \ --enable-sysvmsg \ --enable-sysvsem \ --enable-sysvshm \ --enable-tokenizer |
Make xmlrpc error 1:
1 2 3 4 5 6 7 8 9 |
/usr/src/php-7.2.12/ext/xmlrpc/xmlrpc-epi-php.c:187:2: error: unknown type name 'XMLRPC_SERVER' XMLRPC_SERVER server_ptr; ^~~~~~~~~~~~~ /usr/src/php-7.2.12/ext/xmlrpc/xmlrpc-epi-php.c:195:2: error: unknown type name 'STRUCT_XMLRPC_REQUEST_OUTPUT_OPTIONS' STRUCT_XMLRPC_REQUEST_OUTPUT_OPTIONS xmlrpc_out; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ... Makefile:1933: recipe for target 'ext/xmlrpc/xmlrpc-epi-php.lo' failed |
Open Makefile, add
1 |
-I/usr/include/xmlrpc-epi |
to the line(1933) where the error occured. xmlrpc error 2:
1 2 3 4 5 6 7 8 9 |
ext/xmlrpc/.libs/xmlrpc-epi-php.o: In function `destroy_server_data': /usr/src/php-7.2.12/ext/xmlrpc/xmlrpc-epi-php.c:268: undefined reference to `XMLRPC_ServerDestroy' ext/xmlrpc/.libs/xmlrpc-epi-php.o: In function `zm_info_xmlrpc': ... collect2: error: ld returned 1 exit status Makefile:296: recipe for target 'sapi/cli/php' failed make: *** [sapi/cli/php] Error 1 |
[…]
解除clock_gettime@@GLIBC_2.17的依赖
在x86_64的Debian Jessie上交叉编译一个mipsel架构的程序,能静态链接的都静态链接了。 程序编译好传送到mipsel架构的设备上时,ldd查看库的依赖,却提示
1 |
/lib/mipsel-linux-gnu/libc.so.6: version `GLIBC_2.17' not found |
(⊙﹏⊙)b mipsel设备上运行着Debian Wheezy,使用的是glibc 2.13:
1 2 |
# /lib/mipsel-linux-gnu/libc.so.6 GNU C Library (Debian EGLIBC 2.13-38+deb7u11) stable release version 2.13, by Roland McGrath et al. |
尝试了更新到glibc 2.17,结果运行所有动态链接glibc的程序都提示Segmentation fault或Bus error,眼看要变砖!!!∑(゚Д゚ノ)ノ,最后用一个静态链接版本 […]
探讨C语言返回struct的实现
C语言基本类型的返回通过寄存器实现。 寄存器容量不大,一个结构体的大小不定,多塞几个成员,很容易就会超过寄存器的容量,不太可能通过寄存器一次性返回一个结构体。 把以下代码转为汇编,探个究竟:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// return_struct.c struct the_struct { int num1; int num2; double num3; double num4; int *num_ptr1; int *num_ptr2; }; struct the_struct fun() { struct the_struct the_struct1; the_struct1.num1 = 1; the_struct1.num2 = 2; return the_struct1; } int get_struct() { struct the_struct the_struct1 = fun(); return the_struct1.num1 + 1; } |
优化后的代码可能比较晦涩,64位寄存器数量是32位的一倍,为了简便理解,关闭代码优化,并且转为32位汇编,命令:
1 |
bash # gcc -O0 -S -masm=intel -m32 return_struct.c |
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
.file "return_struct.c" .intel_syntax noprefix .text .globl _fun .def _fun; .scl 2; .type 32; .endef _fun: push ebp mov ebp, esp sub esp, 32 ; 为结构体在栈帧中分配32字节内存 mov DWORD PTR [ebp-32], 1 ; *(ebp - 32) = 1 mov DWORD PTR [ebp-28], 2 ; *(ebp - 28) = 1 ; ebp指向的位置储存着get_struct()函数的ebp值 ; ebp+4指向返回地址 ; ebp+8是get_struct()函数中结构体的指针 mov eax, DWORD PTR [ebp+8] ; eax = get_struct()函数中结构体的指针 mov edx, DWORD PTR [ebp-32] ; edx是fun()函数中结构体首DWORD的值 mov DWORD PTR [eax], edx ; *eax = edx,让get_struct()中的结构体第一个DWORD = edx ; 结构体剩余的其余值传值 mov edx, DWORD PTR [ebp-28] mov DWORD PTR [eax+4], edx mov edx, DWORD PTR [ebp-24] mov DWORD PTR [eax+8], edx mov edx, DWORD PTR [ebp-20] mov DWORD PTR [eax+12], edx mov edx, DWORD PTR [ebp-16] mov DWORD PTR [eax+16], edx mov edx, DWORD PTR [ebp-12] mov DWORD PTR [eax+20], edx mov edx, DWORD PTR [ebp-8] mov DWORD PTR [eax+24], edx mov edx, DWORD PTR [ebp-4] mov DWORD PTR [eax+28], edx mov eax, DWORD PTR [ebp+8] leave ret 4 .globl _get_struct .def _get_struct; .scl 2; .type 32; .endef _get_struct: push ebp mov ebp, esp sub esp, 40 ; 分配40字节内存 lea eax, [ebp-32] ; eax = ebp - 32,eax是结构体的指针 mov DWORD PTR [esp], eax ; *esp储存结构体的指针,即get_struct()函数栈顶是结构体的指针 call _fun sub esp, 4 mov eax, DWORD PTR [ebp-32] ; (ebp - 32)是结构体的地址 add eax, 1 leave ret .ident "GCC: (GNU) 5.3.0" |
汇编代码已写上注释。 在get_struct()函数中,调用fun()之前,会首先把ge […]
关于Visual Studio C LANG下pow()函数的重载
当初看到Visual Studio 2010的这个提示,我真当VS实现了C LANG的函数重载。 今天即兴尝试VS下C LANG的函数重载,虽然IDE没报语法错误,但编译器编译时会报错。无奈之下只好打开长长的math.h一探究竟。 通过全文搜索很容易找到math.h声明的pow()原型:
1 2 3 4 5 6 7 8 9 10 11 |
double __cdecl pow(_In_ double _X, _In_ double _Y); inline double __CRTDECL pow(_In_ double _X, _In_ int _Y) {return (_Pow_int(_X, _Y)); } inline float __CRTDECL pow(_In_ float _X, _In_ float _Y) {return (powf(_X, _Y)); } inline float __CRTDECL pow(_In_ float _X, _In_ int _Y) {return (_Pow_int(_X, _Y)); } inline long double __CRTDECL pow(_In_ long double _X, _In_ long double _Y) {return (powl(_X, _Y)); } inline long double __CRTDECL pow(_In_ long double _X, _In_ int _Y) {return (_Pow_int(_X, _Y)); } |
声明的这些原型一眼看上去没什么问题,挺正常的重载方式。不过math.h内容有点多,不细心点还是看不出来,实际上pow()的重载使用了条件编译:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
... #ifdef __cplusplus extern "C" { #endif ... double __cdecl pow(_In_ double _X, _In_ double _Y); ... #ifdef __cplusplus } extern "C++" { ... inline double __CRTDECL pow(_In_ double _X, _In_ int _Y) {return (_Pow_int(_X, _Y)); } inline float __CRTDECL pow(_In_ float _X, _In_ float _Y) {return (powf(_X, _Y)); } inline float __CRTDECL pow(_In_ float _X, _In_ int _Y) {return (_Pow_int(_X, _Y)); } inline long double __CRTDECL pow(_In_ long double _X, _In_ long double _Y) {return (powl(_X, _Y)); } inline long double __CRTDECL pow(_In_ long double _X, _In_ int _Y) {return (_Pow_int(_X, _Y)); } ... } #endif |
查找了一下资料,得知” […]
PHP线程安全与非线程安全版本的本质区别
在百度上搜“PHP 线程安全 非线程安全”,你肯定会找到这种狗屁话: 一本正经说胡话,完完全全没解释到点上。 稍微懂点C语言的都不会相信这种话,更别谈说出来了,千转载万转载你转载我我转载你就转载点那么没水平的东西来忽悠人。 线程和进程最大的根本区别就是内存数据的共享。 每个进程都独享一个虚拟内存[虚拟内存 = 物理内存 + SWAP/页面文件)]。 一个进程可以拥有多个线程,一般来说一个线程仅独享一个进程的虚拟内存中的一个函数栈帧。 程序储存数据有下面几种常用的方式: 自动变量: 自动变量是储存在栈中的,随着函数的调用而产生,结束而销毁。 静态(全局)变量: 静态分 […]
为何C语言函数可以返回struct
struct可由多个数据类型构成,初步看起来应该类似数组,变量本身是一个指向首字节的指针,无法直接通过此指针赋值struct,在函数中声明为自动变量时,也无法返回此指针所指向的值。 但事实上就并非如此,struct之间可以直接赋值,使用指针指向其地址时需要使用”&”,函数中声明为自动变量时可以直接return其值。 那struct变量本身到底是何? 写了这样一个东西,运行后瞬间明白:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include <stdio.h> #include <string.h> struct my_struct { unsigned char ch1; unsigned char ch2; unsigned char ch3; unsigned char ch4; }; int main() { struct my_struct struct1; memset(&struct1, 0, sizeof(struct my_struct)); printf("%u\n", struct1); struct1.ch1 = 0xFF; printf("%u\n", struct1); struct1.ch2 = 0xFF; printf("%u\n", struct1); struct1.ch3 = 0xFF; printf("%u\n", struct1); struct1.ch4 = 0xFF; printf("%u\n", struct1); return 0; } |
struct变量就和基本类型,int, char等一样,直接指向其值,而且struct有多少字节,那个值就有多少字 […]
Linux chroot Shell —— 简单chroot指定用户
对于Linux服务器,有时需要开放登录权限给一部分用户,但并非所有用户都愿意安分守己,也无法知道谁是不安分守己的,给多一个这些用户开放登录权限,系统的威胁就多了一分。 目前来说比较好的方案是chroot,调用了chroot(),就能把的根目录改成指定的根目录。何为根目录?顾名思义,“根”就是所有目录的“根”,一切目录均从“根”而生,没有“根”就没有其他目录,换句话说,“根目录”就是最原始的目录。你无法访问“根”之前前的数据,没有“根”的时候,怎么可以发展数据呢? 二进制程序chroot乃GNU的核心程序中的一个,Linux发行版本一般都有Coreutils,不过二进制版的chroot在这种情况 […]
[PHP模块开发]获取单次请求所耗的CPU时间
数天前与一个学校中的朋友闲聊,对方提到了使用Hostker的经历,涉及到了一项“按CPU时间”计费的功能。 个人来说,是挺欣赏这一项收费策略的,毕竟有多少个使用虚拟主机的用户,就有多少种不同资源需求量,按照PHP对CPU资源的使用情况来计费,不仅实现公平收费,还能逼那些让资源占用多的用户占得谨慎点,比用CloudLinux的那些逼格高得多哈! 既然如此,就自己来动手实现一个。 计算CPU时间,并不难实现,Unix Like有提供这一个系统调用,所以嘛,根本不需要你自己计算…… 我所知道相关的系统调用有两个,以下是他们的函数原型: [crayon-60123deb739e41749 […]