slan's blog

Quantity is a miracle.

思想传播的重要性

2014-12-20 18:43:00 +0000 UTC

思想传播的重要性

相比与绚丽的技术,思想就显得没那么引人注意,因为他不带来任何具体的革新。

回顾人类社会的发展,为什么近两百年的发展程度,远大于过去几万年的累积总和,甚至每年,每个月都有重大的技术,发明出来。

知识,与思想的累积与传播在此进程中占了非常大的作用。

在几千年前,知识与意识的累积,主要靠书简刻字,效率极其的低,社会的流动性也非常原始,到纸张的出现,与印刷术的发明,文明开始进入加速发展的时代,将人类拉入封建社会,出现一系列绚烂的文明,各种思想,技术开始交流,碰撞,社会开始有了流动性,出现了一些盛世文明。

然后到机械革命,蒸汽机的出现让人类开始了近代的高速发展,轮船,火车的出现让信息快速传播,世界开始成为一个整体,这直接导致了新的技术,能快速应用,快速改进,快速发明,举个飞机的例子,飞机也不是莱特兄弟突发奇想捣鼓出来了,整个世界同时有多个团队在研发飞机项目,汽油机的出现,空气动力学的发展让飞机出现成为可能,所以技术的累积与传播奠定了非常重要的基础。

项目会失败,人也会失败,但是思想不会,思想是世界上最有威力的武器,只要思想还在传播,累积到一定的量,一定会改变这个世界。所以现在世界上的独裁国家,无不以阻碍思想传播为第一大要务,一定要统一思想。

但是作为一个普通人,如何去改变世界?

做成一个改变世界的事情成功很难,以一己之力,或者一伙之力,去推动社会的变革也很难,执着于做这样的事情,大多数情况下都是一场空。

那么怎么才能为世界的发展贡献出自己的力量?

有两件事情,永远不会错,1,传播知识,思想。2,帮助传播知识,思想。

以程序开发为例。git,github为什么成功,它做了第二件事情,帮助传播知识,思想。

在git出现之前,你要去开发一款软件,如各种地方找第三方库,去遵守各式各样的规范,知识相对零散,共享程度较低。在git,github出现之后,约定了readme,约定了markdown文档,帮助知识组织起来,更方便的传播出去。极大的发展了开源运动。

同样,php的composer,把之前php相对零散的库组织了起来,更方便的安装管理,发展也极为迅猛。

传播知识,思想,是当前世界发展的主动力。经常写博客,写开源程序,传播社区精神,翻译,打破知识封锁,这都是我们能做的事情。一个人做的可能只是一件小事,可能被遗忘,被忽视。然而在整个人类的发展进程中,就汇聚了不可逆转的进步洪流。

这是一个坏的时代,这却是一个最好的时代,因为作为一个最最最普通的人,也能参与这个世界改变的进程。迟早,我们能累积到我们所期望的变革。

无奈!gravatar被墙,博客头像打不开了

2014-11-16 20:27:00 +0000 UTC

无奈!gravatar被墙,博客头像打不开了

事情是这样的,某天登录我的sae,突然提示,我的云豆只够用两天了,奇怪,我是sae高级开发者,每月有1.5w云豆,上面跑的云豆一般一个月就用几十个,根本用不完呀。

赶紧去看看,发现是自己写的一个没啥用的小玩意儿,一直废弃着,怎么一天居然耗了3000豆。。。

蓝线是这个应用的访问量pv,36w一天。。。。。。。看访问记录,都是一个啥监控的破网站

useragent:

xilin.sinaapp.com "GET HTTP/1.0" "-" "Pingdom.com_bot_version_1.4_(http://www.pingdom.com/)" 69.64.56.47.1410600599359359 yq48

是这个网站搞的鬼 http://www.pingdom.com/ 跑去看了下,是个监控网站,在国外,于是开启防火墙,限制访问,一个ip访问5次就封掉。

效果很好:

