Hi Dmitry,

Have some diagnostics:

1) zend_shutdown() is called before anything in TSRM. It invokes zend_hash_graceful_reverse_destroy(&module_registry);

2) module_destructor() is invoked via the hash-destroyer (being part of the module_registry hash constructor). This performs the MSHUTDOWN routine for each registered module, which in several cases (now) includes a PHP-side call to ts_free_id(). The ts_free_id() call usually allows the next stage to be unproblematic; it also marks the module's entry in the resource table as 'done', so that the final clearing loop won't try to double-free it. However, ts_free_id() doesn't check for 'done' itself before it frees resources.

3) DL_UNLOAD (an alias for FreeLibrary, under doze) is then called on any module loaded via dl() or php.ini (checking for a module handle)... it looks like this stage might only have happened under Macs on CLI until mid-March...

4) tsrm_shutdown() - the final clearing loop - is called via the end of the various SAPI source files (in this case, php_cli.c), and any resource that hasn't been freed explicitly by this point is freed there.

It won't help our particular situation, but I think automatically calling ts_free_id() on dl-loaded modules would be better than either blanket avoidance of tsrm_shutdown() or requiring each module to call ts_free_id() explicitly during MINIT. Patch(es) to do that in PHP_5_2 branch attached.

The problem in PHP-GTK is we're crashing when the compiler_globals dtor is called in tsrm_shutdown(), rather than when the gtk_globals dtor is called. I think this is a ZE problem rather than ours, but see what you think: somehow, in compiler_globals_dtor(),

compiler_globals->class_table != GLOBAL_CLASS_TABLE

and the compiler_globals->class_table is destroyed and freed because of that.

- Steph

----- Original Message ----- From: "Dmitry Stogov" <[EMAIL PROTECTED]>
To: "'Steph Fox'" <[EMAIL PROTECTED]>
Cc: "'internals'" <internals@lists.php.net>
Sent: Thursday, June 01, 2006 1:25 PM
Subject: RE: [PHP-DEV] tsrm_shutdown() and the CLI SAPI


Patch was cutted.

Dmitry.

