xref: /PHP-7.0/sapi/phpdbg/phpdbg_watch.h (revision 478f119a)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 7                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2017 The PHP Group                                |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 3.01 of the PHP license,	  |
8    | that is bundled with this package in the file LICENSE, and is        |
9    | available through the world-wide-web at the following url:           |
10    | http://www.php.net/license/3_01.txt                                  |
11    | If you did not receive a copy of the PHP license and are unable to   |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@php.net so we can mail you a copy immediately.               |
14    +----------------------------------------------------------------------+
15    | Authors: Felipe Pena <felipe@php.net>                                |
16    | Authors: Joe Watkins <joe.watkins@live.co.uk>                        |
17    | Authors: Bob Weinand <bwoebi@php.net>                                |
18    +----------------------------------------------------------------------+
19 */
20 
21 #ifndef PHPDBG_WATCH_H
22 #define PHPDBG_WATCH_H
23 
24 #include "phpdbg_cmd.h"
25 
26 #ifdef _WIN32
27 #	include "phpdbg_win.h"
28 #endif
29 
30 #define PHPDBG_WATCH(name) PHPDBG_COMMAND(watch_##name)
31 
32 /**
33  * Printer Forward Declarations
34  */
35 PHPDBG_WATCH(array);
36 PHPDBG_WATCH(delete);
37 PHPDBG_WATCH(recursive);
38 
39 extern const phpdbg_command_t phpdbg_watch_commands[];
40 
41 /* Watchpoint functions/typedefs */
42 
43 /* References are managed through their parent zval *, being a simple WATCH_ON_ZVAL and eventually WATCH_ON_REFCOUNTED */
44 typedef enum {
45 	WATCH_ON_ZVAL,
46 	WATCH_ON_HASHTABLE,
47 	WATCH_ON_REFCOUNTED,
48 } phpdbg_watchtype;
49 
50 
51 #define PHPDBG_WATCH_SIMPLE     0x01
52 #define PHPDBG_WATCH_RECURSIVE  0x02
53 #define PHPDBG_WATCH_ARRAY      0x04
54 #define PHPDBG_WATCH_OBJECT     0x08
55 #define PHPDBG_WATCH_NORMAL     (PHPDBG_WATCH_SIMPLE | PHPDBG_WATCH_RECURSIVE)
56 #define PHPDBG_WATCH_IMPLICIT   0x10
57 
58 #define PHPDBG_DESTRUCTED_ZVAL 0x80
59 
60 typedef struct _phpdbg_watchpoint_t phpdbg_watchpoint_t;
61 
62 struct _phpdbg_watchpoint_t {
63 	union {
64 		zval *zv;
65 		zend_refcounted *ref;
66 		void *ptr;
67 	} addr;
68 	size_t size;
69 	phpdbg_watchtype type;
70 	char flags;
71 	unsigned int implicit_ht_count;
72 	phpdbg_watchpoint_t *parent;
73 	phpdbg_watchpoint_t *reference;
74 	HashTable *parent_container;
75 	zend_string *name_in_parent;
76 	zend_string *str;
77 };
78 
79 typedef struct {
80 	phpdbg_watchpoint_t *watch;
81 	unsigned int refs;
82 	HashTable watches;
83 	HashTable implicit_watches;
84 } phpdbg_watch_collision;
85 
86 typedef struct {
87 	dtor_func_t dtor;
88 	HashTable watches;
89 } phpdbg_watch_ht_info;
90 
91 void phpdbg_setup_watchpoints(void);
92 
93 #ifndef _WIN32
94 int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context);
95 #else
96 int phpdbg_watchpoint_segfault_handler(void *addr);
97 #endif
98 
99 void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch);
100 void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch);
101 
102 int phpdbg_delete_var_watchpoint(char *input, size_t len);
103 int phpdbg_create_var_watchpoint(char *input, size_t len);
104 
105 int phpdbg_print_changed_zvals(void);
106 
107 void phpdbg_list_watchpoints(void);
108 
109 void phpdbg_watch_efree(void *ptr);
110 
111 
112 static long phpdbg_pagesize;
113 
phpdbg_get_page_boundary(void * addr)114 static zend_always_inline void *phpdbg_get_page_boundary(void *addr) {
115 	return (void *) ((size_t) addr & ~(phpdbg_pagesize - 1));
116 }
117 
phpdbg_get_total_page_size(void * addr,size_t size)118 static zend_always_inline size_t phpdbg_get_total_page_size(void *addr, size_t size) {
119 	return (size_t) phpdbg_get_page_boundary((void *) ((size_t) addr + size - 1)) - (size_t) phpdbg_get_page_boundary(addr) + phpdbg_pagesize;
120 }
121 
122 #endif
123