访问一下就封死了。但是发现自己刷两下就不能访问了,这样不好,会影响别人访问,虽然也没人访问,但是处女座心理还是让我把限制放宽了。

放宽之后,云豆消耗立马又上来了,每天1000豆。一天十块钱啊,没几天就会用完了。

好吧9.4号-9.8号,一直消耗在1000云豆左右,于是放大杀招了,useragent中带pingdom,全部禁止访问:

if(strpos($_SERVER['HTTP_USER_AGENT'],'pingdom')!==false)
{
    die('fuck you!');
}

好了搞定,访问虽然每天仍然有40w,但是风轻轻云淡淡,一天就85个豆,毛毛雨拉。

一次apache Segmentation fault (11) 崩溃问题定位

2014-09-18 05:38:00 +0000 UTC

一次apache Segmentation fault (11) 崩溃问题定位

这些天出了一个很严重的问题。php接口,或者某个页面,会突然访问不了,查看apache错误日志,发现是不断的apache Segmentation fault (11),访问就会出现崩溃,之后所有的请求都会失败了。

之后运维重启apache解决,但是之后惨无人道的崩溃大幕开始了,每天晚上十点多的时候,某个站就会跑出来崩溃下。在分析最近更新内容后,发现没有明显能导致崩溃的更新或者写法。于是开发不行运维补,伟大的运维大神在连续几天晚上两三点被叫起来尿尿的情况下,终于想到了一个好办法,监控apache error日志的Segmentation fault (11) ,出现就重启,粗糙猛的办法临时解决了问题。

但是原因还是要找的,万一啥时候监控不准或者忘了加,或者掉了,那就出大事了。在这种找不到具体问题,也没法知道是更新了什么的情况下,只有分析apache的崩溃文件了。于是叫运维大神开启了apache崩溃产生core文件的配置。抓到了一堆core文件,gdb强势插入,bt观察,core文件大致分2种,

第一种崩在

崩溃1

remove_header,而且参数是 content-type ,大概估计是移除这个content-type的时候,崩溃了,看了下php代码,没有手动设置删除content-type,设置content-type倒很多,但都不是新增的,还是无法直接定位到具体的原因。

第二种是:

在销毁op_array的地方,完整堆栈: 崩溃2

注意下12-16层,是curl的调用,curl出了很多bug,于是猜测是新增了什么大量调用curl的功能,但是检查发现没有。

继续看类似几个core文件,发现除了curl,其他core文件还有mysql,file_get_contents等函数出现,然后就崩溃了,难道是阿里云网络最近不稳定,导致涉及网络调用的代码崩溃了?再仔细看看调用:

#7 0x004ea8ed in apr_pool_destroy (pool=0x9cbb920)

    at memory/unix/apr_pools.c:814

#8 0x001c06e5 in clean_child_exit (code=0) at prefork.c:218

#9 0x001c073d in just_die (sig=15) at prefork.c:344

#10

just_die (sig=15)应该是收到信号,然后apache退出,在释放资源的时候崩溃了,结合core文件生成的时候,能确定这种是产生Segmentation fault (11)后,监控脚本重启apache,然后apache进程在退出的时候,因为有网络调用的内容在跑,没处理好导致了崩溃,这种崩溃只在重启的时候才会发生,于是略过不管,真正致命的应该是第一种。

继续分析第一种core,完整堆栈信息

(gdb) bt

#0 sapi_remove_header (l=0x85e20e8, name=0xb7fc21a0 "Content-Type", len=12) at /usr/local/src/lamp/php-5.4.15/main/SAPI.c:601

#1 0x01426236 in sapi_header_add_op (op=, sapi_header=0xbff94460, tsrm_ls=0x85e2f60)

    at /usr/local/src/lamp/php-5.4.15/main/SAPI.c:650

#2 0x01426e8b in sapi_header_op (op=SAPI_HEADER_REPLACE, arg=0xbff944a0, tsrm_ls=0x85e2f60)

    at /usr/local/src/lamp/php-5.4.15/main/SAPI.c:842

