# Need help with simple PHP patch?



## juv123 (Jan 21, 2011)

Hello all,

I would like to change the order of a line in zend_execute.h in PHP.  I feel I may be suffering from this bug: http://bugs.php.net/bug.php?id=52678

The patch is simply to move 1 line of code down 1 line in zend_execute.h.  Like so:

```
static inline void zend_vm_stack_clear_multiple(TSRMLS_D)
{
        void **p = EG(argument_stack)->top - 1;
        int delete_count = (int)(zend_uintptr_t) *p;

        while (--delete_count>=0) {
                zval *q = *(zval **)(--p);
                *p = NULL;
                zval_ptr_dtor(&q);
        }
        zend_vm_stack_free_int(p TSRMLS_CC);
}
```
TO:

```
static inline void zend_vm_stack_clear_multiple(TSRMLS_D)
{
        void **p = EG(argument_stack)->top - 1;
        int delete_count = (int)(zend_uintptr_t) *p;

        while (--delete_count>=0) {
                zval *q = *(zval **)(--p);
                zval_ptr_dtor(&q);
                *p = NULL;
        }
        zend_vm_stack_free_int(p TSRMLS_CC);
}
```
CHANGED: *p = NULL; // moved down 1 line

I thought I could make the change to the zend_execute.h file in my lang/php5/work directory then deinstall and reinstall.  This did update the working zend_execute.h (located at /usr/local/include/php/Zend/zend_execute.h)

I still get segfaults, but the error line in the core dump doesn't change.  That is: the error used to be in 
	
	



```
zval_ptr_dtor on line 318
```
 after the change, I would expect the error to change to line 317 (since it moved up a line) but the error still reports on line 318.  This leads me to believe that my method of patching zend_execute.h is incorrect.  Can someone lead me in the right direction?

Thanks!


----------



## wblock@ (Jan 21, 2011)

"reinstall" will find the built object code already in place and will just install that without rebuilding from source.

`# make clean patch`
will extract the source and apply port patches to it.

Then you can make your own changes, deinstall the existing and install the new.

Your patch will disappear when you clean the port, so if it's a known bug fix, make a real ports patch, then send it to the maintainer or enter a PR.


----------



## juv123 (Jan 22, 2011)

wblock - thank you for the reply.

When I edit the code, I am supposed to edit the code from the file in the /work/ directory right?
First copy the file to file.orig, then
`# make makefile`
that makes my patch show up in the files directory. So then I do a `# make clean patch`
and I get a stop error:

```
===> Setting user-specified options for php5-5.3.0 and dependencies
===>  Patching for php5-5.3.5
===>  Applying FreeBSD patches for php5-5.3.5
Ignoring previously applied (or reversed) patch.
1 out of 1 hunks ignored--saving rejects to TSRM/threads.m4.rej
=> Patch patch-TSRM_threads.m4 failed to apply cleanly.
*** Error code 1

Stop in /usr/ports/lang/php5.3.5.
*** Error code 1

Stop in /usr/ports/lang/php5.3.5.
```
After that I am unable to do anything including deinstall/reinstall - it keeps giving me the stop error.


----------



## expl (Jan 22, 2011)

Fast way to patch the source is to do


```
make extract
```

Edit source in work/

then do


```
make install
```


----------



## wblock@ (Jan 22, 2011)

juv123 said:
			
		

> wblock - thank you for the reply.
> 
> When I edit the code, I am supposed to edit the code from the file in the /work/ directory right?
> First copy the file to file.orig, then
> `# make makefile`



ITYM "makepatch".  The problem is that there are already a bunch of patches in files/.  So I would not use makepatch, at least here.  Here's how to do it the old way, which is more work but better because you end up with a patch name that tells what file it's patching.  Here's what to do:

`# cd /usr/ports/lang/php5`

Make sure that all the port patches have been applied before you start making changes.
`# make patch`
`# cd work/php-5.3.5`

Save the original file.
`# cp Zend/zend_execute.h Zend/zend_execute.h.orig`

Edit Zend/zend_execute.h, moving that one line.  Save it.

Create the patch.
`# diff -u Zend/zend_execute.h.orig Zend/zend_execute.h > ../../files/patch-Zend_zend_execute.h`

This is done from the work/php-5.3.5 directory, because that will be the current directory when the ports system applies it.  The filename is pretty much "patch" plus the path with underscores as separators, and of course it's written in the files/ directory of the port.

That's it.  Now that patch file is just another port patch.  Be sure to save a copy of it outside of the ports tree (/usr/ports/) because portsnap(8) will want to delete it when you update.

