Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:97491 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 57660 invoked from network); 30 Dec 2016 00:13:29 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 30 Dec 2016 00:13:29 -0000 Authentication-Results: pb1.pair.com header.from=hufeng1987@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=hufeng1987@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.216.182 as permitted sender) X-PHP-List-Original-Sender: hufeng1987@gmail.com X-Host-Fingerprint: 209.85.216.182 mail-qt0-f182.google.com Received: from [209.85.216.182] ([209.85.216.182:32942] helo=mail-qt0-f182.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 16/E7-04761-4A6A5685 for ; Thu, 29 Dec 2016 19:13:26 -0500 Received: by mail-qt0-f182.google.com with SMTP id p16so381620461qta.0 for ; Thu, 29 Dec 2016 16:13:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=/YuSiUTIaDSOVTX+vLBkHwnDiukke9CPGjEoWC2+euI=; b=nmx/X57nIxQaLeuk0zy1lELNNjVzm1VRxqtZFMVnzDf7gjgHo2zeqvxZ3Uoasykqt2 k0fILZ0XT+K/g7d5SKPDH8WExYiIZlFP+WjnCSf+AKZAjiMAJouqG2qIN9j4D1wFevVz Edjv7rfazki8wurW7Tm4n6WWSc/43+ZYkhlcQx2PdQyygrTnWgIHe1QzPx/jynG24hi3 3kJNwux0MU8cLOvX4akjVMOGKOoNwqpFQ1Zp0xfQ8PPDaKRq6/VFF3hYzAwwCsvhicso Dh007DUutUCThDeJwMnOONi6elH0uFTKEW+K4PHQBaEeWWPU2PR6cMdEfCZ02YZni1qu 1GKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=/YuSiUTIaDSOVTX+vLBkHwnDiukke9CPGjEoWC2+euI=; b=R3zpOzzms3fnb2NSGr6FkSZfbtW9m9I0XJS/Ptn703IJN6ByPvHOYpo1jrpDodZLwk cwG1v3Z0pTNq5Rgfpwcn3kfJ8Alz31zDkY3CknY5AMnmNE1qGk4m+wSh6AKwnkgw/HQv EJt38B5mn9cOtArOltiP1fv3VRaLUWX89lwoczCyhOD7C+qBXt89QtRj2qo+FtboUIeX gUecHtXZSA7YDdh88ETmCpSJcLfoIxAfXPbJPCBf7LSDPJZDwMK86U9/MzH9DqU0V4Y1 z7E5AzopJLXU9Nr10TEUEenJMHJkj74mQC/+kWeAP5DEZ5Vvm+o0+wUrgP+kEVXCSxtS DeTA== X-Gm-Message-State: AIkVDXJs/XIenUVZ9qeHO4ncsXccXq1qGU57HRneZCOkBT9Mr4F5ZrWvgd+/2zab0OqE19S2OhhebsLfkOIvZQ== X-Received: by 10.200.34.56 with SMTP id o53mr44949699qto.272.1483056801394; Thu, 29 Dec 2016 16:13:21 -0800 (PST) MIME-Version: 1.0 Received: by 10.12.180.17 with HTTP; Thu, 29 Dec 2016 16:13:01 -0800 (PST) Date: Fri, 30 Dec 2016 08:13:01 +0800 Message-ID: To: PHP Internals Content-Type: text/plain; charset=UTF-8 Subject: How to foreach each function and execute functions of an object. From: hufeng1987@gmail.com (Netroby) I am trying to modify yaf extension. i try to write code to foreach functions of an object and try to execute them. but i got segment fault. i have no idea where i was wrong. I want to implement ```php foreach ($funcName in $obj) { call_user_func([$obj, $funcName]); } ``` my code snippet was here ``` /** {{{ proto public Yaf_Application::bootstrap(void) */ PHP_METHOD(yaf_application, bootstrap) { zend_string *bootstrap_path; uint retval = 1; zend_class_entry *ce; yaf_application_t *self = getThis(); zval bootstrap; if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &bootstrap, yaf_bootstrap_ce) == FAILURE) { if (!(ce = zend_hash_str_find_ptr(EG(class_table), YAF_DEFAULT_BOOTSTRAP_LOWER, sizeof(YAF_DEFAULT_BOOTSTRAP_LOWER) - 1))) { if (YAF_G(bootstrap)) { bootstrap_path = zend_string_copy(YAF_G(bootstrap)); } else { bootstrap_path = strpprintf(0, "%s%c%s.%s", ZSTR_VAL(YAF_G(directory)), DEFAULT_SLASH, YAF_DEFAULT_BOOTSTRAP, ZSTR_VAL(YAF_G(ext))); } if (!yaf_loader_import(bootstrap_path, 0)) { php_error_docref(NULL, E_WARNING, "Couldn't find bootstrap file %s", ZSTR_VAL(bootstrap_path)); retval = 0; } else if (UNEXPECTED((ce = zend_hash_str_find_ptr(EG(class_table), YAF_DEFAULT_BOOTSTRAP_LOWER, sizeof(YAF_DEFAULT_BOOTSTRAP_LOWER) - 1)) == NULL)) { php_error_docref(NULL, E_WARNING, "Couldn't find class %s in %s", YAF_DEFAULT_BOOTSTRAP, ZSTR_VAL(bootstrap_path)); retval = 0; } else if (UNEXPECTED(!instanceof_function(ce, yaf_bootstrap_ce))) { php_error_docref(NULL, E_WARNING, "Expect a %s instance, %s give", ZSTR_VAL(yaf_bootstrap_ce->name), ZSTR_VAL(ce->name)); retval = 0; } zend_string_release(bootstrap_path); } if (UNEXPECTED(!retval)) { RETURN_FALSE; } else { zend_string *func; yaf_dispatcher_t *dispatcher; object_init_ex(&bootstrap, ce); dispatcher = zend_read_property(yaf_application_ce, self, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_DISPATCHER), 1, NULL); ZEND_HASH_FOREACH_STR_KEY(&(ce->function_table), func) { /* cann't use ZEND_STRL in strncasecmp, it cause a compile failed in VS2009 */ if (strncasecmp(ZSTR_VAL(func), YAF_BOOTSTRAP_INITFUNC_PREFIX, sizeof(YAF_BOOTSTRAP_INITFUNC_PREFIX) - 1)) { continue; } zend_call_method(&bootstrap, ce, NULL, ZSTR_VAL(func), ZSTR_LEN(func), NULL, 1, dispatcher, NULL); /** an uncaught exception threw in function call */ if (UNEXPECTED(EG(exception))) { zval_ptr_dtor(&bootstrap); RETURN_FALSE; } } ZEND_HASH_FOREACH_END(); zval_ptr_dtor(&bootstrap); } } else { // my code start here zend_string *func; yaf_dispatcher_t *dispatcher; zval *funcval; ce = Z_OBJCE_P(&bootstrap); dispatcher = zend_read_property(yaf_application_ce, self, ZEND_STRL(YAF_APPLICATION_PROPERTY_NAME_DISPATCHER), 1, NULL); ZEND_HASH_FOREACH_STR_KEY(&(ce->function_table), func) { /* cann't use ZEND_STRL in strncasecmp, it cause a compile failed in VS2009 */ if (strncasecmp(ZSTR_VAL(func), YAF_BOOTSTRAP_INITFUNC_PREFIX, sizeof(YAF_BOOTSTRAP_INITFUNC_PREFIX) - 1)) { continue; } ZVAL_STRING(funcval, &func); call_user_function(&(ce)->function_table, &bootstrap, funcval, NULL, 0, NULL); /** an uncaught exception threw in function call */ if (UNEXPECTED(EG(exception))) { zval_ptr_dtor(&bootstrap); RETURN_FALSE; } } ZEND_HASH_FOREACH_END(); zval_ptr_dtor(&bootstrap); } //my code end RETURN_ZVAL(self, 1, 0); } /* }}} */ ``` I put it on github https://gist.github.com/netroby/1fce94f023a9a45c28be0881e8429e48 And the gdb report like ``` gdb /usr/bin/php huzhifeng@devdocker ~ $ gdb /usr/bin/php GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1 Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from /usr/bin/php...(no debugging symbols found)...done. (gdb) source ./workspace/php-src/.gdbinit (gdb) run workspace/yaf-framework/public/cli.php Starting program: /usr/bin/php workspace/yaf-framework/public/cli.php [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. 0x00007fffee9010b5 in zim_yaf_application_bootstrap (execute_data=, return_value=0x7ffff3813260) at /home/huzhifeng/workspace/yaf/yaf_application.c:592 warning: Source file is more recent than executable. 592 (gdb) bt #0 0x00007fffee9010b5 in zim_yaf_application_bootstrap (execute_data=, return_value=0x7ffff3813260) at /home/huzhifeng/workspace/yaf/yaf_application.c:592 #1 0x00005555557a2c9a in dtrace_execute_internal () #2 0x0000555555837940 in ?? () #3 0x00005555557f2f8b in execute_ex () #4 0x00005555557a2b31 in dtrace_execute_ex () #5 0x0000555555846d57 in zend_execute () #6 0x00005555557b2d33 in zend_execute_scripts () #7 0x00005555557535a0 in php_execute_script () #8 0x0000555555848a17 in ?? () #9 0x00005555556380a4 in main () (gdb) zbacktrace Attempt to extract a component of a value that is not a structure. (gdb) set print object on (gdb) set print pretty on (gdb) ptype *return_value type = struct _zval_struct { zend_value value; union { struct {...} v; uint32_t type_info; } u1; union { uint32_t var_flags; uint32_t next; uint32_t cache_slot; uint32_t lineno; uint32_t num_args; uint32_t fe_pos; uint32_t fe_iter_idx; } u2; } (gdb) print *return_value; Invalid character ';' in expression. (gdb) print *return_value $1 = { value = { lval = 0, dval = 0, counted = 0x0, str = 0x0, arr = 0x0, obj = 0x0, res = 0x0, ref = 0x0, ast = 0x0, zv = 0x0, ptr = 0x0, ce = 0x0, func = 0x0, ww = { w1 = 0, w2 = 0 } }, u1 = { v = { type = 1 '\001', type_flags = 0 '\000', const_flags = 0 '\000', reserved = 0 '\000' }, type_info = 1 }, u2 = { var_flags = 0, next = 0, cache_slot = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0 } } ``` Appreciate your time. ---------------------------- Netroby