#3 0x013b9415 in zif_header (ht=1, return_value=0xb7fc213c, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0, tsrm_ls=0x85e2f60)

    at /usr/local/src/lamp/php-5.4.15/ext/standard/head.c:48

#4 0x014b21a4 in zend_do_fcall_common_helper_SPEC (execute_data=0xb7fb210c, tsrm_ls=0x85e2f60)

    at /usr/local/src/lamp/php-5.4.15/Zend/zend_vm_execute.h:643

#5 0x014b8d98 in execute (op_array=0xb7fb2070, tsrm_ls=0x85e2f60) at /usr/local/src/lamp/php-5.4.15/Zend/zend_vm_execute.h:410

#6 0x01480c7c in zend_execute_scripts (type=2, tsrm_ls=0x85e2f60, retval=0x0, file_count=1)

    at /usr/local/src/lamp/php-5.4.15/Zend/zend.c:1315

#7 0x015364fb in php_handler (r=0x8801058) at /usr/local/src/lamp/php-5.4.15/sapi/apache2handler/sapi_apache2.c:669

#8 0x0808541b in ap_run_handler (r=0x8801058) at config.c:168

#9 0x08088fbb in ap_invoke_handler (r=0x8801058) at config.c:432

#10 0x0809a707 in ap_process_async_request (r=0x8801058) at http_request.c:317

#11 0x0809a83d in ap_process_request (r=0x8801058) at http_request.c:363

#12 0x08097230 in ap_process_http_sync_connection (c=0x87f4b20) at http_core.c:190

#13 ap_process_http_connection (c=0x87f4b20) at http_core.c:231

#14 0x0808f32b in ap_run_process_connection (c=0x87f4b20) at connection.c:41

#15 0x00fb6c59 in child_main (child_num_arg=) at prefork.c:704

#16 0x00fb6ffd in make_child (s=0x8570d48, slot=15) at prefork.c:800

#17 0x00fb7b13 in prefork_run (_pconf=0x854c0a8, plog=0x85729a0, s=0x8570d48) at prefork.c:902

#18 0x0806ddc9 in ap_run_mpm (pconf=0x854c0a8, plog=0x85729a0, s=0x8570d48) at mpm_common.c:96

#19 0x0806886a in main (argc=139763872, argv=0x87f2940) at main.c:777

调用层比较少,说明还没跑什么就崩溃了。

这里有两个地方能看到php信息,第5层的 execute 以及第4层zend_do_fcall_common_helper_SPEC 。看下op_array中的信息:

找到了崩溃的php文件main.php,但是这是一个入口文件。基本所有功能都走这进入,要定位的范围还是很大。

继续看下zend_do_fcall_common_helper_SPEC,在gdb中,可以手动打印出函数的变量,可以查看下源码,看传递进去的变量是什么结构,然后构造个指针查看。

不过php调试有简单方法。php有个gdb调试脚本,可以较快的将php执行信息输出来,不用盯着c的结构体看细节内容,

来执行一下:source /usr/local/src/lamp/php-5.4.15/.gdbinit

然后切到zend_do_fcall_common_helper_SPEC的上下文中,命令是frame 层数 缩写是f,执行f 4

dump_bt类似bt,是php的gdb调试脚本提供的方法,能看到当前执行环境的调用层次,我们这就看到一层,在header设置content-type的时候就崩掉了。

main.php源代码如下:

date_default_timezone_set('Asia/Shanghai');
header('Content-Type: text/html;charset=utf-8');
define('APP_PATH',dirname(__FILE__)."/aae");//tita base dir
define('ROOT_PATH',dirname(__FILE__));
 
require APP_PATH . '/core/Core.php';//加载框架核心
 
$app=\core\Tita::App();
$app->run();

根据dump_bt提示,崩在16行设置header的地方,也就是这里的第二行,这比较头痛,刚到入口apache就崩了,应该不是php语句写错了导致的。这样子也不好绕过,继续往上看:

