1. 如果a.txt被LOCK_EX了, 则file_put_contents时使用了LOCK_EX,结果会怎样? —– 阻塞,直到得到锁
2. 对于问题1, 我能让file_put_contents加锁但是不阻塞吗? —— 尝试使用 LOCK_EX|LOCK_NB , 没有达到我想要的效果
先留下来,有时间再看怎么办!
DevOps
1. 如果a.txt被LOCK_EX了, 则file_put_contents时使用了LOCK_EX,结果会怎样? —– 阻塞,直到得到锁
2. 对于问题1, 我能让file_put_contents加锁但是不阻塞吗? —— 尝试使用 LOCK_EX|LOCK_NB , 没有达到我想要的效果
先留下来,有时间再看怎么办!
参考函数: compare_function (in Zend/zend_operators.c)
test.php
===================
class phpor{
public function __tostring() {
return ‘aa’;
}
}
if (new phpor == "aa") echo ‘ok1’;
if ("aa" == new phpor) echo ‘ok2’;
exit;
===========================
你觉得ok1和ok2是不是都能输出; 原来我猜测php是不是将 ”==“ 右边的转换成左边的类型后进行比较的; 看了源码才知道根本不是这么简单的;
如果其中一个是对象,并且该对象是可以cast的,则将对象cast成另一操作数的类型后再进行比较。所以上面ok1和ok2都是输出的
———————-
关于 ‘===’ 的实现,参考: is_identical_function (in Zend/zend_operators.c)
1. PHP中对象的赋值,默认是引用的;对象作为参数传递时也是引用传递的,和普通变量是不同的。
2. 函数定义时,试图将返回值定义成引用是没有意义的; 如下面代码:
——————–
<?php
function &phpor() { // 这里的 & 没有任何作用
static $a = 1;
$a++;
return $a;
}
$b = phpor(); // $b没有被作用返回值的引用
$c = &phpor(); // 引用返回值需要在函数调用时引用
echo "b:$b\n";
echo "c:$c\n";
phpor();
echo "b:$b\n";
echo "c:$c\n";
exit;
===================
输出结果:
b:2
c:3
b:2
c:4
—————————-
阅读PHP源码有一个非常重要的函数: zend_do_fcall_common_helper_SPEC (in Zend/zend_vm_execute.h);
PHP中有很多现有的函数是用C写的, 称之为: ZEND_INTERNAL_FUNCTION ; 还有一部分是我们自己使用function关键字定义的,这部分称为: ZEND_USER_FUNCTION ; 对于类也有这种区别,用C写的那部分类,称之为: ZEND_INTERNAL_CLASS; 我们自己使用class关键字定义的类,称为:ZEND_USER_CLASS ; 相关定义可参看: Zend/zend_compile.h
通过函数zend_do_fcall_common_helper_SPEC() , 我们可以知道内部函数和用户函数分别是怎么执行的。 内部函数通过函数 zend_execute_internal 来执行, 用户函数是通过函数 zend_execute来解释执行opcode的。
PHP中函数的存储结构:
———————- in zend_compile.h ———————-
typedef union _zend_function {
zend_uchar type; /* MUST be the first element of this struct! */
struct {
zend_uchar type; /* never used */
char *function_name;
zend_class_entry *scope;
zend_uint fn_flags;
union _zend_function *prototype;
zend_uint num_args;
zend_uint required_num_args;
zend_arg_info *arg_info;
zend_bool pass_rest_by_reference;
unsigned char return_reference;
} common;
zend_op_array op_array;
zend_internal_function internal_function;
} zend_function;
其中,type标识的是内部函数还是用户函数
————————————————-
关于类的存储结构,参看Zend/zend.h 中结构体 _zend_class_entry,其中也有一个type属性来标识了内部类还是用户类了;
作业: foreach一个类的时候,能看到那些属性或函数,内部类和用户类表现一样吗?为什么?
1. foreach内部类的时候,什么也看不到
2. foreach用户类的使用,public的属性可以看到,private的属性或任意访问权限的成员方法是看不见的。
* 比较方便的办法是下载一个合适的二进制的mongodb的包,直接复制到合适的目录
* 自己编译安装:
- devel/boost
- devel/libexecinfo
- devel/pcre
- lang/spidermonkey
5. 假设你安装完了上面依赖, 好了, scons . ; 但愿你是幸运的
——————–
提示: boost安装可以使用yum:
yum install boost-devel
pcre的安装: http://www.pcre.org/
spidermonkey的安装: http://www.mongodb.org/display/DOCS/Building+Spider+Monkey
重要: gcc < 4编译不行
TT的内存占用和实际的条目数不是完全一致的,可能存在内存占用为实际的消耗的几倍的情况,至于什么时候释放不需要的内存,还没搞明白,下面有一些意外看到的数据:
本来5.7w条的记录 20M内存够用了,但是这里占用了155M, 在释放过期数据的过程中,内存不是一点一点释放的,而是突然释放了8M,又突然释放了122M。
那么内存的开辟也是批量开辟的吗?好想不是,且看下图:
看样子,好想是,但多看一些:
好像也不是, 还是看看源码吧。
记得前面的一篇日志中提到过,Linux top命令中的SWAP是通过 VIRT – RSS计算出来的;但是SWAP真的就代表占用磁盘的SWAP的空间大小吗?
我们知道linux的内存使用是采用记账的方式的,比如,我malloc了1G的内存,但是我什么都没存,于是,我们的RSS占用没有增加,我的VIRT却显示多了1G; 显然,通过top命令查看,该进程的SWAP为1G; 但是查看SWAP的占用量并没有增加;
再观察DATA,占用也是1G,说明只要malloc了,就算使用了。
测试程序:
=============== malloc.c =================
#include <stdio.h>
#include <stdlib.h>
int main() {
char *c = malloc(1024 * 1024 * 1024);
sleep(10000);
return 0;
}
==========================================
gcc -o malloc malloc.c
./malloc
top:
———————————————————————–
Mem: 2074828k total, 2049228k used, 25600k free, 280568k buffers
Swap: 8385888k total, 17000k used, 8368888k free, 1458464k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ SWAP CODE DATA COMMAND
23673 root 16 0 1026m 276 220 S 0.0 0.0 0:00.00 1.0g 0 1.0g malloc ————————————————————————
昨天跑一个deamon,是关于mongo的操作,使用的是php的mongo模块, mongo-1.1.4; 发现出现了 too many open files的情况, 使用lsof查看了一下进程的情况,出现了很多 sock类型的资源,都是 can’t identify protocol 。
例如:
lijunjie 3074 web 3u sock 0,4 0t0 45174 can’t identify protocol
看了一下mongo-1.1.4的源代码,发现在函数php_mongo_connect_nonb(…)中,socket产生的fd,在connect(或因别的错误)出错时,直接return false; 没有close, 所以才出现这种情况。
先修改了一下代码,然后再给官方提个bug吧
按说socket产生的时候都已经指定了sock类型的,所以似乎不需要显示成“can’t identify protocol”
相关资料:http://kasicass.blog.163.com/blog/static/3956192010101994124701/
问题: httpd server是用web用户执行的,如何才能通过httpd server来做root才能做到事情呢?
我想大概这样可以:
我们知道linux上到可执行文件到属主有一个s位,则该文件就可以seteuid到该用户到权限来做事情,于是写如下测试脚本:
====== agent.c=========
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(int ac, char ** av) {
seteuid(0);
printf("%d", geteuid()); // 返回0
// 这里干活就是root的身份了
return 0;
}
========================
编译文件:
gcc -o agent agent.c
生成文件:
-rwxr-xr-x 1 root root 7213 2011-06-13 00:02 agent
修改文件属性:
chmod +s agent
-rwsr-sr-x 1 root root 7213 2011-06-13 00:02 agent
执行agent:
./agent
0
返回结果为0,说明提升权限成功了
——————————
问题: 按说如果添加来s位,则非属主用户不应该有写权限,换言之,如果非属主用户有来写权限,则s位应该无效;但事实上, chmod a+w agent 后,提升权限还是成功来,为什么?
使用rpm命名查看gdb的rpm包,主要由下面几个程序:
/usr/bin/gcore
/usr/bin/gdb
/usr/bin/gdbserver
/usr/bin/gdbtui
/usr/bin/gstack
其中:
gcore 是生成core文件用的
gdb 调试用的
gdbserver 远程调试使用
gdbtui 界面化的gdb, 同 gdb -tui
gstack 查看正在运行的进程的调用栈信息
实例:
gcore:
# gcore -o a 3236
[root@login ~]# ll a.3236
-rw-r–r– 1 root root 64691440 6? 11 20:48 a.3236
产生core的过程中进程暂停工作
========================================
# gdbserver 10.55.38.18:12345 a.out
Process a.out created; pid = 20975
Listening on port 12345
Remote debugging from host 10.55.38.14
注意: 本地需要有a.out 和a.c
========================================
# gstack 24874
#0 0x0088e7a2 in ?? () from /lib/ld-linux.so.2
#1 0x0096f68b in semop () from /lib/tls/libc.so.6
#2 0x006fdbe3 in proc_mutex_sysv_acquire (mutex=0x70ed50)
#3 0x006fe608 in apr_proc_mutex_lock (mutex=0xfffffffc)
#4 0x080829bf in child_main (child_num_arg=-4) at prefork.c:205
#5 0x08082c5e in make_child (s=0x808260c, slot=4) at prefork.c:758
#6 0x080837e5 in ap_mpm_run (_pconf=0x1, plog=0x9dfe160, s=0x2)
#7 0x08063de4 in main (argc=3, argv=0xbfe63654) at main.c:740
=========================================
gdbtui: