Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

某些情况构建的 micro.sfx 容易出现 zend_mm_heap corrupted #11

Closed
crazywhalecc opened this issue May 1, 2023 · 33 comments
Closed

Comments

@crazywhalecc
Copy link
Contributor

crazywhalecc commented May 1, 2023

使用构建环境是 macOS Ventura arm64,构建命令:

./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes CFLAGS='--target=arm64-apple-darwin -Werror=unknown-warning-option' --disable-all --disable-cgi --disable-phpdbg --enable-cli --enable-fpm --enable-micro  --enable-bcmath --with-bz2="/Users/jerry/project/git-project/static-php-cli/buildroot" --enable-calendar --enable-ctype --with-curl --enable-dom --with-libxml="/Users/jerry/project/git-project/static-php-cli/buildroot" --enable-exif --enable-fileinfo --enable-filter --enable-ftp --with-zlib --enable-gd --with-gmp="/Users/jerry/project/git-project/static-php-cli/buildroot" --with-iconv="/Users/jerry/project/git-project/static-php-cli/buildroot" --enable-xml --with-libxml="/Users/jerry/project/git-project/static-php-cli/buildroot" --enable-mbstring --enable-mbregex --enable-mysqlnd --with-openssl --enable-pcntl --enable-pdo --with-pdo-mysql --with-sqlite3="/Users/jerry/project/git-project/static-php-cli/buildroot" --with-pdo-sqlite --enable-phar --enable-posix --enable-redis --disable-redis-session --enable-session --enable-simplexml --with-libxml="/Users/jerry/project/git-project/static-php-cli/buildroot" --enable-soap --with-libxml="/Users/jerry/project/git-project/static-php-cli/buildroot" --enable-sockets --enable-tokenizer --enable-xmlwriter --with-libxml="/Users/jerry/project/git-project/static-php-cli/buildroot" --enable-xmlreader --with-libxml="/Users/jerry/project/git-project/static-php-cli/buildroot" --with-zip="/Users/jerry/project/git-project/static-php-cli/buildroot" PKG_CONFIG_PATH="/Users/jerry/project/git-project/static-php-cli/buildroot/lib/pkgconfig/" CC='clang' CXX='clang++' CFLAGS='--target=arm64-apple-darwin -Wimplicit-function-declaration'

make -j8 EXTRA_CFLAGS="-g -Os -fno-ident" EXTRA_LIBS="-framework CoreFoundation -framework SystemConfiguration /Users/jerry/project/git-project/static-php-cli/buildroot/lib/libzip.a /Users/jerry/project/git-project/static-php-cli/buildroot/lib/libsqlite3.a /Users/jerry/project/git-project/static-php-cli/buildroot/lib/libonig.a /Users/jerry/project/git-project/static-php-cli/buildroot/lib/libgmp.a /Users/jerry/project/git-project/static-php-cli/buildroot/lib/libpng16.a /Users/jerry/project/git-project/static-php-cli/buildroot/lib/libxml2.a /Users/jerry/project/git-project/static-php-cli/buildroot/lib/libiconv.a /Users/jerry/project/git-project/static-php-cli/buildroot/lib/libcharset.a /Users/jerry/project/git-project/static-php-cli/buildroot/lib/libcurl.a /Users/jerry/project/git-project/static-php-cli/buildroot/lib/libssl.a /Users/jerry/project/git-project/static-php-cli/buildroot/lib/libcrypto.a /Users/jerry/project/git-project/static-php-cli/buildroot/lib/libz.a /Users/jerry/project/git-project/static-php-cli/buildroot/lib/libbz2.a -liconv -lresolv" STRIP="dsymutil -f " micro

加入了这么多扩展后,就会出现 zend_mm_heap corrupted,只使用少数几个扩展 mbstring,pcntl,posix,tokenizer 时就不会出现。

./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes CFLAGS='--target=arm64-apple-darwin -Werror=unknown-warning-option' --disable-all --disable-cgi --disable-phpdbg --enable-cli --enable-fpm --enable-micro  --enable-mbstring --disable-mbregex --enable-pcntl --enable-posix --enable-tokenizer PKG_CONFIG_PATH="/Users/jerry/project/git-project/static-php-cli/buildroot/lib/pkgconfig/" CC='clang' CXX='clang++' CFLAGS='--target=arm64-apple-darwin -Wimplicit-function-declaration'

 make -j8 EXTRA_CFLAGS="-g -Os -fno-ident" EXTRA_LIBS=" /Users/jerry/project/git-project/static-php-cli/buildroot/lib/libonig.a -lresolv" STRIP="dsymutil -f " micro