*Warning: I don't know about the value of the patched code, and did not actually compile or test it, just whether it applied cleanly.  This is just an example of creating a port patch.*

If the patch is trustworthy/important/valuable/useful to others, check with the port maintainer to see about including it in the port.


----------



## wblock@ (Jan 22, 2011)

expl said:
			
		

> Fast way to patch the source is to do
> 
> 
> ```
> ...



`# make patch`
does the same, but also applies port patches so you'll be editing the final version of the file.

If you're making new port patches, watch out for files that already have a patch.  Two patches to the same file are bad news, so regenerate the patch to combine them.


----------



## juv123 (Jan 23, 2011)

Okay - 2 questions:
1.  Does it matter if you have one or 2 underscores in the patch name for the folder:


			
				wblock said:
			
		

> Save the original file.
> Create the patch.
> `# diff -u Zend/zend_execute.h.orig Zend/zend_execute.h > ../../files/patch-Zend_zend_execute.h`


I have the patch named as:
patch-Zend__zend_execute.h

2nd Question, once the patch is created (and a copy made outside the ports tree for saving), I do a:
`# make clean patch`
then should I deinstall and reinstall the port?


----------



## wblock@ (Jan 23, 2011)

juv123 said:
			
		

> Okay - 2 questions:
> 1.  Does it matter if you have one or 2 underscores in the patch name for the folder:
> 
> I have the patch named as:
> patch-Zend__zend_execute.h



That will work, the system doesn't care about it because the actual file names are inside the patch.  I'd still rename it, because it's good technique to be as precise as possible with the patch name.



> 2nd Question, once the patch is created (and a copy made outside the ports tree for saving), I do a:
> `# make clean patch`



It's not necessary to do that again, but it won't hurt.  "patch" is done as part of the normal build.



> then should I deinstall and reinstall the port?



Treat it just as if you were upgrading the port.  Since it's experimental, you should probably make sure it builds with the new patch first:
`# make clean`
`# make`

If it builds without errors, then
`# make deinstall install`


----------



## juv123 (Jan 23, 2011)

Awesome.  Thank you very much for all of your help!


----------



## juv123 (Jan 28, 2011)

Just wanted to drop back in and state that I figured out my problem with segfaults.

