Bug #71596 [Com]: Segmentation fault on ZTS with date function (setlocale)

From: Date: Mon, 15 Feb 2016 10:27:04 +0000
Subject: Bug #71596 [Com]: Segmentation fault on ZTS with date function (setlocale)
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-199225@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=71596&edit=1

 ID:                 71596
 Comment by:         maroszek at gmx dot net
 Reported by:        maroszek at gmx dot net
 Summary:            Segmentation fault on ZTS with date function
                     (setlocale)
 Status:             Open
 Type:               Bug
 Package:            Date/time related
 Operating System:   Windows
 PHP Version:        7.0.3
 Block user comment: N
 Private report:     N

 New Comment:

When adding this code before ts_resource(0); the crash remains but looks a little bit different. 
_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);

MSDN: https://msdn.microsoft.com/de-de/library/26c0tb7x.aspx
We a calling this function in SAPI.c in sapi_startup. AFAIK this function is only called for the
"main" thread. 
If i read the MSDN right, we need to call this function in all worker threads aswell. Neither one of
the SAPIs does this!?


Previous Comments:
------------------------------------------------------------------------
[2016-02-15 09:39:55] maroszek at gmx dot net

Examples: https://www.dropbox.com/s/c5cs2rz1zcssk3r/CrashTest.zip
StackTrace: https://www.dropbox.com/s/saff1d5z5z2vpon/PHPStackTraceSetLocale.png?dl=0

------------------------------------------------------------------------
[2016-02-15 09:38:26] maroszek at gmx dot net

Description:
------------
Description:
------------
PHP 7 is current stable (Also reproducable with 5.6.18)
PHP 7 is used as Embed (Also reproducable with 5.6.18)

Visual Studio 2013

I build a simple example to demonstrate the threading problem. 
It crashes nearly instatly. Running only one thread works fine.

Expected result:
----------------
No crash. Endless loop doing the work. 

Actual result:
--------------
Crash. I attached a backtrace which shows the concurrent access to setlocale which causes the crash



Test script:
---------------
#include <stdio.h>
#include <iostream>
#include <thread>

#include <main/php.h>
#include <main/SAPI.h>
#include <main/php_main.h>
#include <main/php_variables.h>
#include <main/php_ini.h>
#include <zend_ini.h>

#ifdef ZTS
ZEND_TSRMLS_CACHE_EXTERN();
#endif

zend_module_entry ips_module_entry = {
	STANDARD_MODULE_HEADER,
	"XYZ",
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	NO_VERSION_YET,
	STANDARD_MODULE_PROPERTIES
};

static size_t php_embed_read_post(char *str, size_t str_length)
{
	return 0;
}

static char* php_embed_read_cookies()
{
	return NULL;
}

static size_t php_embed_ub_write(const char *str, size_t str_length)
{
	std::cout << str;
	return str_length;
}

static void php_embed_flush(void *server_context)
{
	//
}

static void php_embed_send_header(sapi_header_struct *sapi_header, void *server_context)
{
	//
}

static void php_embed_log_message(char *message)
{
	fprintf(stderr, "%s\n", message);
}

static void php_embed_register_variables(zval *track_vars_array)
{
	//
}

static int php_embed_startup(sapi_module_struct *sapi_module)
{
	if (php_module_startup(sapi_module, NULL, 0) == FAILURE) {
		return FAILURE;
	}
	return SUCCESS;
}

sapi_module_struct php_embed_module = {
	"XYZ",                       /* name */
	"PHP for XYZ",               /* pretty name */

	php_embed_startup,                 /* startup */
	php_module_shutdown_wrapper,       /* shutdown */

	NULL,                              /* activate */
	NULL,                              /* deactivate */

	php_embed_ub_write,                /* unbuffered write */
	php_embed_flush,                   /* flush */
	NULL,                              /* get uid */
	NULL,                              /* getenv */

	php_error,                         /* error handler */

	NULL,                              /* header handler */
	NULL,                              /* send headers handler */
	php_embed_send_header,             /* send header handler */

	php_embed_read_post,               /* read POST data */
	php_embed_read_cookies,            /* read Cookies */

	php_embed_register_variables,   /* register server variables */
	php_embed_log_message,          /* Log message */
	NULL,							/* Get request time */
	NULL,							/* Child terminate */

	STANDARD_SAPI_MODULE_PROPERTIES
};

int main(int argc, const char * argv[]) {

	tsrm_startup(128, 1, 0, NULL);
	sapi_startup(&php_embed_module);

	php_embed_module.ini_entries = "date.timezone=Europe/Berlin\n\0";

	if (php_embed_module.startup(&php_embed_module) == FAILURE) {
		throw std::runtime_error("Could not start PHP!");
	}

	for (int i = 0; i < 10; i++) {
		std::thread([&argv]{
			ts_resource(0);

			while (true){
				zend_file_handle file_handle;
				file_handle.type = ZEND_HANDLE_FILENAME;
				file_handle.filename = "date.php";
				file_handle.handle.fp = NULL;
				file_handle.opened_path = NULL;
				file_handle.free_filename = 0;

				if (php_request_startup() == FAILURE) {
					//std::cout << "ERR" << std::endl;
					php_request_shutdown(NULL);
					continue;
				}

				if (php_execute_script(&file_handle) == FAILURE)
					break;

				//std::cout << "RUN" << std::endl;
				php_request_shutdown(NULL);
			}

			std::cout << "DIED" << std::endl;

		}).detach();
	}

	while (true);

	return 0;
}



------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=71596&edit=1


Thread (36 messages)

« previous php.bugs (#199225) next »