具体原因可能需要根据不同扩展之间是否有相互干扰的情况来处理了。这个是我尝试使用 static-php-cli 自身构建自身后的一个 phar。

static-php-cli.phar.zip

目前这个问题感觉不是个例,因为使用 Webman 的项目打包 phar 运行 micro 时也会出现这样的报错,社区也有很多反馈:

目前我猜想调试的方案只能一个一个扩展进行尝试了,但我之前也遇到过一些奇怪的问题,比如 Segment Fault,在 PHP 编译加上 --host= 参数并且优化选项采用 -Os 时,运行 phar 打包命令 $phar->buildFronDirectory() 就会导致段错误。具体成因不太清楚,gdb 调试也没调出什么有效信息,最顶栈基本就是随机跳到一个地方导致崩溃。

@crazywhalecc crazywhalecc changed the title 貌似 某些情况构建的 micro.sfx 容易出现 zend_mm_heap corrupted May 1, 2023
@dixyes
Copy link
Collaborator

dixyes commented Jul 31, 2023

才看到。。。
micro几乎没有动zend内存池的东西,目测是php本身的bug,或者micro的生命周期有些问题
我也没找到最小可复现demo

至于-Os的segv多半是编译器bug,如果能制作最小demo(c代码),可以向gcc/clang反馈问题

对于micro的调试 可以把debug打开,strip关掉,打开asan(我一般直接改makefile),然后有符号的情况下进行调试,Linux上比较方便,mac/windows比较痛苦(mac缺少调试工具,还有些莫名其妙的完整性检查策略,windows下debug构建比较麻烦)

@avriltank
Copy link

avriltank commented May 22, 2024

最小复现demo,参见这个issue(crazywhalecc/static-php-cli#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");

@dixyes
Copy link
Collaborator

dixyes commented May 29, 2024

内存泄漏应该不会core啊(sfxname是全生命周期的 也算不上泄露)

我猜事php改什么东西了,等我收拾完这波重构看一眼咋回事

@dixyes
Copy link
Collaborator

dixyes commented May 29, 2024

最小复现demo,参见这个issue(crazywhalecc/static-php-cli#460)

<?php
define("K_SP"," ");
...

内存泄露快速修了下: dixyes@9d84d14 ,但应该和它没关系,zend内存池寄了才会报zend_mm_heap corrupted

Windows 11 VS2022 php8.3.7

无法复现

最脑阔疼的地方就是 没有demo -> 有了demo不复现

能的话把你的带调试符号的二进制发一下(没有敏感信息的话直接issue附件就行) 我来看看咋回事

@dixyes
Copy link
Collaborator

dixyes commented May 29, 2024

@avriltank 你可以试试环境变量USE_ZEND_ALLOC=0 然后跑一下程序,看他core不

@avriltank
Copy link

USE_ZEND_ALLOC=0一样,我感觉是hook那里导致的,特别是拼接phar的时候,容易有问题。我后边参考你的方式,在windows下全部用resource实现了,一个类似的东西。

@avriltank

This comment was marked as off-topic.

@avriltank
Copy link

其实micro的实现是最科学的,只需要拼接,偏移下就可以。上边这种实现方式,需要释放出,资源文件中的phar文件,如果是单php文件,可以直接zend_execute,但是phar,我看php代码是用的phar_open_from_filename,必须要从本地文件一个存在的文件包里边去获取转换成phar结构体,其实修改phar源码也可以实现(直接从资源文件流转换到php stream),不释放到本地,只是太麻烦了

@avriltank

This comment was marked as duplicate.

@dixyes
Copy link
Collaborator

dixyes commented May 30, 2024

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

@avriltank
Copy link

线程安全版本,USE_ZEND_ALLOC=0不会core,我整理下文件发给你

@avriltank
Copy link

avriltank commented May 30, 2024

我将所有必备文件打包为静态库和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);
}

@dixyes
Copy link
Collaborator

dixyes commented May 30, 2024

我将所有必备文件打包为静态库和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这个附件功能上传文件的,没看懂你发了个啥。。。

我猜:

  1. 如果你自己实现了个micro类似的功能的sfx或者单二进制的php解释器啥的,这个就和micro无关了,我不介意帮你调下zend内存池问题,但我希望你把它的源码以符合PHP许可证的方式开源到gh/gl/gitee等平台
  2. 如果你需要上面描述的二进制,又不希望开源自己的C源码,你可以使用PHP的embed SAPI,static-php项目有编译这个SAPI的功能。这种情况你应该会用会写php,不需要我来调试,这也跟micro没关系了
  3. 如果你需要帮助调试你的micro二进制,不要对他做太大的修改或者修改了什么也描述一下。这种情况只需要对应的micro.sfx二进制和pdb即可,不需要未链接的.lib。vs只需要这个pdb文件就能调

