xref: /PHP-5.6/sapi/phpdbg/phpdbg_watch.h (revision 49493a2d)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 5                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2016 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 "TSRM.h"
25 #include "phpdbg_cmd.h"
26 
27 #ifdef _WIN32
28 # include "phpdbg_win.h"
29 #endif
30 
31 #define PHPDBG_WATCH(name) PHPDBG_COMMAND(watch_##name)
32 
33 /**
34  * Printer Forward Declarations
35  */
36 PHPDBG_WATCH(array);
37 PHPDBG_WATCH(delete);
38 PHPDBG_WATCH(recursive);
39 
40 /**
41  * Commands
42  */
43 
44 static const phpdbg_command_t phpdbg_watch_commands[] = {
45 	PHPDBG_COMMAND_D_EX(array,      "create watchpoint on an array", 'a', watch_array,     NULL, "s"),
46 	PHPDBG_COMMAND_D_EX(delete,     "delete watchpoint",             'd', watch_delete,    NULL, "s"),
47 	PHPDBG_COMMAND_D_EX(recursive,  "create recursive watchpoints",  'r', watch_recursive, NULL, "s"),
48 	PHPDBG_END_COMMAND
49 };
50 
51 /* Watchpoint functions/typedefs */
52 
53 typedef enum {
54 	WATCH_ON_ZVAL,
55 	WATCH_ON_HASHTABLE,
56 } phpdbg_watchtype;
57 
58 
59 #define PHPDBG_WATCH_SIMPLE	0x0
60 #define PHPDBG_WATCH_RECURSIVE	0x1
61 
62 typedef struct _phpdbg_watchpoint_t phpdbg_watchpoint_t;
63 
64 struct _phpdbg_watchpoint_t {
65 	phpdbg_watchpoint_t *parent;
66 	HashTable *parent_container;
67 	char *name_in_parent;
68 	size_t name_in_parent_len;
69 	char *str;
70 	size_t str_len;
71 	union {
72 		zval *zv;
73 		HashTable *ht;
74 		void *ptr;
75 	} addr;
76 	size_t size;
77 	phpdbg_watchtype type;
78 	char flags;
79 };
80 
81 void phpdbg_setup_watchpoints(TSRMLS_D);
82 
83 #ifndef _WIN32
84 int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC);
85 #else
86 int phpdbg_watchpoint_segfault_handler(void *addr TSRMLS_DC);
87 #endif
88 
89 void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch);
90 void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch);
91 
92 int phpdbg_delete_var_watchpoint(char *input, size_t len TSRMLS_DC);
93 int phpdbg_create_var_watchpoint(char *input, size_t len TSRMLS_DC);
94 
95 int phpdbg_print_changed_zvals(TSRMLS_D);
96 
97 void phpdbg_list_watchpoints(TSRMLS_D);
98 
99 void phpdbg_watch_efree(void *ptr);
100 
101 
102 static long phpdbg_pagesize;
103 
phpdbg_get_page_boundary(void * addr)104 static zend_always_inline void *phpdbg_get_page_boundary(void *addr) {
105 	return (void *)((size_t)addr & ~(phpdbg_pagesize - 1));
106 }
107 
phpdbg_get_total_page_size(void * addr,size_t size)108 static zend_always_inline size_t phpdbg_get_total_page_size(void *addr, size_t size) {
109 	return (size_t)phpdbg_get_page_boundary((void *)((size_t)addr + size - 1)) - (size_t)phpdbg_get_page_boundary(addr) + phpdbg_pagesize;
110 }
111 
112 #endif
113