-----Original Message-----
From: Dmitry Stogov [mailto:[EMAIL PROTECTED]
Sent: Thursday, June 01, 2006 3:05 PM
To: 'Andi Gutmans'; 'Steph Fox'; 'Frank M. Kromann'
Cc: 'internals'; 'Antony Dovgal'; 'Xuefer'
Subject: RE: [PHP-DEV] tsrm_shutdown() and the CLI SAPI


Hi Stepth,

I reproduced crash of php-gtk on linix with php-zts.
I mean running "php -v" then php.ini contains
"extension=gtk2.so". The crash occurs only then php compiled
with --enable-debug.

The reason of the crash is a bug in ZE that is activated by
memory leaks in php-gtk. In case of "php -v" we don't do
request startup/shutdown and as result we don't handle memory
leaks on request shutdown. During tsrm_shutdown()
shutdow_nmemory_manager() is called after sapi_shutdown() and
as result we cannot access sapi_globals then trying to print
information about memory leaks and crashes.

The solution - don't print information about memory leaks
during tsrm_shutdown().

Patch for PHP_5_2 is attached, but it can be manually applied
to any version.

Steph, does you crash(es) go away with this patch?

I am going to commit patch in 24h.
Any objections?

Thanks. Dmitry.

> -----Original Message-----
> From: Andi Gutmans [mailto:[EMAIL PROTECTED]
> Sent: Thursday, June 01, 2006 10:29 AM
> To: Steph Fox; Frank M. Kromann
> Cc: 'internals'; 'Antony Dovgal'; Dmitry Stogov; 'Xuefer'
> Subject: Re: [PHP-DEV] tsrm_shutdown() and the CLI SAPI
>
>
> As we are not planning to release a new version within the next
> couple of weeks, I suggest before jumping to conclusions we
> take a look at it.
>
> If you really need to comment out that line in the meanwhile
> that's OK with me.
>
> Andi
>
> At 09:50 PM 5/31/2006, Steph Fox wrote:
> >>>Yes, it would, given the root cause - but would you
really want to
> >>>break the whole of PHP for an academic exercise?
> >>
> >>It's not really an academic exercise. If we know there's a bug
> >>someplace we should at least look into it and try and
understand it.
> >
> >Frank's referring to Zeev's three-years-ago decision to simply opt
> >out of tsrm_shutdown() here... he's suggesting we revert it.
> >
> >>Then if we decide to remove the trsm_shutdown call for a
good reason
> >>(circular dependency, blah blah blah) then we can do that
and put a
> >>nice fat comment on why it's the right thing to do. But I
do think
> >>it's benefical to try and understand what's happening.
> >
> >Fine, but breaking working code while you're trying to understand
> >what's happening is far from beneficial to our users. Can't
> we at least #0 it?
> >
> >>
> >>Andi
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
>



__________ NOD32 1.1380 (20060125) Information __________

This message was checked by NOD32 antivirus system.
http://www.eset.com




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


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

__________ NOD32 1.1380 (20060125) Information __________

This message was checked by NOD32 antivirus system.
http://www.eset.com


Index: Zend/zend_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_API.c,v
retrieving revision 1.296.2.27.2.13
diff -u -r1.296.2.27.2.13 zend_API.c
--- Zend/zend_API.c     27 May 2006 20:16:53 -0000      1.296.2.27.2.13
+++ Zend/zend_API.c     2 Jun 2006 05:27:09 -0000
@@ -32,6 +32,7 @@

/* these variables are true statics/globals, and have to be mutex'ed on every 
access */
static int module_count=0;
+static int dl_module_count=0;
ZEND_API HashTable module_registry;

/* this function doesn't check for too many parameters */
@@ -1831,6 +1832,8 @@

void module_destructor(zend_module_entry *module)
{
+       int table_size;
+
        TSRMLS_FETCH();

        if (module->type == MODULE_TEMPORARY) {
@@ -1852,6 +1855,8 @@
#if HAVE_LIBDL || defined(HAVE_MACH_O_DYLD_H)
#if !(defined(NETWARE) && defined(APACHE_1_BUILD))
        if (module->handle) {
+               table_size = tsrm_table_size() + 1;
+               ts_free_id(table_size - zend_dl_module_reverse());
                DL_UNLOAD(module->handle);
        }
#endif
@@ -1899,6 +1904,12 @@
        return ++module_count;
}

+/* return the dl module count */
+int zend_dl_module_reverse(void)
+{
+       return ++dl_module_count;
+}
+
static zend_class_entry *do_register_internal_class(zend_class_entry 
*orig_class_entry, zend_uint ce_flags TSRMLS_DC)
{
        zend_class_entry *class_entry = malloc(sizeof(zend_class_entry));
Index: Zend/zend_API.h
===================================================================
RCS file: /repository/ZendEngine2/zend_API.h,v
retrieving revision 1.207.2.8.2.2
diff -u -r1.207.2.8.2.2 zend_API.h
--- Zend/zend_API.h     25 May 2006 10:01:06 -0000      1.207.2.8.2.2
+++ Zend/zend_API.h     2 Jun 2006 05:12:12 -0000
@@ -160,6 +160,7 @@
#endif

int zend_next_free_module(void);
+int zend_dl_module_reverse(void);

BEGIN_EXTERN_C()
ZEND_API int zend_get_parameters(int ht, int param_count, ...);
Index: TSRM/TSRM.c
===================================================================
RCS file: /repository/TSRM/TSRM.c,v
retrieving revision 1.68.2.3
diff -u -r1.68.2.3 TSRM.c
--- TSRM/TSRM.c 14 Mar 2006 15:16:07 -0000      1.68.2.3
+++ TSRM/TSRM.c 2 Jun 2006 05:06:49 -0000
@@ -542,7 +542,7 @@

                        while (p) {
                                if (p->count > j && p->storage[j]) {
-                                       if (resource_types_table && 
resource_types_table[j].dtor) {
+                                       if (resource_types_table && 
resource_types_table[j].dtor && !resource_types_table[j].done) {
                                                
resource_types_table[j].dtor(p->storage[j], &p->storage);
                                        }
                                        free(p->storage[j]);
@@ -586,6 +586,12 @@
#endif
}

+/* Obtain the current resource table size */
+TSRM_API int tsrm_table_size(void)
+{
+       return id_count;
+}
+

/* Allocate a mutex */
TSRM_API MUTEX_T tsrm_mutex_alloc(void)
Index: TSRM/TSRM.h
===================================================================
RCS file: /repository/TSRM/TSRM.h,v
retrieving revision 1.50.2.2
diff -u -r1.50.2.2 TSRM.h
--- TSRM/TSRM.h 14 Mar 2006 15:16:07 -0000      1.50.2.2
+++ TSRM/TSRM.h 2 Jun 2006 05:06:43 -0000
@@ -127,6 +127,7 @@

/* utility functions */
TSRM_API THREAD_T tsrm_thread_id(void);
+TSRM_API int tsrm_table_size(void);
TSRM_API MUTEX_T tsrm_mutex_alloc(void);
TSRM_API void tsrm_mutex_free(MUTEX_T mutexp);
TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp);

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to