对于你发的这个东西:缺少php的符号,调试不了,不知道zend内存池有啥地方炸了。我太久没调试过了,怀疑可能是zend现在检测到泄露会abort,但这个不会影响lwmbs或者static-php-cli的构建产物(他们都没开debug,不会检测内存泄露

@avriltank
Copy link

大佬你想多了,完全就用的php的代码和你的代码,我是菜鸟,对php底层代码是真不熟悉。只是php那套编译流程是真的繁琐,所以我简化了下,因为静态编译,每次自己开发一个扩展或者修改追踪代码,都要基本全部编译一遍,所以我按照每个扩展,抽离成静态库,简化下编译,方便调试,回头空了我好好研究下php的源码

@avriltank
Copy link

上边应该带pdb文件的,你是要官方的php的编译方式的pdb文件?

@dixyes
Copy link
Collaborator

dixyes commented May 30, 2024

上边应该带pdb文件的,你是要官方的php的编译方式的pdb文件?

我hide了一些comment,太长了 有点碍事了

没有php源码的pdb啊 abort是在php的栈里的 但这部分无了

屏幕截图 2024-05-30 164153

@avriltank
Copy link

这是怎么玩的,大佬厉害,visual studio,我都还是大一的时候装过一次就卸载了

@avriltank
Copy link

我用的cmake编译的,pdb文件,也是开了下,好像缺少php主文件包的pdb文件?应该在zend_static.pdb文件里边

@dixyes
Copy link
Collaborator

dixyes commented May 30, 2024

我开了debug 跑那个php也没问题

那么问题可能是

  1. lwmbs有魔法 -> 换lwmbs的二进制试一试
  2. 我的大refactor不知不觉修了这个问题 -> rebase下你的micro到我的fork https://github.com/dixyes/phpmicro
  3. 你的构建系统哪里写歪了,导致了两次构建的lib ABI不匹配 -> 检查是不是用了不同版本的php头/lib 然后用PHP官方构建系统跑一下
  4. spc有魔法 -> 用PHP官方构建系统跑一下

@avriltank
Copy link

3的问题我全部用的libcmtd,不是libcmt,4我可以尝试下,这个issule先留着,我这几天忙完实验报告后,好好研究下php的源码

@dixyes
Copy link
Collaborator

dixyes commented May 30, 2024

3的问题我全部用的libcmtd,不是libcmt,4我可以尝试下,这个issule先留着,我这几天忙完实验报告后,好好研究下php的源码

不是MT MTd这种CRT的不匹配 是各种lib的ABI CRT不匹配直接就报错了

@avriltank
Copy link

应该都是用的同种方式编译的。crt应该是匹配的,不管怎样,很感谢大佬的调试,暂时也不清楚是啥原因。

@crazywhalecc
Copy link
Contributor Author

我也尝试复现一下 mac 上这里之前的问题,好久没看了 //

@crazywhalecc
Copy link
Contributor Author

crazywhalecc commented May 30, 2024

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 导致的还是不太清楚。

@avriltank
Copy link

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);
	}
}

这里好些有问题

@avriltank
Copy link

但这个很奇怪的是,cli模式没问题,唯独micro这边有问题

@avriltank
Copy link

可以解决了,把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);
            }
        }

@dixyes
Copy link
Collaborator

dixyes commented May 30, 2024

在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上我也类似跑了一遍 没复现

@dixyes
Copy link
Collaborator

dixyes commented May 30, 2024

可以解决了,把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这里确实有魔法,我很怀疑是他的问题,但我没法复现,也没法修

@crazywhalecc
Copy link
Contributor Author

不带任何扩展或者只带少量或特定的扩展本来就是好的,就上面我提到的那个扩展组合在和 phar 结合后就会出现 zend_mm_heap 错误。

@avriltank
Copy link

不带任何扩展或者只带少量或特定的扩展本来就是好的,就上面我提到的那个扩展组合在和 phar 结合后就会出现 zend_mm_heap 错误。

暂时没遇到问题,我基本把php的所有扩展静态编译了。windows下测试没问题

@dixyes
Copy link
Collaborator

dixyes commented May 31, 2024

@avriltank
Copy link

没有问题

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants