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