Apache 2.2.17
PHP 5.3.4 & 5.3.5  (from ports.  Segfaults didn't occur in php 5.2.17 compiled from source)

I was getting random segmentation faults on a site that has medium traffic (about 12-20 faults a day for a site with about 200,000 page views a day).  Turns out it was due to the PHP "virtual()" function.  I had about 3-4 on every page to include footer, header, etc.  Changing these out to include() or require() completely removed segmentation faults.  I post this in hopes it can help someone else in case it is a bug.

My gdb `# bt full` is below


```
Loaded symbols for /libexec/ld-elf.so.1
#0  0x28adf4f1 in _zval_ptr_dtor (zval_ptr=0xbfbfd23c,
    __zend_filename=0x28c61a48 "/usr/ports/lang/php5/work/php-5.3.5/Zend/zend_execute.h", __zend_lineno=318) at zend.h:385
385     zend.h: No such file or directory.
        in zend.h
[New Thread 0x28501040 (LWP 100269)]
(gdb) bt full
#0  0x28adf4f1 in _zval_ptr_dtor (zval_ptr=0xbfbfd23c,
    __zend_filename=0x28c61a48 "/usr/ports/lang/php5/work/php-5.3.5/Zend/zend_execute.h", __zend_lineno=318) at zend.h:385
No locals.
#1  0x28b1d1fd in zend_vm_stack_clear_multiple () at zend_execute.h:318
        q = (zval *) 0x0
        p = (void **) 0x29924ab8
        delete_count = 686419922
#2  0x28b1dc33 in zend_do_fcall_common_helper_SPEC (execute_data=0x29924040) at zend_vm_execute.h:406
        opline = (zend_op *) 0x28e9bc2c
        should_change_scope = 0 '\0'
#3  0x28b22758 in ZEND_DO_FCALL_SPEC_CONST_HANDLER (execute_data=0x29924040) at zend_vm_execute.h:1606
        opline = (zend_op *) 0x28e9bc2c
        fname = (zval *) 0x28e9bc48
#4  0x28b1ca6b in execute (op_array=0x28e9f0a0) at zend_vm_execute.h:107
        ret = 0
        execute_data = (zend_execute_data *) 0x29924040
        nested = 1 '\001'
        original_in_execution = 0 '\0'
#5  0x28af0557 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /usr/ports/lang/php5/work/php-5.3.5/Zend/zend.c:1194
        files = 0xbfbfd404 ""
        i = 1
        file_handle = (zend_file_handle *) 0xbfbfe934
        orig_op_array = (zend_op_array *) 0x0
        orig_retval_ptr_ptr = (zval **) 0x0
#6  0x28a843ad in php_execute_script (primary_file=0xbfbfe934) at /usr/ports/lang/php5/work/php-5.3.5/main/main.c:2265
        realfile = "Â¥Â¤Â¬(Ã¬SÃ©(\230eÃ©(l\000\000\000\020\000\000\000\220\214[(Ã€\aÃ¥(\bÃ¥Â¿Â¿\230Ã˜Â¬(\000\214[(\024TÃ©(\200Ã Ã…(Â©\001", '\0' 
<repeats 14 times>, "\004ÃŠÂ¬(\024eÃ©
(\021\000\000\000ÃˆÃ¤Â¿Â¿Â¥Â¤Â¬ (xÃ¶\002\000\v\000\000\000\021\000\000\000ÃˆÃ¤Â¿Â¿yÂ§Â¬
( Ã¶\002\000 Ã¶\002\000\021\000\000\000\024\216[(`yÃ©(|yÃ©(T,\003\000\021\000\000\000Ã€
aÃ¥(Ã°\020Ã¸(\004ÃŠÂ¬(Â´yÃ©(TÃ™Ã‡(\004\000\000\000\bÃ¥Â¿Â¿yÂ§Â¬(\b,\003\000\b,\003\000\210yÃ©
(\000\000\000\000\021\000\000\0008Ã¥Â¿Â¿Â¥Â¤Â¬(`yÃ©(X\000\000\000"...
        __orig_bailout = (sigjmp_buf *) 0xbfbfe970
        __bailout = {{_sjb = {682115418, 0, -1077947412, -1077942008, 0, -1077942100, 4735, -1077942168, 682556027, 684203328,
      682590304, 0}}}
        prepend_file_p = (zend_file_handle *) 0x0
        append_file_p = (zend_file_handle *) 0x0
        prepend_file = {type = ZEND_HANDLE_FILENAME, filename = 0x0, opened_path = 0x0, handle = {fd = 0, fp = 0x0, stream = {
      handle = 0x0, isatty = 0, mmap = {len = 0, pos = 0, map = 0x0, buf = 0x0, old_handle = 0x0, old_closer = 0}, reader = 0,
      fsizer = 0, closer = 0}}, free_filename = 0 '\0'}
        append_file = {type = ZEND_HANDLE_FILENAME, filename = 0x0, opened_path = 0x0, handle = {fd = 0, fp = 0x0, stream = {
      handle = 0x0, isatty = 0, mmap = {len = 0, pos = 0, map = 0x0, buf = 0x0, old_handle = 0x0, old_closer = 0}, reader = 0,
      fsizer = 0, closer = 0}}, free_filename = 0 '\0'}
        old_cwd = 0xbfbfd420 "/"
        use_heap = 0 '\0'
---Type <return> to continue, or q <return> to quit---
        retval = 0
#7  0x28bbbd73 in php_handler (r=0x29918058) at /usr/ports/lang/php5/work/php-5.3.5/sapi/apache2handler/sapi_apache2.c:669
        zfd = {type = ZEND_HANDLE_MAPPED, filename = 0x29919828 "/usr/home/yyy/public_html/removed/removed.php", opened_path = 0x0,
  handle = {fd = 686393184, fp = 0x28e98760, stream = {handle = 0x28e98760, isatty = 0, mmap = {len = 11011, pos = 0, map = 0x0,
        buf = 0x295fd000 <Address 0x295fd000 out of bounds>, old_handle = 0x0, old_closer = 0},
      reader = 0x28a9bab0 <_php_stream_read>, fsizer = 0x28a825e0 <php_zend_stream_fsizer>,
      closer = 0x28a825c0 <php_zend_stream_mmap_closer>}}, free_filename = 0 '\0'}
        __orig_bailout = (sigjmp_buf *) 0x0
        __bailout = {{_sjb = {683391806, 0, -1077942004, -1077941800, 0, 686098368, 4735, 676142160, 676141696, 686099352,
      -1077941800, 0}}}
        ctx = (php_struct * volatile) 0x2991c3f0
        conf = (void *) 0x28e4f858
        brigade = (apr_bucket_brigade * volatile) 0x2991cb18
        bucket = (apr_bucket *) 0x2854c760
        rv = 676135291
        parent_req = (request_rec * volatile) 0x0
#8  0x08076a89 in ap_run_handler (r=0x29918058) at config.c:157
        n = 0
        rv = Variable "rv" is not available.
```


----------