#0 sapi_remove_header (l=0x85e20e8, name=0xb7fc21a0 "Content-Type", len=12) at /usr/local/src/lamp/php-5.4.15/main/SAPI.c:601
#1 0x01426236 in sapi_header_add_op (op=, sapi_header=0xbff94460, tsrm_ls=0x85e2f60)
    at /usr/local/src/lamp/php-5.4.15/main/SAPI.c:650
#2 0x01426e8b in sapi_header_op (op=SAPI_HEADER_REPLACE, arg=0xbff944a0, tsrm_ls=0x85e2f60)
    at /usr/local/src/lamp/php-5.4.15/main/SAPI.c:842

最终是崩在remove_header,我们是设置header,为什么会remove header呢, 看源码。

sapi.c 601 行
/*
 * since zend_llist_del_element only remove one matched item once,
 * we should remove them by ourself
 */
static void sapi_remove_header(zend_llist *l, char *name, uint len) {
 sapi_header_struct *header;
 zend_llist_element *next;
 zend_llist_element *current=l->head;
 while (current) {
  header = (sapi_header_struct *)(current->data);
  next = current->next;
  if (header->header_len > len && header->header[len] == ':'
    && !strncasecmp(header->header, name, len)) {
   if (current->prev) {
    current->prev->next = next;
   } else {
    l->head = next;
   }
   if (next) {
    next->prev = current->prev;
   } else {
    l->tail = current->prev;
   }
   sapi_free_header(header);
   efree(current);
   --l->count;
  }
  current = next;
 }
}

这里对current这个结构体进行操作,l->head是个链表,在next = current->next;崩溃,当时的current是个已经损坏的zend_llist_element结构,导致继续遍历下个节点的时候崩溃了。注意这句:

zend_llist_element *current=l->head;

current最初是从l来的,幸好l还没损坏,

检查下链表指向

查看到第二个节点的时候,就发现异常了0x1d明显不像是个指针,也就是应该只有一个节点,第一个节点的next本来应该为null,这里却是一个不知道啥的值。在->next的时候就崩溃了

至此,大致情况清楚了:

我们的php程序在调用header('Content-Type: text/html;charset=utf-8');的时候,apache进入了sapi_remove_header,然后这个函数里,遍历header列表的时候,使用了一个未初始化或者已经释放或者不知道怎么被损坏的一个header链表。如何解决这个问题呢?既然我们不需要remove_header,那是不是不进入这里就可以了,再看下#1层的函数sapi_header_add_op,这应该是我们要操作的内容,设置header content-type

static void sapi_header_add_op(sapi_header_op_enum op, sapi_header_struct *sapi_header TSRMLS_DC)
{
 if (!sapi_module.header_handler ||
  (SAPI_HEADER_ADD & sapi_module.header_handler(sapi_header, op, &SG(sapi_headers) TSRMLS_CC))) {
  if (op == SAPI_HEADER_REPLACE) {
   char *colon_offset = strchr(sapi_header->header, ':');
   if (colon_offset) {
    char sav = *colon_offset;
    *colon_offset = 0;
          sapi_remove_header(&SG(sapi_headers).headers, sapi_header->header, strlen(sapi_header->header));
    *colon_offset = sav;
   }
  }
  zend_llist_add_element(&SG(sapi_headers).headers, (void *) sapi_header);
 } else {
  sapi_free_header(sapi_header);
 }
}

源代码显示op == SAPI_HEADER_REPLACE时才会进入sapi_remove_header,也就是我们传进来就是replace,看手册:

void header ( string $string [, bool $replace = true [, int $http_response_code ]] )

原来默认设置成replace,这个参数的意思是当有同名header的时候替换较旧设置的那个header,我们这因为是入口,代码保证了这个header是第一个,所以,直接设置成false,来避免进入崩溃的函数sapi_remove_header。改成:header('Content-Type: text/html;charset=utf-8',false);

