Yaf中Action再次Dispatch导致PHP段错误Segmentation fault

首先,这个问题是在Yaf群偶然看到的,这些小伙儿不折腾不畅快,今天闲来,扫了一下代码,得出结论。
其次,另外一个观点是,工具在运用时一定要清楚其原理,不然就是自己跳坑了没有人救的。
先简单明了看一下,在基于Yaf的PHP代码示例:

 代码如下 复制代码

<?php
use Yaf\Dispatcher;
use Yaf\Controller_Abstract;

final class IndexController extends Controller_Abstract
{
    public function init()
    {
        // 无
    }

    public function indexAction()
    {
            $request = new Yaf\Request\Simple('API', 'index', 'index', 'simple');
            Dispatcher::getInstance()->dispatch($request);
            $this->_view->assign('displayWelcome', 1);
            $this->_view->assign('hello', 'hello world!');
    }

    public function simpleAction()
    {
            echo 'xudianyang';
    }
}

在默认的indexAction中,我创建了一个Yaf\Request\Simple的请求对象$request,参数的意思是请求Index模块和Index控制器的Simple动作,这里需要注意的是,如果你将请求设置为和当前action的路由参数相同,那么你将进入死循环,都不用大拇指想就知道。然后调用派遣器Dispatcher的dispatch方法,进行路由分发。


从图中可以看出,在“新一轮分发”的过程中,任何一个环节出现问题,或者exit,return都不会产生程序崩溃。比如,simpleAction方法这样写:

 代码如下 复制代码

public function simpleAction()

{

    echo  'xudianyang';

    exit;

}

再比如:simple方法对应的模板文件views/index/simple.phtml不存在,也不会生产Segmentation fault。
产生段错误的原因在图中说得也很明显,指针引用不再可用,因为新一轮分发是调用了Dispatcher::getInstance()->dispatch($request);此方法会重置Yaf\Dispatcher单实例的$_request属性。
通过gdb调试core文件也可以得出:

 代码如下 复制代码
(gdb) bt
#0 0x083d58d4 in zend_std_read_property (object=0xb777c020, member=0xb73f8938, type=3, key=0x0)
at /home/vagrant/php-5.4.31/Zend/zend_object_handlers.c:431
#1 0x083b4508 in zend_read_property (scope=0xa392cb8, object=0xb777c020, name=0xcb64c6 "module", name_length=6, silent=1 '\001')
at /home/vagrant/php-5.4.31/Zend/zend_API.c:3859
#2 0x00c96c85 in yaf_dispatcher_fix_default (dispatcher=0xb778143c) at /home/vagrant/yaf-2.3.2/yaf_dispatcher.c:236
#3 yaf_dispatcher_dispatch (dispatcher=0xb778143c) at /home/vagrant/yaf-2.3.2/yaf_dispatcher.c:927
#4 0x00c91bd6 in zim_yaf_application_run (ht=0, return_value=0xb7799fcc, return_value_ptr=0x0, this_ptr=0xb777a140,
return_value_used=0) at /home/vagrant/yaf-2.3.2/yaf_application.c:468
#5 0x0841f5d4 in zend_do_fcall_common_helper_SPEC (execute_data=)
at /home/vagrant/php-5.4.31/Zend/zend_vm_execute.h:643
#6 0x084137a6 in execute (op_array=0xb777a408) at /home/vagrant/php-5.4.31/Zend/zend_vm_execute.h:410
#7 0x083b1c6e in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/vagrant/php-5.4.31/Zend/zend.c:1315
#8 0x08357706 in php_execute_script (primary_file=0xbfb72338) at /home/vagrant/php-5.4.31/main/main.c:2502
#9 0x0845c1cb in main (argc=6, argv=0xbfb72494) at /home/vagrant/php-5.4.31/sapi/fpm/fpm/fpm_main.c:1933

最后,其实分析这个只是熟悉一下Yaf的分发策略及其源码。另外,想要在一个action中执行另外一个action,其实鸟哥已经考虑了,通过Yaf_Controller_Abstract::forward就可以了。我们在实际应用中,不要异想天开,乱来!

时间: 2024-09-29 18:58:04

Yaf中Action再次Dispatch导致PHP段错误Segmentation fault的相关文章

安装MySQL 5.6.16登录出错:段错误 (Segmentation fault)解决办法

