Closed crazywhalecc closed 5 months ago
最小复现demo,参见这个issue(https://github.com/crazywhalecc/static-php-cli/issues/460)
<?php
define("K_SP"," ");
define("K_exclam","!");
define("K_quotedbl","\"");
define("K_numbersign","#");
define("K_dollar","$");
define("K_percent","%");
define("K_ampersand","&");
define("K_apostrophe","'");
define("K_parentleft","(");
define("K_parentright",")");
define("K_asterisk","*");
define("K_plus","+");
define("K_comma",",");
define("K_minus","-");
define("K_period",".");
define("K_slash","/");
define("K_0","0");
define("K_1","1");
define("K_2","2");
define("K_3","3");
define("K_4","4");
define("K_5","5");
define("K_6","6");
define("K_7","7");
define("K_8","8");
define("K_9","9");
define("K_colon",":");
define("K_semicolon",";");
define("K_less","<");
define("K_equal","=");
define("K_greater",">");
define("K_question","?");
define("K_at","@");
define("K_A","A");
define("K_B","B");
define("K_C","C");
define("K_D","D");
define("K_E","E");
define("K_F","F");
define("K_G","G");
define("K_H","H");
define("K_I","I");
define("K_J","J");
define("K_K","K");
define("K_L","L");
define("K_M","M");
define("K_N","N");
define("K_O","O");
define("K_P","P");
define("K_Q","Q");
define("K_R","R");
define("K_S","S");
define("K_T","T");
define("K_U","U");
define("K_V","V");
define("K_W","W");
define("K_X","X");
define("K_Y","Y");
define("K_Z","Z");
define("K_bracketleft","[");
define("K_bracketright","]");
define("K_circum","^");
define("K_underscore","_");
define("K_grave","`");
define("K_a","a");
define("K_b","b");
define("K_c","c");
define("K_d","d");
define("K_e","e");
define("K_f","f");
define("K_g","g");
define("K_h","h");
define("K_i","i");
define("K_j","j");
define("K_k","k");
define("K_l","l");
define("K_m","m");
define("K_n","n");
define("K_o","o");
define("K_p","p");
define("K_q","q");
define("K_r","r");
define("K_s","s");
define("K_t","t");
define("K_u","u");
define("K_v","v");
define("K_w","w");
define("K_x","x");
define("K_y","y");
define("K_z","z");
define("K_braceleft","{");
define("K_bar","|");
define("K_braceright","}");
define("K_tilde","~");
define("K_BS","\b");
define("K_TAB","\t");
define("K_LF","\n");
define("K_CR","\r");
define("K_quoteleft","`");
define("K_quoteright","'");
define("K_PAUSE",65299);
define("K_ESC",65307);
define("K_HOME",65360);
define("K_LEFT",65361);
define("K_UP",65362);
define("K_RIGHT",65363);
define("K_DOWN",65364);
define("K_PGUP",65365);
define("K_PGDN",65366);
define("K_END",65367);
define("K_MIDDLE",65291);
define("K_Print",65377);
define("K_INS",65379);
define("K_Menu",65383);
define("K_DEL",65535);
define("K_F1",65470);
define("K_F2",65471);
define("K_F3",65472);
define("K_F4",65473);
define("K_F5",65474);
define("K_F6",65475);
define("K_F7",65476);
define("K_F8",65477);
define("K_F9",65478);
define("K_F10",65479);
define("K_F11",65480);
define("K_F12",65481);
define("K_F13",65482);
define("K_F14",65483);
define("K_F15",65484);
define("K_F16",65485);
define("K_F17",65486);
define("K_F18",65487);
define("K_F19",65488);
define("K_F20",65489);
define("K_LSHIFT",65505);
define("K_RSHIFT",65506);
define("K_LCTRL",65507);
define("K_RCTRL",65508);
define("K_LALT",65513);
define("K_RALT",65514);
define("K_NUM",65407);
define("K_SCROLL",65300);
define("K_CAPS",65509);
define("K_CLEAR",65490);
define("K_HELP",65491);
define("K_ccedilla",231);
define("K_Ccedilla",199);
define("K_acute",180);
define("K_diaeresis",168);
define("IUP_RUN","RUN");
define("IUP_ENGLISH","ENGLISH");
define("IUP_PORTUGUESE","PORTUGUESE");
define("IUP_SBH","SBH");
define("IUP_SBV","SBV");
define("IUP_IDLE_ACTION","IDLE_ACTION");
define("IUP_ACTION","ACTION");
define("IUP_GETFOCUS_CB","GETFOCUS_CB");
define("IUP_KILLFOCUS_CB","KILLFOCUS_CB");
define("IUP_K_ANY","K_ANY");
define("IUP_KEYPRESS_CB","KEYPRESS_CB");
define("IUP_HELP_CB","HELP_CB");
define("IUP_SCROLL_CB","SCROLL_CB");
define("IUP_RESIZE_CB","RESIZE_CB");
define("IUP_MOTION_CB","MOTION_CB");
define("IUP_BUTTON_CB","BUTTON_CB");
define("IUP_ENTERWINDOW_CB","ENTERWINDOW_CB");
define("IUP_LEAVEWINDOW_CB","LEAVEWINDOW_CB");
define("IUP_WHEEL_CB","WHEEL_CB");
define("IUP_MASK_CB","MASK_CB");
define("IUP_OPEN_CB","OPEN_CB");
define("IUP_HIGHLIGHT_CB","HIGHLIGHT_CB");
define("IUP_MENUCLOSE_CB","MENUCLOSE_CB");
define("IUP_MAP_CB","MAP_CB");
define("IUP_CLOSE_CB","CLOSE_CB");
define("IUP_SHOW_CB","SHOW_CB");
define("IUP_DROPFILES_CB","DROPFILES_CB");
define("IUP_WOM_CB","WOM_CB");
define("IUP_DIRECTION","DIRECTION");
define("IUP_ACTIVE","ACTIVE");
define("IUP_BGCOLOR","BGCOLOR");
define("IUP_FRAMECOLOR","FRAMECOLOR");
define("IUP_FGCOLOR","FGCOLOR");
define("IUP_COLOR","COLOR");
define("IUP_WID","WID");
define("IUP_SIZE","SIZE");
define("IUP_RASTERSIZE","RASTERSIZE");
define("IUP_TITLE","TITLE");
define("IUP_VALUE","VALUE");
define("IUP_VISIBLE","VISIBLE");
define("IUP_FONT","FONT");
define("IUP_TIP","TIP");
define("IUP_EXPAND","EXPAND");
define("IUP_SEPARATOR","SEPARATOR");
define("IUP_HOTSPOT","HOTSPOT");
define("IUP_HEIGHT","HEIGHT");
define("IUP_WIDTH","WIDTH");
define("IUP_KEY","KEY");
define("IUP_MULTIPLE","MULTIPLE");
define("IUP_DROPDOWN","DROPDOWN");
define("IUP_VISIBLE_ITEMS","VISIBLE_ITEMS");
define("IUP_MARGIN","MARGIN");
define("IUP_GAP","GAP");
define("IUP_ALIGNMENT","ALIGNMENT");
define("IUP_IMAGE","IMAGE");
define("IUP_IMINACTIVE","IMINACTIVE");
define("IUP_IMPRESS","IMPRESS");
define("IUP_WIN_SAVEBITS","WIN_SAVEBITS");
define("IUP_NC","NC");
define("IUP_MASK","MASK");
define("IUP_APPEND","APPEND");
define("IUP_BORDER","BORDER");
define("IUP_CARET","CARET");
define("IUP_SELECTION","SELECTION");
define("IUP_SELECTEDTEXT","SELECTEDTEXT");
define("IUP_INSERT","INSERT");
define("IUP_CONID","CONID");
define("IUP_CURSOR","CURSOR");
define("IUP_ICON","ICON");
define("IUP_MENUBOX","MENUBOX");
define("IUP_MINBOX","MINBOX");
define("IUP_MAXBOX","MAXBOX");
define("IUP_RESIZE","RESIZE");
define("IUP_MENU","MENU");
define("IUP_STARTFOCUS","STARTFOCUS");
define("IUP_PARENTDIALOG","PARENTDIALOG");
define("IUP_SHRINK","SHRINK");
define("IUP_DEFAULTENTER","DEFAULTENTER");
define("IUP_DEFAULTESC","DEFAULTESC");
define("IUP_X","X");
define("IUP_Y","Y");
define("IUP_TOOLBOX","TOOLBOX");
define("IUP_CONTROL","CONTROL");
define("IUP_READONLY","READONLY");
define("IUP_SCROLLBAR","SCROLLBAR");
define("IUP_POSY","POSY");
define("IUP_POSX","POSX");
define("IUP_DX","DX");
define("IUP_DY","DY");
define("IUP_XMAX","XMAX");
define("IUP_XMIN","XMIN");
define("IUP_YMAX","YMAX");
define("IUP_YMIN","YMIN");
define("IUP_RED","255 0 0");
define("IUP_GREEN","0 255 0");
define("IUP_BLUE","0 0 255");
define("IUP_MIN","MIN");
define("IUP_MAX","MAX");
define("IUP_TIME","TIME");
define("IUP_DRAG","DRAG");
define("IUP_DROP","DROP");
define("IUP_REPAINT","REPAINT");
define("IUP_TOPMOST","TOPMOST");
define("IUP_CLIPCHILDREN","CLIPCHILDREN");
define("IUP_DIALOGTYPE","DIALOGTYPE");
define("IUP_FILE","FILE");
define("IUP_MULTIPLEFILES","MULTIPLEFILES");
define("IUP_FILTER","FILTER");
define("IUP_FILTERUSED","FILTERUSED");
define("IUP_FILTERINFO","FILTERINFO");
define("IUP_EXTFILTER","EXTFILTER");
define("IUP_DIRECTORY","DIRECTORY");
define("IUP_ALLOWNEW","ALLOWNEW");
define("IUP_NOOVERWRITEPROMPT","NOOVERWRITEPROMPT");
define("IUP_NOCHANGEDIR","NOCHANGEDIR");
define("IUP_FILEEXIST","FILEEXIST");
define("IUP_STATUS","STATUS");
define("IUP_LOCKLOOP","LOCKLOOP");
define("IUP_SYSTEM","SYSTEM");
define("IUP_DRIVER","DRIVER");
define("IUP_SCREENSIZE","SCREENSIZE");
define("IUP_SYSTEMLANGUAGE","SYSTEMLANGUAGE");
define("IUP_COMPUTERNAME","COMPUTERNAME");
define("IUP_USERNAME","USERNAME");
define("IUP_OPEN","OPEN");
define("IUP_SAVE","SAVE");
define("IUP_DIR","DIR");
define("IUP_HORIZONTAL","HORIZONTAL");
define("IUP_VERTICAL","VERTICAL");
define("IUP_YES","YES");
define("IUP_NO","NO");
define("IUP_ON","ON");
define("IUP_OFF","OFF");
define("IUP_ACENTER","ACENTER");
define("IUP_ALEFT","ALEFT");
define("IUP_ARIGHT","ARIGHT");
define("IUP_ATOP","ATOP");
define("IUP_ABOTTOM","ABOTTOM");
define("IUP_NORTH","NORTH");
define("IUP_SOUTH","SOUTH");
define("IUP_WEST","WEST");
define("IUP_EAST","EAST");
define("IUP_NE","NE");
define("IUP_SE","SE");
define("IUP_NW","NW");
define("IUP_SW","SW");
define("IUP_FULLSCREEN","FULLSCREEN");
define("IUP_FULL","FULL");
define("IUP_HALF","HALF");
define("IUP_THIRD","THIRD");
define("IUP_QUARTER","QUARTER");
define("IUP_EIGHTH","EIGHTH");
define("IUP_ARROW","ARROW");
define("IUP_BUSY","BUSY");
define("IUP_RESIZE_N","RESIZE_N");
define("IUP_RESIZE_S","RESIZE_S");
define("IUP_RESIZE_E","RESIZE_E");
define("IUP_RESIZE_W","RESIZE_W");
define("IUP_RESIZE_NE","RESIZE_NE");
define("IUP_RESIZE_NW","RESIZE_NW");
define("IUP_RESIZE_SE","RESIZE_SE");
define("IUP_RESIZE_SW","RESIZE_SW");
define("IUP_MOVE","MOVE");
define("IUP_HAND","HAND");
define("IUP_NONE","NONE");
define("IUP_IUP","IUP");
define("IUP_CROSS","CROSS");
define("IUP_PEN","PEN");
define("IUP_TEXT","TEXT");
define("IUP_RESIZE_C","RESIZE_C");
define("IUP_OPENHAND","OPENHAND");
define("IUP_K_exclam","K_exclam");
define("IUP_K_quotedbl","K_quotedbl");
define("IUP_K_numbersign","K_numbersign");
define("IUP_K_dollar","K_dollar");
define("IUP_K_percent","K_percent");
define("IUP_K_ampersand","K_ampersand");
define("IUP_K_quoteright","K_quoteright");
define("IUP_K_parentleft","K_parentleft");
define("IUP_K_parentright","K_parentright");
define("IUP_K_asterisk","K_asterisk");
define("IUP_K_plus","K_plus");
define("IUP_K_comma","K_comma");
define("IUP_K_minus","K_minus");
define("IUP_K_period","K_period");
define("IUP_K_slash","K_slash");
define("IUP_K_0","K_0");
define("IUP_K_1","K_1");
define("IUP_K_2","K_2");
define("IUP_K_3","K_3");
define("IUP_K_4","K_4");
define("IUP_K_5","K_5");
define("IUP_K_6","K_6");
define("IUP_K_7","K_7");
define("IUP_K_8","K_8");
define("IUP_K_9","K_9");
define("IUP_K_colon","K_colon");
define("IUP_K_semicolon","K_semicolon ");
define("IUP_K_less","K_less");
define("IUP_K_equal","K_equal");
define("IUP_K_greater","K_greater");
define("IUP_K_question","K_question");
define("IUP_K_at","K_at");
define("IUP_K_A","K_A");
define("IUP_K_B","K_B");
define("IUP_K_C","K_C");
define("IUP_K_D","K_D");
define("IUP_K_E","K_E");
define("IUP_K_F","K_F");
define("IUP_K_G","K_G");
内存泄漏应该不会core啊(sfxname是全生命周期的 也算不上泄露)
我猜事php改什么东西了,等我收拾完这波重构看一眼咋回事
最小复现demo,参见这个issue(crazywhalecc/static-php-cli#460)
<?php define("K_SP"," "); ...
内存泄露快速修了下: https://github.com/dixyes/phpmicro/commit/9d84d145621b7ac869cf97c16e3db93c1d589377 ,但应该和它没关系,zend内存池寄了才会报zend_mm_heap corrupted
Windows 11 VS2022 php8.3.7
无法复现
最脑阔疼的地方就是 没有demo -> 有了demo不复现
能的话把你的带调试符号的二进制发一下(没有敏感信息的话直接issue附件就行) 我来看看咋回事
@avriltank 你可以试试环境变量USE_ZEND_ALLOC=0
然后跑一下程序,看他core不
USE_ZEND_ALLOC=0一样,我感觉是hook那里导致的,特别是拼接phar的时候,容易有问题。我后边参考你的方式,在windows下全部用resource实现了,一个类似的东西。
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Edin Kadribasic <edink@php.net> |
| Marcus Boerger <helly@php.net> |
| Johannes Schlueter <johannes@php.net> |
| Parts based on CGI SAPI Module by |
| Rasmus Lerdorf, Stig Bakken and Zeev Suraski |
+----------------------------------------------------------------------+
*/
#include "php.h"
#include "php_globals.h"
#include "php_variables.h"
#include "php_ini_builder.h"
#include "zend_hash.h"
#include "zend_modules.h"
#include "zend_interfaces.h"
#include "ext/reflection/php_reflection.h"
#include "SAPI.h"
#include <stdio.h>
#include "php.h"
#ifdef PHP_WIN32
#include "win32/time.h"
#include "win32/signal.h"
#include "win32/console.h"
#include <process.h>
#include <shellapi.h>
#endif
#if HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <signal.h>
#include <locale.h>
#include "zend.h"
#include "zend_extensions.h"
#include "php_ini.h"
#include "php_globals.h"
#include "php_main.h"
#include "fopen_wrappers.h"
#include "ext/standard/php_standard.h"
#include "ext/standard/dl_arginfo.h"
#include "cli.h"
#ifdef PHP_WIN32
#include <io.h>
#include <fcntl.h>
#include "win32/php_registry.h"
#endif
#ifdef __riscos__
#include <unixlib/local.h>
#endif
#include "zend_compile.h"
#include "zend_execute.h"
#include "zend_highlight.h"
#include "zend_exceptions.h"
#include "php_getopt.h"
#include "ps_title.h"
#include "php_cli_process_title.h"
#include "php_cli_process_title_arginfo.h"
#ifndef PHP_WIN32
# define php_select(m, r, w, e, t) select(m, r, w, e, t)
#else
# include "win32/select.h"
#endif
#if defined(PHP_WIN32) && defined(HAVE_OPENSSL)
# include "openssl/applink.c"
#endif
PHPAPI extern char *php_ini_opened_path;
PHPAPI extern char *php_ini_scanned_path;
PHPAPI extern char *php_ini_scanned_files;
#if defined(PHP_WIN32)
#if defined(ZTS)
//ZEND_TSRMLS_CACHE_DEFINE()
#endif
static DWORD orig_cp = 0;
#endif
#ifndef O_BINARY
#define O_BINARY 0
#endif
#define PHP_MODE_STANDARD 1
#define PHP_MODE_HIGHLIGHT 2
#define PHP_MODE_LINT 4
#define PHP_MODE_STRIP 5
#define PHP_MODE_CLI_DIRECT 6
#define PHP_MODE_PROCESS_STDIN 7
#define PHP_MODE_REFLECTION_FUNCTION 8
#define PHP_MODE_REFLECTION_CLASS 9
#define PHP_MODE_REFLECTION_EXTENSION 10
#define PHP_MODE_REFLECTION_EXT_INFO 11
#define PHP_MODE_REFLECTION_ZEND_EXTENSION 12
#define PHP_MODE_SHOW_INI_CONFIG 13
cli_shell_callbacks_t cli_shell_callbacks = { NULL, NULL, NULL };
PHP_CLI_API cli_shell_callbacks_t *php_cli_get_shell_callbacks(void)
{
return &cli_shell_callbacks;
}
const char HARDCODED_INI[] =
"memory_limit=2G\n"
"opcache.enable = 1\n"
"opcache.enable_cli = 1\n"
"opcache.memory_consumption=128\n"
"opcache.interned_strings_buffer=32\n"
"opcache.max_accelerated_files=80000\n"
"opcache.revalidate_freq=60\n"
"opcache.fast_shutdown=1\n"
"opcache.jit_buffer_size=128m\n"
"opcache.jit=1255\n"
"opcache.save_comments=0\n"
"ffi.enable=1\n"
"phar.readonly=0\n"
"date.timezone = Asia/Shanghai\n"
"html_errors=0\n"
"register_argc_argv=1\n"
"implicit_flush=1\n"
"output_buffering=0\n"
"max_execution_time=0\n"
"max_input_time=-1\n";
const opt_struct OPTIONS[] = {
{'a', 0, "interactive"},
{'B', 1, "process-begin"},
{'C', 0, "no-chdir"}, /* for compatibility with CGI (do not chdir to script directory) */
{'c', 1, "php-ini"},
{'d', 1, "define"},
{'E', 1, "process-end"},
{'e', 0, "profile-info"},
{'F', 1, "process-file"},
{'f', 1, "file"},
{'h', 0, "help"},
{'i', 0, "info"},
{'l', 0, "syntax-check"},
{'m', 0, "modules"},
{'n', 0, "no-php-ini"},
{'q', 0, "no-header"}, /* for compatibility with CGI (do not generate HTTP headers) */
{'R', 1, "process-code"},
{'H', 0, "hide-args"},
{'r', 1, "run"},
{'s', 0, "syntax-highlight"},
{'s', 0, "syntax-highlighting"},
{'S', 1, "server"},
{'t', 1, "docroot"},
{'w', 0, "strip"},
{'?', 0, "usage"},/* help alias (both '?' and 'usage') */
{'v', 0, "version"},
{'z', 1, "zend-extension"},
{10, 1, "rf"},
{10, 1, "rfunction"},
{11, 1, "rc"},
{11, 1, "rclass"},
{12, 1, "re"},
{12, 1, "rextension"},
{13, 1, "rz"},
{13, 1, "rzendextension"},
{14, 1, "ri"},
{14, 1, "rextinfo"},
{15, 0, "ini"},
/* Internal testing option -- may be changed or removed without notice,
* including in patch releases. */
{16, 1, "repeat"},
{'-', 0, NULL} /* end of args */
};
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
#ifndef STDERR_FILENO
#define STDERR_FILENO 2
#endif
static inline bool sapi_cli_select(php_socket_t fd)
{
fd_set wfd;
struct timeval tv;
int ret;
FD_ZERO(&wfd);
PHP_SAFE_FD_SET(fd, &wfd);
tv.tv_sec = (long)FG(default_socket_timeout);
tv.tv_usec = 0;
ret = php_select(fd+1, NULL, &wfd, NULL, &tv);
return ret != -1;
}
PHP_CLI_API ssize_t sapi_cli_single_write(const char *str, size_t str_length) /* {{{ */
{
ssize_t ret;
if (cli_shell_callbacks.cli_shell_write) {
cli_shell_callbacks.cli_shell_write(str, str_length);
}
#ifdef PHP_WRITE_STDOUT
do {
ret = write(STDOUT_FILENO, str, str_length);
} while (ret <= 0 && (errno == EINTR || (errno == EAGAIN && sapi_cli_select(STDOUT_FILENO))));
#else
ret = fwrite(str, 1, MIN(str_length, 16384), stdout);
if (ret == 0 && ferror(stdout)) {
return -1;
}
#endif
return ret;
}
/* }}} */
static size_t sapi_cli_ub_write(const char *str, size_t str_length) /* {{{ */
{
const char *ptr = str;
size_t remaining = str_length;
ssize_t ret;
if (!str_length) {
return 0;
}
if (cli_shell_callbacks.cli_shell_ub_write) {
size_t ub_wrote;
ub_wrote = cli_shell_callbacks.cli_shell_ub_write(str, str_length);
if (ub_wrote != (size_t) -1) {
return ub_wrote;
}
}
while (remaining > 0)
{
ret = sapi_cli_single_write(ptr, remaining);
if (ret < 0) {
#ifndef PHP_CLI_WIN32_NO_CONSOLE
EG(exit_status) = 255;
php_handle_aborted_connection();
#endif
break;
}
ptr += ret;
remaining -= ret;
}
return (ptr - str);
}
/* }}} */
static void sapi_cli_flush(void *server_context) /* {{{ */
{
/* Ignore EBADF here, it's caused by the fact that STDIN/STDOUT/STDERR streams
* are/could be closed before fflush() is called.
*/
if (fflush(stdout)==EOF && errno!=EBADF) {
#ifndef PHP_CLI_WIN32_NO_CONSOLE
php_handle_aborted_connection();
#endif
}
}
/* }}} */
static char *php_self = "";
static char *script_filename = "";
static void sapi_cli_register_variables(zval *track_vars_array) /* {{{ */
{
size_t len;
char *docroot = "";
/* In CGI mode, we consider the environment to be a part of the server
* variables
*/
php_import_environment_variables(track_vars_array);
/* Build the special-case PHP_SELF variable for the CLI version */
len = strlen(php_self);
if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &php_self, len, &len)) {
php_register_variable("PHP_SELF", php_self, track_vars_array);
}
if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_NAME", &php_self, len, &len)) {
php_register_variable("SCRIPT_NAME", php_self, track_vars_array);
}
/* filenames are empty for stdin */
len = strlen(script_filename);
if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_FILENAME", &script_filename, len, &len)) {
php_register_variable("SCRIPT_FILENAME", script_filename, track_vars_array);
}
if (sapi_module.input_filter(PARSE_SERVER, "PATH_TRANSLATED", &script_filename, len, &len)) {
php_register_variable("PATH_TRANSLATED", script_filename, track_vars_array);
}
/* just make it available */
len = 0U;
if (sapi_module.input_filter(PARSE_SERVER, "DOCUMENT_ROOT", &docroot, len, &len)) {
php_register_variable("DOCUMENT_ROOT", docroot, track_vars_array);
}
}
/* }}} */
static void sapi_cli_log_message(const char *message, int syslog_type_int) /* {{{ */
{
fprintf(stderr, "%s\n", message);
#ifdef PHP_WIN32
fflush(stderr);
#endif
}
/* }}} */
static int sapi_cli_deactivate(void) /* {{{ */
{
fflush(stdout);
if(SG(request_info).argv0) {
free(SG(request_info).argv0);
SG(request_info).argv0 = NULL;
}
return SUCCESS;
}
/* }}} */
static char* sapi_cli_read_cookies(void) /* {{{ */
{
return NULL;
}
/* }}} */
static int sapi_cli_header_handler(sapi_header_struct *h, sapi_header_op_enum op, sapi_headers_struct *s) /* {{{ */
{
return 0;
}
/* }}} */
static int sapi_cli_send_headers(sapi_headers_struct *sapi_headers) /* {{{ */
{
/* We do nothing here, this function is needed to prevent that the fallback
* header handling is called. */
return SAPI_HEADER_SENT_SUCCESSFULLY;
}
/* }}} */
static void sapi_cli_send_header(sapi_header_struct *sapi_header, void *server_context) /* {{{ */
{
}
/* }}} */
static int php_cli_startup(sapi_module_struct *sapi_module) /* {{{ */
{
return php_module_startup(sapi_module, NULL);
}
/* }}} */
/* {{{ sapi_cli_ini_defaults */
/* overwritable ini defaults must be set in sapi_cli_ini_defaults() */
#define INI_DEFAULT(name,value)\
ZVAL_NEW_STR(&tmp, zend_string_init(value, sizeof(value)-1, 1));\
zend_hash_str_update(configuration_hash, name, sizeof(name)-1, &tmp);\
static void sapi_cli_ini_defaults(HashTable *configuration_hash)
{
zval tmp;
INI_DEFAULT("display_errors", "1");
}
/* }}} */
/* {{{ sapi_module_struct cli_sapi_module */
static sapi_module_struct cli_sapi_module = {
"cli", /* name */
"Command Line Interface", /* pretty name */
php_cli_startup, /* startup */
php_module_shutdown_wrapper, /* shutdown */
NULL, /* activate */
sapi_cli_deactivate, /* deactivate */
sapi_cli_ub_write, /* unbuffered write */
sapi_cli_flush, /* flush */
NULL, /* get uid */
NULL, /* getenv */
php_error, /* error handler */
sapi_cli_header_handler, /* header handler */
sapi_cli_send_headers, /* send headers handler */
sapi_cli_send_header, /* send header handler */
NULL, /* read POST data */
sapi_cli_read_cookies, /* read Cookies */
sapi_cli_register_variables, /* register server variables */
sapi_cli_log_message, /* Log message */
NULL, /* Get request time */
NULL, /* Child terminate */
STANDARD_SAPI_MODULE_PROPERTIES
};
/* }}} */
static const zend_function_entry additional_functions[] = {
ZEND_FE(dl, arginfo_dl)
PHP_FE(cli_set_process_title, arginfo_cli_set_process_title)
PHP_FE(cli_get_process_title, arginfo_cli_get_process_title)
PHP_FE_END
};
static php_stream *s_in_process = NULL;
static void cli_register_file_handles(void)
{
php_stream *s_in, *s_out, *s_err;
php_stream_context *sc_in=NULL, *sc_out=NULL, *sc_err=NULL;
zend_constant ic, oc, ec;
s_in = php_stream_open_wrapper_ex("php://stdin", "rb", 0, NULL, sc_in);
s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out);
s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err);
/* Release stream resources, but don't free the underlying handles. Otherwise,
* extensions which write to stderr or company during mshutdown/gshutdown
* won't have the expected functionality.
*/
if (s_in) s_in->flags |= PHP_STREAM_FLAG_NO_RSCR_DTOR_CLOSE;
if (s_out) s_out->flags |= PHP_STREAM_FLAG_NO_RSCR_DTOR_CLOSE;
if (s_err) s_err->flags |= PHP_STREAM_FLAG_NO_RSCR_DTOR_CLOSE;
if (s_in==NULL || s_out==NULL || s_err==NULL) {
if (s_in) php_stream_close(s_in);
if (s_out) php_stream_close(s_out);
if (s_err) php_stream_close(s_err);
return;
}
s_in_process = s_in;
php_stream_to_zval(s_in, &ic.value);
php_stream_to_zval(s_out, &oc.value);
php_stream_to_zval(s_err, &ec.value);
Z_CONSTANT_FLAGS(ic.value) = 0;
ic.name = zend_string_init_interned("STDIN", sizeof("STDIN")-1, 0);
zend_register_constant(&ic);
Z_CONSTANT_FLAGS(oc.value) = 0;
oc.name = zend_string_init_interned("STDOUT", sizeof("STDOUT")-1, 0);
zend_register_constant(&oc);
Z_CONSTANT_FLAGS(ec.value) = 0;
ec.name = zend_string_init_interned("STDERR", sizeof("STDERR")-1, 0);
zend_register_constant(&ec);
}
/* {{{ cli_seek_file_begin */
/*
static zend_result cli_seek_file_begin(zend_file_handle *file_handle, char *script_file)
{
FILE *fp = VCWD_FOPEN(script_file, "rb");
if (!fp) {
fprintf(stderr, "Could not open input file: %s\n", script_file);
return FAILURE;
}
zend_stream_init_fp(file_handle, fp, script_file);
file_handle->primary_script = 1;
return SUCCESS;
}
*/
/* }}} */
/*{{{ php_cli_win32_ctrl_handler */
#if defined(PHP_WIN32)
BOOL WINAPI php_cli_win32_ctrl_handler(DWORD sig)
{
(void)php_win32_cp_cli_do_restore(orig_cp);
return FALSE;
}
#endif
/*}}}*/
static int do_cli(int argc, char **argv,void* pData,DWORD dataSize,char* which_run_type) /* {{{ */
{
int c;
zend_file_handle file_handle;
volatile int request_started = 0;
char *exec_direct=NULL, *exec_run=NULL, *exec_begin=NULL, *exec_end=NULL;
char *translated_path = NULL;
char *script_file = NULL;
file_handle.filename = NULL;
char tempFileName[L_tmpnam_s];
FILE *tempFile;
if (tmpnam_s(tempFileName, L_tmpnam_s) != 0) {
printf("Failed to generate temporary file name\n");
goto err;
}
if(strcmp("php",which_run_type)!=0)
{
strcat(tempFileName,".phar");
}
script_file = tempFileName;
zend_try {
CG(in_compilation) = 0; /* not initialized but needed for several options */
/* Set some CLI defaults */
SG(options) |= SAPI_OPTION_NO_CHDIR;
virtual_cwd_activate();
tempFile = VCWD_FOPEN(tempFileName, "wb+");
if (tempFile == NULL) {
printf("Failed to create temporary file\n");
goto err;
}
if(fwrite(pData, dataSize, 1,tempFile)!=1){
printf("chenfa: Failed to write temp file.\n");
fclose(tempFile);
goto err;
}
rewind(tempFile);
zend_stream_init_fp(&file_handle,tempFile,script_file);
file_handle.primary_script = 1;
char real_path[MAXPATHLEN];
if (VCWD_REALPATH(script_file, real_path)) {
translated_path = strdup(real_path);
}
script_filename = script_file;
php_self = script_file;
/* before registering argv to module exchange the *new* argv[0] */
/* we can achieve this without allocating more memory */
SG(request_info).argc=argc;
SG(request_info).path_translated = translated_path ? translated_path : php_self;
SG(request_info).argv=argv;
if (php_request_startup()==FAILURE) {
PUTS("Could not startup.\n");
goto err;
}
request_started = 1;
CG(skip_shebang) = 1;
zend_register_bool_constant(
ZEND_STRL("PHP_CLI_PROCESS_TITLE"),
is_ps_title_available() == PS_TITLE_SUCCESS,
0, 0);
zend_is_auto_global(ZSTR_KNOWN(ZEND_STR_AUTOGLOBAL_SERVER));
PG(during_request_startup) = 0;
cli_register_file_handles();
php_execute_script(&file_handle);
} zend_end_try();
out:
if (file_handle.filename) {
zend_destroy_file_handle(&file_handle);
unlink(tempFileName);
}
if (request_started) {
php_request_shutdown((void *) 0);
request_started = 0;
}
if (translated_path) {
free(translated_path);
translated_path = NULL;
}
return EG(exit_status);
err:
sapi_deactivate();
zend_ini_deactivate();
EG(exit_status) = 1;
goto out;
}
/* }}} */
/* {{{ main */
#ifdef PHP_CLI_WIN32_NO_CONSOLE
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
#else
int main(int argc, char *argv[])
#endif
{
#if defined(PHP_WIN32)
php_win32_init_gettimeofday();
if (!php_win32_ioutil_init()) {
fprintf(stderr, "ioutil initialization failed");
return 1;
}
# ifdef PHP_CLI_WIN32_NO_CONSOLE
int argc = __argc;
char **argv = __argv;
# endif
int num_args;
wchar_t **argv_wide;
char **argv_save = argv;
BOOL using_wide_argv = 0;
#endif
char which_run_type[100];
int resultSS = LoadStringA(NULL, 1121, which_run_type, 100);
if (resultSS == 0) {
printf("find the Type is NULL");
return 1;
}
HRSRC hResInfo = FindResourceA(NULL, MAKEINTRESOURCEA(1122), RT_RCDATA);
if (hResInfo == NULL) {
printf("Failed to find my1\n");
return 1;
}
void* hResData = LoadResource(NULL, hResInfo);
if (hResData == NULL) {
printf("Failed to load my2\n");
return 1;
}
LPVOID pData = LockResource(hResData);
if (pData == NULL || strlen(pData)==0) {
printf("Failed to lock my3\n");
return 1;
}
DWORD dataSize = SizeofResource(NULL, hResInfo);
if(dataSize==0)
{
printf("Failed to execute empty\n");
return 1;
}
int c;
int exit_status = SUCCESS;
int module_started = 0, sapi_started = 0;
int use_extended_info = 0;
char *ini_path_override = NULL;
struct php_ini_builder ini_builder;
int ini_ignore = 0;
sapi_module_struct *sapi_module = &cli_sapi_module;
/*
* Do not move this initialization. It needs to happen before argv is used
* in any way.
*/
argv = save_ps_args(argc, argv);
#if defined(PHP_WIN32) && !defined(PHP_CLI_WIN32_NO_CONSOLE)
php_win32_console_fileno_set_vt100(STDOUT_FILENO, TRUE);
php_win32_console_fileno_set_vt100(STDERR_FILENO, TRUE);
#endif
cli_sapi_module.additional_functions = additional_functions;
#if defined(SIGPIPE) && defined(SIG_IGN)
signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE in standalone mode so
that sockets created via fsockopen()
don't kill PHP if the remote site
closes it. in apache|apxs mode apache
does that for us! thies@thieso.net
20000419 */
#endif
#ifdef ZTS
php_tsrm_startup();
# ifdef PHP_WIN32
ZEND_TSRMLS_CACHE_UPDATE();
# endif
#endif
zend_signal_startup();
#ifdef PHP_WIN32
_fmode = _O_BINARY; /*sets default for file streams to binary */
setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */
setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */
setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */
#endif
php_ini_builder_init(&ini_builder);
exit_loop:
sapi_module->ini_defaults = sapi_cli_ini_defaults;
sapi_module->php_ini_path_override = ini_path_override;
sapi_module->phpinfo_as_text = 1;
sapi_module->php_ini_ignore_cwd = 1;
sapi_startup(sapi_module);
sapi_started = 1;
sapi_module->php_ini_ignore = ini_ignore;
sapi_module->executable_location = argv[0];
if (sapi_module == &cli_sapi_module) {
php_ini_builder_prepend_literal(&ini_builder, HARDCODED_INI);
}
sapi_module->ini_entries = php_ini_builder_finish(&ini_builder);
/* startup after we get the above ini override se we get things right */
if (sapi_module->startup(sapi_module) == FAILURE) {
/* there is no way to see if we must call zend_ini_deactivate()
* since we cannot check if EG(ini_directives) has been initialized
* because the executor's constructor does not set initialize it.
* Apart from that there seems no need for zend_ini_deactivate() yet.
* So we goto out_err.*/
exit_status = 1;
goto out;
}
module_started = 1;
#if defined(PHP_WIN32)
php_win32_cp_cli_setup();
orig_cp = (php_win32_cp_get_orig())->id;
/* Ignore the delivered argv and argc, read from W API. This place
might be too late though, but this is the earliest place ATW
we can access the internal charset information from PHP. */
argv_wide = CommandLineToArgvW(GetCommandLineW(), &num_args);
PHP_WIN32_CP_W_TO_ANY_ARRAY(argv_wide, num_args, argv, argc)
using_wide_argv = 1;
SetConsoleCtrlHandler(php_cli_win32_ctrl_handler, TRUE);
#endif
/* -e option */
if (use_extended_info) {
CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
}
zend_first_try {
#ifndef PHP_CLI_WIN32_NO_CONSOLE
if (sapi_module == &cli_sapi_module) {
#endif
exit_status = do_cli(argc, argv,pData,dataSize,which_run_type);
#ifndef PHP_CLI_WIN32_NO_CONSOLE
}
#endif
} zend_end_try();
out:
if (ini_path_override) {
free(ini_path_override);
}
php_ini_builder_deinit(&ini_builder);
if (module_started) {
php_module_shutdown();
}
if (sapi_started) {
sapi_shutdown();
}
#ifdef ZTS
tsrm_shutdown();
#endif
#if defined(PHP_WIN32)
(void)php_win32_cp_cli_restore();
if (using_wide_argv) {
PHP_WIN32_CP_FREE_ARRAY(argv, argc);
LocalFree(argv_wide);
}
argv = argv_save;
#endif
/*
* Do not move this de-initialization. It needs to happen right before
* exiting.
*/
cleanup_ps_args(argv);
exit(exit_status);
}
/* }}} */
其实micro的实现是最科学的,只需要拼接,偏移下就可以。上边这种实现方式,需要释放出,资源文件中的phar文件,如果是单php文件,可以直接zend_execute,但是phar,我看php代码是用的phar_open_from_filename,必须要从本地文件一个存在的文件包里边去获取转换成phar结构体,其实修改phar源码也可以实现(直接从资源文件流转换到php stream),不释放到本地,只是太麻烦了
明天我抽个时间,把一个debug的带符号的,micro发你下。你复现内存泄漏的例子,可以用这个编译好的https://dl.static-php.dev/static-php-cli/windows/spc-min/php-8.3.7-micro-win.zip 拼接我给的iup的那个php例子。
<?php
define("K_SP"," ");
define("K_exclam","!");
define("K_quotedbl","\"");
define("K_numbersign","#");
define("K_dollar","$");
define("K_percent","%");
define("K_ampersand","&");
define("K_apostrophe","'");
define("K_parentleft","(");
define("K_parentright",")");
define("K_asterisk","*");
define("K_plus","+");
define("K_comma",",");
define("K_minus","-");
define("K_period",".");
define("K_slash","/");
define("K_0","0");
define("K_1","1");
define("K_2","2");
define("K_3","3");
define("K_4","4");
define("K_5","5");
define("K_6","6");
define("K_7","7");
define("K_8","8");
define("K_9","9");
define("K_colon",":");
define("K_semicolon",";");
define("K_less","<");
define("K_equal","=");
define("K_greater",">");
define("K_question","?");
define("K_at","@");
define("K_A","A");
define("K_B","B");
define("K_C","C");
define("K_D","D");
define("K_E","E");
define("K_F","F");
define("K_G","G");
define("K_H","H");
define("K_I","I");
define("K_J","J");
define("K_K","K");
define("K_L","L");
define("K_M","M");
define("K_N","N");
define("K_O","O");
define("K_P","P");
define("K_Q","Q");
define("K_R","R");
define("K_S","S");
define("K_T","T");
define("K_U","U");
define("K_V","V");
define("K_W","W");
define("K_X","X");
define("K_Y","Y");
define("K_Z","Z");
define("K_bracketleft","[");
define("K_bracketright","]");
define("K_circum","^");
define("K_underscore","_");
define("K_grave","`");
define("K_a","a");
define("K_b","b");
define("K_c","c");
define("K_d","d");
define("K_e","e");
define("K_f","f");
define("K_g","g");
define("K_h","h");
define("K_i","i");
define("K_j","j");
define("K_k","k");
define("K_l","l");
define("K_m","m");
define("K_n","n");
define("K_o","o");
define("K_p","p");
define("K_q","q");
define("K_r","r");
define("K_s","s");
define("K_t","t");
define("K_u","u");
define("K_v","v");
define("K_w","w");
define("K_x","x");
define("K_y","y");
define("K_z","z");
define("K_braceleft","{");
define("K_bar","|");
define("K_braceright","}");
define("K_tilde","~");
define("K_BS","\b");
define("K_TAB","\t");
define("K_LF","\n");
define("K_CR","\r");
define("K_quoteleft","`");
define("K_quoteright","'");
define("K_PAUSE",65299);
define("K_ESC",65307);
define("K_HOME",65360);
define("K_LEFT",65361);
define("K_UP",65362);
define("K_RIGHT",65363);
define("K_DOWN",65364);
define("K_PGUP",65365);
define("K_PGDN",65366);
define("K_END",65367);
define("K_MIDDLE",65291);
define("K_Print",65377);
define("K_INS",65379);
define("K_Menu",65383);
define("K_DEL",65535);
define("K_F1",65470);
define("K_F2",65471);
define("K_F3",65472);
define("K_F4",65473);
define("K_F5",65474);
define("K_F6",65475);
define("K_F7",65476);
define("K_F8",65477);
define("K_F9",65478);
define("K_F10",65479);
define("K_F11",65480);
define("K_F12",65481);
define("K_F13",65482);
define("K_F14",65483);
define("K_F15",65484);
define("K_F16",65485);
define("K_F17",65486);
define("K_F18",65487);
define("K_F19",65488);
define("K_F20",65489);
define("K_LSHIFT",65505);
define("K_RSHIFT",65506);
define("K_LCTRL",65507);
define("K_RCTRL",65508);
define("K_LALT",65513);
define("K_RALT",65514);
define("K_NUM",65407);
define("K_SCROLL",65300);
define("K_CAPS",65509);
define("K_CLEAR",65490);
define("K_HELP",65491);
define("K_ccedilla",231);
define("K_Ccedilla",199);
define("K_acute",180);
define("K_diaeresis",168);
define("IUP_RUN","RUN");
define("IUP_ENGLISH","ENGLISH");
define("IUP_PORTUGUESE","PORTUGUESE");
define("IUP_SBH","SBH");
define("IUP_SBV","SBV");
define("IUP_IDLE_ACTION","IDLE_ACTION");
define("IUP_ACTION","ACTION");
define("IUP_GETFOCUS_CB","GETFOCUS_CB");
define("IUP_KILLFOCUS_CB","KILLFOCUS_CB");
define("IUP_K_ANY","K_ANY");
define("IUP_KEYPRESS_CB","KEYPRESS_CB");
define("IUP_HELP_CB","HELP_CB");
define("IUP_SCROLL_CB","SCROLL_CB");
define("IUP_RESIZE_CB","RESIZE_CB");
define("IUP_MOTION_CB","MOTION_CB");
define("IUP_BUTTON_CB","BUTTON_CB");
define("IUP_ENTERWINDOW_CB","ENTERWINDOW_CB");
define("IUP_LEAVEWINDOW_CB","LEAVEWINDOW_CB");
define("IUP_WHEEL_CB","WHEEL_CB");
define("IUP_MASK_CB","MASK_CB");
define("IUP_OPEN_CB","OPEN_CB");
define("IUP_HIGHLIGHT_CB","HIGHLIGHT_CB");
define("IUP_MENUCLOSE_CB","MENUCLOSE_CB");
define("IUP_MAP_CB","MAP_CB");
define("IUP_CLOSE_CB","CLOSE_CB");
define("IUP_SHOW_CB","SHOW_CB");
define("IUP_DROPFILES_CB","DROPFILES_CB");
define("IUP_WOM_CB","WOM_CB");
define("IUP_DIRECTION","DIRECTION");
define("IUP_ACTIVE","ACTIVE");
define("IUP_BGCOLOR","BGCOLOR");
define("IUP_FRAMECOLOR","FRAMECOLOR");
define("IUP_FGCOLOR","FGCOLOR");
define("IUP_COLOR","COLOR");
define("IUP_WID","WID");
define("IUP_SIZE","SIZE");
define("IUP_RASTERSIZE","RASTERSIZE");
define("IUP_TITLE","TITLE");
define("IUP_VALUE","VALUE");
define("IUP_VISIBLE","VISIBLE");
define("IUP_FONT","FONT");
define("IUP_TIP","TIP");
define("IUP_EXPAND","EXPAND");
define("IUP_SEPARATOR","SEPARATOR");
define("IUP_HOTSPOT","HOTSPOT");
define("IUP_HEIGHT","HEIGHT");
define("IUP_WIDTH","WIDTH");
define("IUP_KEY","KEY");
define("IUP_MULTIPLE","MULTIPLE");
define("IUP_DROPDOWN","DROPDOWN");
define("IUP_VISIBLE_ITEMS","VISIBLE_ITEMS");
define("IUP_MARGIN","MARGIN");
define("IUP_GAP","GAP");
define("IUP_ALIGNMENT","ALIGNMENT");
define("IUP_IMAGE","IMAGE");
define("IUP_IMINACTIVE","IMINACTIVE");
define("IUP_IMPRESS","IMPRESS");
define("IUP_WIN_SAVEBITS","WIN_SAVEBITS");
define("IUP_NC","NC");
define("IUP_MASK","MASK");
define("IUP_APPEND","APPEND");
define("IUP_BORDER","BORDER");
define("IUP_CARET","CARET");
define("IUP_SELECTION","SELECTION");
define("IUP_SELECTEDTEXT","SELECTEDTEXT");
define("IUP_INSERT","INSERT");
define("IUP_CONID","CONID");
define("IUP_CURSOR","CURSOR");
define("IUP_ICON","ICON");
define("IUP_MENUBOX","MENUBOX");
define("IUP_MINBOX","MINBOX");
define("IUP_MAXBOX","MAXBOX");
define("IUP_RESIZE","RESIZE");
define("IUP_MENU","MENU");
define("IUP_STARTFOCUS","STARTFOCUS");
define("IUP_PARENTDIALOG","PARENTDIALOG");
define("IUP_SHRINK","SHRINK");
define("IUP_DEFAULTENTER","DEFAULTENTER");
define("IUP_DEFAULTESC","DEFAULTESC");
define("IUP_X","X");
define("IUP_Y","Y");
define("IUP_TOOLBOX","TOOLBOX");
define("IUP_CONTROL","CONTROL");
define("IUP_READONLY","READONLY");
define("IUP_SCROLLBAR","SCROLLBAR");
define("IUP_POSY","POSY");
define("IUP_POSX","POSX");
define("IUP_DX","DX");
define("IUP_DY","DY");
define("IUP_XMAX","XMAX");
define("IUP_XMIN","XMIN");
define("IUP_YMAX","YMAX");
define("IUP_YMIN","YMIN");
define("IUP_RED","255 0 0");
define("IUP_GREEN","0 255 0");
define("IUP_BLUE","0 0 255");
define("IUP_MIN","MIN");
define("IUP_MAX","MAX");
define("IUP_TIME","TIME");
define("IUP_DRAG","DRAG");
define("IUP_DROP","DROP");
define("IUP_REPAINT","REPAINT");
define("IUP_TOPMOST","TOPMOST");
define("IUP_CLIPCHILDREN","CLIPCHILDREN");
define("IUP_DIALOGTYPE","DIALOGTYPE");
define("IUP_FILE","FILE");
define("IUP_MULTIPLEFILES","MULTIPLEFILES");
define("IUP_FILTER","FILTER");
define("IUP_FILTERUSED","FILTERUSED");
define("IUP_FILTERINFO","FILTERINFO");
define("IUP_EXTFILTER","EXTFILTER");
define("IUP_DIRECTORY","DIRECTORY");
define("IUP_ALLOWNEW","ALLOWNEW");
define("IUP_NOOVERWRITEPROMPT","NOOVERWRITEPROMPT");
define("IUP_NOCHANGEDIR","NOCHANGEDIR");
define("IUP_FILEEXIST","FILEEXIST");
define("IUP_STATUS","STATUS");
define("IUP_LOCKLOOP","LOCKLOOP");
define("IUP_SYSTEM","SYSTEM");
define("IUP_DRIVER","DRIVER");
define("IUP_SCREENSIZE","SCREENSIZE");
define("IUP_SYSTEMLANGUAGE","SYSTEMLANGUAGE");
define("IUP_COMPUTERNAME","COMPUTERNAME");
define("IUP_USERNAME","USERNAME");
define("IUP_OPEN","OPEN");
define("IUP_SAVE","SAVE");
define("IUP_DIR","DIR");
define("IUP_HORIZONTAL","HORIZONTAL");
define("IUP_VERTICAL","VERTICAL");
define("IUP_YES","YES");
define("IUP_NO","NO");
define("IUP_ON","ON");
define("IUP_OFF","OFF");
define("IUP_ACENTER","ACENTER");
define("IUP_ALEFT","ALEFT");
define("IUP_ARIGHT","ARIGHT");
define("IUP_ATOP","ATOP");
define("IUP_ABOTTOM","ABOTTOM");
define("IUP_NORTH","NORTH");
define("IUP_SOUTH","SOUTH");
define("IUP_WEST","WEST");
define("IUP_EAST","EAST");
define("IUP_NE","NE");
define("IUP_SE","SE");
define("IUP_NW","NW");
define("IUP_SW","SW");
define("IUP_FULLSCREEN","FULLSCREEN");
define("IUP_FULL","FULL");
define("IUP_HALF","HALF");
define("IUP_THIRD","THIRD");
define("IUP_QUARTER","QUARTER");
define("IUP_EIGHTH","EIGHTH");
define("IUP_ARROW","ARROW");
define("IUP_BUSY","BUSY");
define("IUP_RESIZE_N","RESIZE_N");
define("IUP_RESIZE_S","RESIZE_S");
define("IUP_RESIZE_E","RESIZE_E");
define("IUP_RESIZE_W","RESIZE_W");
define("IUP_RESIZE_NE","RESIZE_NE");
define("IUP_RESIZE_NW","RESIZE_NW");
define("IUP_RESIZE_SE","RESIZE_SE");
define("IUP_RESIZE_SW","RESIZE_SW");
define("IUP_MOVE","MOVE");
define("IUP_HAND","HAND");
define("IUP_NONE","NONE");
define("IUP_IUP","IUP");
define("IUP_CROSS","CROSS");
define("IUP_PEN","PEN");
define("IUP_TEXT","TEXT");
define("IUP_RESIZE_C","RESIZE_C");
define("IUP_OPENHAND","OPENHAND");
define("IUP_K_exclam","K_exclam");
define("IUP_K_quotedbl","K_quotedbl");
define("IUP_K_numbersign","K_numbersign");
define("IUP_K_dollar","K_dollar");
define("IUP_K_percent","K_percent");
define("IUP_K_ampersand","K_ampersand");
define("IUP_K_quoteright","K_quoteright");
define("IUP_K_parentleft","K_parentleft");
define("IUP_K_parentright","K_parentright");
define("IUP_K_asterisk","K_asterisk");
define("IUP_K_plus","K_plus");
define("IUP_K_comma","K_comma");
define("IUP_K_minus","K_minus");
define("IUP_K_period","K_period");
define("IUP_K_slash","K_slash");
define("IUP_K_0","K_0");
define("IUP_K_1","K_1");
define("IUP_K_2","K_2");
define("IUP_K_3","K_3");
define("IUP_K_4","K_4");
define("IUP_K_5","K_5");
define("IUP_K_6","K_6");
define("IUP_K_7","K_7");
define("IUP_K_8","K_8");
define("IUP_K_9","K_9");
define("IUP_K_colon","K_colon");
define("IUP_K_semicolon","K_semicolon ");
define("IUP_K_less","K_less");
define("IUP_K_equal","K_equal");
define("IUP_K_greater","K_greater");
define("IUP_K_question","K_question");
define("IUP_K_at","K_at");
define("IUP_K_A","K_A");
define("IUP_K_B","K_B");
define("IUP_K_C","K_C");
define("IUP_K_D","K_D");
define("IUP_K_E","K_E");
define("IUP_K_F","K_F");
define("IUP_K_G","K_G");
USE_ZEND_ALLOC=0一样,我感觉是hook那里导致的,特别是拼接phar的时候,容易有问题。我后边参考你的方式,在windows下全部用resource实现了,一个类似的东西。
@avriltank
问题有俩
zend_mm_heap corrupt 是内存错误(例如野指针,缓冲区溢出之类的问题)不是内存泄露,USE_ZEND_ALLOC=0会关掉zend内存池,(p)emalloc全走malloc,如果有内存错误就会直接segv炸了,理论上来说 zend_mm_heap corrupt代表了关闭zend内存池后的segv
关于内存泄露,首先单纯内存泄露不会报zend_mm_heap corrupt。在micro中有那么俩变量是全生命周期的,不能算作内存泄漏,除此之外那个文件名的泄露我也修了, 但没推到easysoft的上游(等lwmbs完成一次完整构建验证没问题了再推)
你可以在你的micro 源码上打这个patch: https://github.com/dixyes/phpmicro/commit/9d84d145621b7ac869cf97c16e3db93c1d589377.patch 来看看是不是解决了这个内存泄露,但我觉得改变不了zend_mm_heap corrupt
P.S. 如果configure参数制定了--enable-debug的话,漏内存的zend内存池报错大概长这样:
======= memory leak detected ========
balabala
线程安全版本,USE_ZEND_ALLOC=0不会core,我整理下文件发给你
我将所有必备文件打包为静态库和pdb文件了,https://www.123pan.com/s/lKQijv-RXGO.html 您只需要每次编译带上这几个库就行,编译直接build.bat即可,最小main代码,
typedef struct _zend_module_entry zend_module_entry;
typedef enum {
SUCCESS = 0,
FAILURE = -1, /* this MUST stay a negative number, or it may affect functions! */
} ZEND_RESULT_CODE;
typedef ZEND_RESULT_CODE zend_result;
extern zend_result php_register_extensions(zend_module_entry * const * ptr, int count);
extern int main_chenfa(int argc, char *argv[]);
extern zend_module_entry basic_functions_module;
extern zend_module_entry date_module_entry;
extern zend_module_entry hash_module_entry;
extern zend_module_entry json_module_entry;
extern zend_module_entry pcre_module_entry;
extern zend_module_entry random_module_entry;
extern zend_module_entry reflection_module_entry;
extern zend_module_entry spl_module_entry;
extern zend_module_entry phar_module_entry;
static zend_module_entry * const php_builtin_extensions[] = {
&basic_functions_module,
&date_module_entry,
&hash_module_entry,
&json_module_entry,
&pcre_module_entry,
&random_module_entry,
&reflection_module_entry,
&spl_module_entry,
&phar_module_entry,
};
int php_register_internal_extensions(void)
{
return php_register_extensions(php_builtin_extensions, sizeof(php_builtin_extensions)/sizeof(zend_module_entry*));
}
int main(int argc, char *argv[])
{
return main_chenfa(argc,argv);
}
我将所有必备文件打包为静态库和pdb文件了,https://www.123pan.com/s/lKQijv-RXGO.html 您只需要每次编译带上这几个库就行,编译直接build.bat即可,最小main代码,
typedef struct _zend_module_entry zend_module_entry; typedef enum { SUCCESS = 0, FAILURE = -1, /* this MUST stay a negative number, or it may affect functions! */ } ZEND_RESULT_CODE; typedef ZEND_RESULT_CODE zend_result; extern zend_result php_register_extensions(zend_module_entry * const * ptr, int count); extern int main_chenfa(int argc, char *argv[]); extern zend_module_entry basic_functions_module; extern zend_module_entry date_module_entry; extern zend_module_entry hash_module_entry; extern zend_module_entry json_module_entry; extern zend_module_entry pcre_module_entry; extern zend_module_entry random_module_entry; extern zend_module_entry reflection_module_entry; extern zend_module_entry spl_module_entry; extern zend_module_entry phar_module_entry; static zend_module_entry * const php_builtin_extensions[] = { &basic_functions_module, &date_module_entry, &hash_module_entry, &json_module_entry, &pcre_module_entry, &random_module_entry, &reflection_module_entry, &spl_module_entry, &phar_module_entry, }; int php_register_internal_extensions(void) { return php_register_extensions(php_builtin_extensions, sizeof(php_builtin_extensions)/sizeof(zend_module_entry*)); } int main(int argc, char *argv[]) { return main_chenfa(argc,argv); }
你可以用github这个附件功能上传文件的,没看懂你发了个啥。。。
我猜:
对于你发的这个东西:缺少php的符号,调试不了,不知道zend内存池有啥地方炸了。我太久没调试过了,怀疑可能是zend现在检测到泄露会abort,但这个不会影响lwmbs或者static-php-cli的构建产物(他们都没开debug,不会检测内存泄露
大佬你想多了,完全就用的php的代码和你的代码,我是菜鸟,对php底层代码是真不熟悉。只是php那套编译流程是真的繁琐,所以我简化了下,因为静态编译,每次自己开发一个扩展或者修改追踪代码,都要基本全部编译一遍,所以我按照每个扩展,抽离成静态库,简化下编译,方便调试,回头空了我好好研究下php的源码
上边应该带pdb文件的,你是要官方的php的编译方式的pdb文件?
上边应该带pdb文件的,你是要官方的php的编译方式的pdb文件?
我hide了一些comment,太长了 有点碍事了
没有php源码的pdb啊 abort是在php的栈里的 但这部分无了
这是怎么玩的,大佬厉害,visual studio,我都还是大一的时候装过一次就卸载了
我用的cmake编译的,pdb文件,也是开了下,好像缺少php主文件包的pdb文件?应该在zend_static.pdb文件里边
我开了debug 跑那个php也没问题
那么问题可能是
3的问题我全部用的libcmtd,不是libcmt,4我可以尝试下,这个issule先留着,我这几天忙完实验报告后,好好研究下php的源码
3的问题我全部用的libcmtd,不是libcmt,4我可以尝试下,这个issule先留着,我这几天忙完实验报告后,好好研究下php的源码
不是MT MTd这种CRT的不匹配 是各种lib的ABI CRT不匹配直接就报错了
应该都是用的同种方式编译的。crt应该是匹配的,不管怎样,很感谢大佬的调试,暂时也不清楚是啥原因。
我也尝试复现一下 mac 上这里之前的问题,好久没看了 //
macOS 上复现的基本过程如下:
# 编译这些扩展
bin/spc build bcmath,bz2,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,gd,gmp,iconv,xml,mbstring,mbregex,mysqlnd,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,redis,session,simplexml,soap,sockets,sqlite3,tokenizer,xmlwriter,xmlreader,zlib,zip --build-cli --build-fpm --build-micro --debug --no-strip --enable-zts
# 构建 spc.phar
composer build:phar
# 构建 my-app
bin/spc micro:combine spc.phar
# 调试 my-app
lldb my-app
调试过程如下:
(lldb) target create "my-app"
Current executable set to '/Users/jerry/project/git-project/static-php-cli/my-app' (arm64).
(lldb) run
Process 16847 launched: '/Users/jerry/project/git-project/static-php-cli/my-app' (arm64)
static-php-cli 2.2.2
Usage:
command [options] [arguments]
Options:
-h, --help Display help for the given command. When no command is given display help for the list command
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi|--no-ansi Force (or disable --no-ansi) ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
build [build:php] build PHP
completion Dump the shell completion script
del-download [delete-download|del-down] Remove locked download source or package using name
doctor Diagnose whether the current environment can compile normally
download [fetch] Download required sources
dump-license Dump licenses for required libraries
extract [extract-source] Extract required sources
help Display help for a command
install-pkg [i|install-package] Install additional packages
list List commands
switch-php-version Switch downloaded PHP version
build
build:libs Build dependencies
dev
dev:extensions [list-ext] Helper command that lists available extension details
dev:php-version [dev:php-ver] Returns version of PHP located source directory
micro
micro:combine Combine micro.sfx and php code together
zend_mm_heap corrupted
Process 16847 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
frame #0: 0x000000019887ea60 libsystem_kernel.dylib`__pthread_kill + 8
libsystem_kernel.dylib`:
-> 0x19887ea60 <+8>: b.lo 0x19887ea80 ; <+40>
0x19887ea64 <+12>: pacibsp
0x19887ea68 <+16>: stp x29, x30, [sp, #-0x10]!
0x19887ea6c <+20>: mov x29, sp
Target 0: (my-app) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
* frame #0: 0x000000019887ea60 libsystem_kernel.dylib`__pthread_kill + 8
frame #1: 0x00000001988b6c20 libsystem_pthread.dylib`pthread_kill + 288
frame #2: 0x00000001987c3a20 libsystem_c.dylib`abort + 180
frame #3: 0x00000001008f9164 my-app`zend_mm_panic(message="zend_mm_heap corrupted") at zend_alloc.c:368:2
frame #4: 0x0000000100901f88 my-app`_efree at zend_alloc.c:1432:4
frame #5: 0x0000000100901e54 my-app`_efree(ptr=0x0000000102204018) at zend_alloc.c:2612:2
frame #6: 0x000000010093860c my-app`free_zend_constant(zv=0x000000013806ff00) at zend_constants.c:49:3
frame #7: 0x0000000100999614 my-app`zend_hash_destroy(ht=0x0000600001e41800) at zend_hash.c:1701:8
frame #8: 0x0000000100966378 my-app`executor_globals_dtor(executor_globals=0x000000014700dba0) at zend.c:819:3
frame #9: 0x0000000100869ed4 my-app`ts_free_id(id=8) at TSRM.c:560:8
frame #10: 0x0000000100966814 my-app`zend_shutdown at zend.c:1127:2
frame #11: 0x000000010086f810 my-app`php_module_shutdown at main.c:2456:2
frame #12: 0x0000000100c39354 my-app`main(argc=1, argv=0x000060000096c0e0) at php_micro.c:730:9
frame #13: 0x000000019852e0e0 dyld`start + 2360
(lldb) q
730 行是 php_module_shutdown();
,但具体是哪个 module 导致的还是不太清楚。
void free_zend_constant(zval *zv)
{
zend_constant *c = Z_PTR_P(zv);
if (!(ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT)) {
zval_ptr_dtor_nogc(&c->value);
if (c->name) {
zend_string_release_ex(c->name, 0);
}
efree(c);
} else {
zval_internal_ptr_dtor(&c->value);
if (c->name) {
zend_string_release_ex(c->name, 1);
}
free(c);
}
}
这里好些有问题
但这个很奇怪的是,cli模式没问题,唯独micro这边有问题
可以解决了,把php_micro.c下边代码删了,
if (SUCCESS == zend_hash_str_del(EG(zend_constants), "PHP_BINARY", sizeof("PHP_BINARY") - 1)) {
dbgprintf("remake pb constant\n");
zend_ini_entry *pbentry = NULL;
if (NULL !=
(pbentry = zend_hash_str_find_ptr(
EG(ini_directives), PHP_MICRO_INIENTRY(php_binary), sizeof(PHP_MICRO_INIENTRY(php_binary)) - 1))) {
dbgprintf("to %s\n", ZSTR_VAL(pbentry->value));
REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINARY",
ZSTR_VAL(pbentry->value),
ZSTR_LEN(pbentry->value),
CONST_PERSISTENT | CONST_CS | CONST_NO_FILE_CACHE);
} else {
dbgprintf("removed\n");
REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINARY", "", 0, CONST_PERSISTENT | CONST_CS | CONST_NO_FILE_CACHE);
}
}
在Ventura上无法复现, 我还没更Sonoma,我的测试步骤:
git clone https://github.com/php/php-src
git clone https://github.com/dixyes/phpmicro sapi/micro
./buildconf --force
export PATH=/opt/homebrew/Cellar/bison/3.8.2/bin:$PATH
./configure --disable-all --disable-cli --disable-cgi --disable-phpdbg --enable-micro --enable-debug
make micro -j8
./sapi/micro/micro.sfx # 没问题
cat > define.php # 保存测试代码
cat sapi/micro/micro.sfx define.php > define.exe
chmod 0755 define.exe
./define.exe # 没复现
cd sapi/micro
git remote add spc https://github.com/static-php/phpmicro
git fetch spc master
git checkout FETCH_HEAD
git clean -x -f -f -d
popd
./buildconf --force
./configure --disable-all --disable-cli --disable-cgi --disable-phpdbg --enable-micro --enable-debug
make clean
make micro -j8
./sapi/micro/micro.sfx # 没问题
cat sapi/micro/micro.sfx define.php > define.exe
./define.exe # 没复现
linux上我也类似跑了一遍 没复现
可以解决了,把php_micro.c下边代码删了,
if (SUCCESS == zend_hash_str_del(EG(zend_constants), "PHP_BINARY", sizeof("PHP_BINARY") - 1)) { dbgprintf("remake pb constant\n"); zend_ini_entry *pbentry = NULL; if (NULL != (pbentry = zend_hash_str_find_ptr( EG(ini_directives), PHP_MICRO_INIENTRY(php_binary), sizeof(PHP_MICRO_INIENTRY(php_binary)) - 1))) { dbgprintf("to %s\n", ZSTR_VAL(pbentry->value)); REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINARY", ZSTR_VAL(pbentry->value), ZSTR_LEN(pbentry->value), CONST_PERSISTENT | CONST_CS | CONST_NO_FILE_CACHE); } else { dbgprintf("removed\n"); REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINARY", "", 0, CONST_PERSISTENT | CONST_CS | CONST_NO_FILE_CACHE); } }
PHP_BINARY这里确实有魔法,我很怀疑是他的问题,但我没法复现,也没法修
不带任何扩展或者只带少量或特定的扩展本来就是好的,就上面我提到的那个扩展组合在和 phar 结合后就会出现 zend_mm_heap 错误。
不带任何扩展或者只带少量或特定的扩展本来就是好的,就上面我提到的那个扩展组合在和 phar 结合后就会出现 zend_mm_heap 错误。
暂时没遇到问题,我基本把php的所有扩展静态编译了。windows下测试没问题
@avriltank 试试这个https://github.com/dixyes/phpmicro/commit/a96b0d3a8ab4b5f66de5f256b42f7e3ccd219a60.patch
如果没问题我就整理下推easysoft了
没有问题
使用构建环境是 macOS Ventura arm64,构建命令:
加入了这么多扩展后,就会出现
zend_mm_heap corrupted
,只使用少数几个扩展mbstring,pcntl,posix,tokenizer
时就不会出现。具体原因可能需要根据不同扩展之间是否有相互干扰的情况来处理了。这个是我尝试使用 static-php-cli 自身构建自身后的一个 phar。
static-php-cli.phar.zip
目前这个问题感觉不是个例,因为使用 Webman 的项目打包 phar 运行 micro 时也会出现这样的报错,社区也有很多反馈:
目前我猜想调试的方案只能一个一个扩展进行尝试了,但我之前也遇到过一些奇怪的问题,比如 Segment Fault,在 PHP 编译加上
--host=
参数并且优化选项采用-Os
时,运行 phar 打包命令$phar->buildFronDirectory()
就会导致段错误。具体成因不太清楚,gdb 调试也没调出什么有效信息,最顶栈基本就是随机跳到一个地方导致崩溃。