虽然崩溃问题解决了,但是为啥链表会是个坏的,因为崩溃几率小,压测设置header也不崩溃,所以还无法复现。

A human's structure:

  • Level 3: Service // What he provides
    • System
    • Product
  • Level 2: Action // What he can do
    • Storage: Knowledge
    • Processor: Thinking ability
  • Level 1: Body // What he has
    • Health
    • Age
    • Strength
    • Energy
Moment

Caution: I'm losing the ability to deep think

2023-12-28 09:16:00 +0000 UTC

Recently, I've been unable to focus. My brain is full of noise, busy surfing, catching new things, but I can't foucus on the job that I should be doing.

Yesterday, I tried not to use a PC, or pencil and paper to make a plan of how to write codes, just in my brain. At first, it was so hard. I couldn't even remember the idea that I just thought of, many other things distracted me. The outside world is so attractive, people are moving, talking, the metro is arriving at stations, cars are passing by. How is Blue's competition going? How will the stock market go? Will PCE go up again?

I tried to create some containers in my brain to hold my thoughts. They're rectangular box, I put the plan from top to bottom, first, second, third. The box is emptied again and again because I can't remember what I just planned to do, but when I tried sometimes, those boxes stick in my brain, what I need to do is so clear.

Now I know the reason why I can't focus, why the outside world is so easy to distract me. I lack inner thinking. Nowadays, I can easily write notes and sync them across all my devices, but my brain is exercised less and less, then I will lose the ability to store, process, and recall information in my brain.

Moment

Weekly Report 20231224: Valley of Despair

2023-12-26 09:43:15 +0800 +0800

#time: 2023-12-26

Yes, you read that correctly. Today is Tuesday, but I'm writing last week's report.

Last week was full of mess:

  1. [ ] Service
    1. [ ] Wrote RSS subscribe feature, but failed to finish it. Just couldn't focus on it, wrote for a while, and got distracted by other things.
    2. [x] Started weekly communication with users.
  2. [x] Finished reading the book "Revolution of Glucose".
  3. [ ] Didn't finish the listening goals.
  4. [ ] Slept better than last week, but still not good.

The main reason for this mess is that I didn't have clear priorities, just did what I remembered. When things started going bad, I didn't have a buffer to handle it. I have reorganized my priorities:

  • 1. Push service to public. Build a service that can earn 6k$/month
  • 2. English improvement
  • 3. Health, exercise, eat healthy food, sleep early, take care of my family.

When time switches to these priority zones, I should focus on them, not keep other things in mind.

#hashtag: WeeklyReport

Moment

Mental status: Mouse

2023-12-21 15:00:00 +0000 UTC

Mouse is a mental status invented by me to describe a status that I need to do a hard thing, but I'm not want to do it, i'm avoid to face it, surf the internet, do other things, but eventually I also need to do it.

When I'm in this status, I need to :

  • listen a music that I like
  • write down any thing I can to to make the goal more clear. or more near.
  • just do the simple thing.
Moment

Weekly report 20231217 Continue to Coding

2023-12-17 22:45:00 +0000 UTC

this week:

  1. Kickd out by Xuan's English learning program. cause I didn't commit enough time to learn english.
  2. develop Valid English App to v29, improve highlights, and fix bugs, and add a feature of dictation.
  3. [x] Finish half marthon in 2:04 at Hangzhou.
  4. [ ] not finish book reading goal. 50%
  5. [ ] carefully listen podcast 2/3
  6. [ ] casually listen podcast group 1/4
  7. [ ] sleep goal runs bad.

half marthon

Next week:

  • perform better in Daily Maintenance program, schedule at morning, review at night, write down logs.
  • build a App development pipeline. publish every 2 weeks.
  • write english leanring guide experience. find resouces.

#hashtag: WeeklyReport

What I Learned from a amazing Person

2023-12-12 13:41:00 +0000 UTC