Centos 6.5 安装 MySQL 5.6.16 后,使用命令登录出错: [root@test mysql-5.6.16]# mysql -u root -p Enter password: Welcome to the MySQL monitor.  Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.6.16-log Source distribution   Copyright (c) 2

用gdb调试程序笔记: 以段错误(Segmental fault)为例

用gdb调试程序笔记: 以段错误(Segmental fault)为例[转] 1.背景介绍2.程序中常见的bug分类3.程序调试器(如gdb)有什么用4.段错误(Segmental fault)介绍5.gdb调试入门  一.背景介绍这个笔记主要介绍开源的程序调试器(gdb)的入门知识,目的是使unix/linux环境的编程新手能够快速学会使用gdb调试程序的方法,同时也是对我使用gdb的一个经验总结.本文假设你能使用简单的unix/linux命令并能用gcc(GNU C Compiler, GN

利用linux信号机制调试段错误(Segment fault)

在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过串口.显示器可以查看消息,只要程序运行,通过GDB调试工具即可捕捉产生segment fault的具体原因.但是不知大家有没有想法,当程序运行在嵌入式设备上时,你所面临资源的缺乏,你没有串口打印信息,没有显示器可查看,你不知道程序运行的状态,如果程序的产生segment falut这种bug发生的周

Oracle中静态监听导致的ORA-12523错误

今天配置完共享服务器模式之后发现登录过程中报错ORA-12523,排查错误之后发现是静态监听惹的祸. 本机之上有两个监听,一个静态监听1521端口,一个动态监听1526端口. LISTENER= (DESCRIPTION=  (ADDRESS_LIST=    (ADDRESS=(PROTOCOL=tcp)(HOST=jp)(PORT=1521))    (ADDRESS=(PROTOCOL=ipc)(KEY=extproc)))) LSNR2= (DESCRIPTION=  (ADDRESS_

结构体指针之 段错误 详解(精典!!!)

一个网友问了我一个问题,一个C程序运行出现了段错误,这个问题非常好,很多初学者都容易犯这个错误,具体代码如下: 这个编译没有问题,但是运行是段错误    Segmentation fault 因为你定义了一个结构体指针p,用来指向此类结构体,但是你却没有给他赋值,此时p的值为NULL,你并没有在内存中为p分配任何空间,所以p->a=1这句就会出段错误. 修改方法1:可以给p分配一段内存空间,并使其指向此空间: p=(struct abc *)malloc(sizeof(struct abc));

snort mips段错误-MIPS交叉编译的snort运行出现段错误

问题描述 MIPS交叉编译的snort运行出现段错误 MIPS交叉编译的snort,在IDS模式运行时dlopen()加载libsf_engine.so等库时出现段错误segmentation fault 解决方案 gdb跟踪调试一下.先看具体错误信息.分析

c++ execl函数执行不存在的文件段错误退出

问题描述 c++ execl函数执行不存在的文件段错误退出 如题,execl执行可执行文件,文件不存在或执行失败时,导致主程序段错误退出,怎么处理这个问题 解决方案 那就在调用execl前 检查文件是否存在咯 解决方案二: 我用的是QT,想调别的程序,别的程序不存在就会段错误 解决方案三: 返回值:执行失败则直接返回-1增加捕获异常. 解决方案四: 那你认为的判断一下不就行了,若不存在则不掉就行了么...

【中亦安图】导致Oracle性能抖动的参数提醒(4)

第一章 技术人生系列 · 我和数据中心的故事(第四期)-导致Oracle性能抖动的参数提醒 中亦安图 | 2016-01-25 21:39 前言 不知不觉,技术人生系列·我和数据中心的故事来到了第四期.小y又和大家见面了! 当您看到业务系统压测呈现以下波浪形的tps曲线时,你会怎么下手? 小y(中亦科技)今天要和大家分享的就是这样一个业务系统压测性能问题的分析和解决过程.这个问题困扰了客户相当长一段时间,幸运的是,小y通过远程在10分钟定位到了问题的原因并帮助客户最终解决了问题.需要说明的是,在

Oracle中缺少log_archive_config会导致归档路径被禁用

10g的DATA GUARD的一个主要特点就是引入了log_archive_config参数,如果缺少这个参数,可能会导致归档路径被禁用. 看别人建立DATA GUARD时碰到了这个问题,当时觉得比较有意思,于是特意重现一下. 当前是一个已经配置好的DATA GUARD,为了模拟错误,先将这个参数设置为空: SQL> alter system set log_archive_config = ''; System altered. SQL> alter system switch logfil