How to solve apache crash caused by using preg_match_all in win2003

Source: Internet
Author: User
Tags apache error log preg regular expression win32

The platform is windows server 2003 (32-bit system) + Apache/2.2.9 (Win32) + PHP/5.2.17. The regular expression preg_match_all (for example, preg_match_all ("/ni (.*?) Wo/", $ html, $ matches);) for analysis and matching of a long string $ html (more than 0.1 million bytes, usually used to analyze the source code of the collected webpage ), the Apache server will crash and automatically restart.

The following error message is displayed in the Apache error log:

[Thu Apr 11 18:31:31 2013] [notice] Parent: child process exited with status 128 -- Restarting.
[Thu Apr 11 18:31:31 2013] [notice] Apache/2.2.9 (Win32) PHP/5.2.17 configured -- resuming normal operations
[Thu Apr 11 18:31:31 2013] [notice] Server built: Jun 13 2008 04:04:59
[Thu Apr 11 18:31:31 2013] [notice] Parent: Created child process 2964
[Thu Apr 11 18:31:31 2013] [notice] Disabled use of AcceptEx () WinSock2 API
[Thu Apr 11 18:31:31 2013] [notice] Child 2964: Child process is running
[Thu Apr 11 18:31:31 2013] [notice] Child 2964: Acquired the start mutex.
[Thu Apr 11 18:31:31 2013] [notice] Child 2964: Starting 350 worker threads.
[Thu Apr 11 18:31:31 2013] [notice] Child 2964: Listening on port 80.

After reading Apache official documents and Forum materials, we found that when we use regular expressions preg_match_all or preg_match to analyze long strings on the win platform, the cause of apache crash and restart is that the thread stack space allocated by default in windows is too small. Win32 is only KB by default, while the default value in linux is 8 MB, which is why the same program works normally on the linux platform, but not on the Windows platform.

According to the official instructions of PCRE library: the size of pcre. recursion_limit corresponding to the 256 KB stack space should not exceed 524.
Here is a table of safe values of pcre. recursion_limit for a variety of executable stack sizes:
The following is a recommended security value corresponding to Stacksize and pcre. recursion_limit. If this value is exceeded, Stack Overflow is very likely. apache crash:
Stacksize pcre. recursion_limit
64 MB 134217
32 MB 67108
16 MB 33554
8 MB 16777
4 MB 8388
2 MB 4194
1 MB 2097
512 KB 1048
256 KB 524

If you have not adjusted the stack size, you must add the following at the beginning of the PHP page using regular expressions:

<? Php
Ini_set ("pcre. recursion_limit", "524"); // PHP default is 100,000.
?>

You can use the following code to view specific errors:

$ ResultsArray = preg_match_all ("/table .*? <A>/isU ", $ html, $ contents );
If ($ resultsArray === 0 ){
Echo get_pcre_err ();
}
Function get_pcre_err (){
$ Pcre_err = preg_last_error (); // PHP 5.2 and above.
If ($ pcre_err === PREG_NO_ERROR ){
$ Msg = 'successful non-match .';
} Else {
// Preg_match error!
Switch ($ pcre_err ){
Case PREG_INTERNAL_ERROR:
$ Msg = 'preg _ INTERNAL_ERROR ';
Break;
Case PREG_BACKTRACK_LIMIT_ERROR:
$ Msg = 'preg _ BACKTRACK_LIMIT_ERROR ';
Break;
Case PREG_RECURSION_LIMIT_ERROR:
$ Msg = 'preg _ RECURSION_LIMIT_ERROR ';
Break;
Case PREG_BAD_UTF8_ERROR:
$ Msg = 'preg _ BAD_UTF8_ERROR ';
Break;
Case PREG_BAD_UTF8_OFFSET_ERROR:
$ Msg = 'preg _ BAD_UTF8_OFFSET_ERROR ';
Break;
Default:
$ Msg = 'uncognized PREG error ';
Break;
            }
        }
Return ($ msg );
}

Description of the regular expression modifier isU:

I: in-casesensitive, which is case insensitive.
S: PCRE_DOTALL, indicating that the DOT can match the line break.
U: PCRE_UNGREEDY, non-greedy, equivalent to. *? In perl/python .*?, During the matching process, if A. * regular expression matches, it is executed immediately, instead of waiting for. * to search all characters and then return them one by one.

When using regular expressions, we should try to avoid recursive calls, which may easily cause stack overflow. For example:

/<Table ((?! <Table ).)*? </A>/isU will cause an error and use/<table .*? </A>/I is normal.


So how can we increase the ThreadStackSize of the win platform? In the apache configuration file httpd. enable "Include conf/extra/httpd-mpm.conf" in conf (delete previous comment #), then set "ThreadStackSize 8400000" in the mpm_winnt_module configuration module in the httpd-mpm.conf File (about 8 M ).

<IfModule mpm_winnt_module>
ThreadStackSize 8400000
ThreadsPerChild 200
MaxRequestsPerChild 10000
Win32DisableAcceptEx
</IfModule>

Note that a 32-bit Apache program can only use up to 2 GB of memory space! Therefore, the value of ThreadStackSize multiplied by ThreadsPerChild (8 M * 200) should not exceed 2 GB. Otherwise, apache cannot be started. The error log is as follows:

[Thu Apr 11 20:02:45 2013] [crit] (OS 8) does not have enough storage space to handle this command. : Child 4832: _ beginthreadex failed. Unable to create all worker threads. Created 212 of the 220 threads requested with the ThreadsPerChild configuration directive.

With the above prompt, it is easy to tell you that on my server, when the thread stack size is set to 8 MB, the maximum number of threads that I can set is 212.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.