11#[=============================================================================[
22Check for ptrace().
33
4- Result variables:
5-
6- * `PHP_TRACE_TYPE`
7- Name of the trace type that should be used in FPM.
8-
9- Cache variables:
4+ ## Cache variables:
105
116* `HAVE_PTRACE`
7+
128 Whether `ptrace()` is present and working as expected.
9+
1310* `HAVE_MACH_VM_READ`
11+
1412 Whether `ptrace()` didn't work and the `mach_vm_read()` is present.
13+
14+ ## Result variables
15+
1516* `PROC_MEM_FILE`
16- String of the `/proc/pid/mem` interface.
17+
18+ If neither `ptrace()` or mach_vm_read()` works, the `/proc/pid/<file>`
19+ interface (`mem` or `as`) is set if found and works as expected.
1720#]=============================================================================]
1821
1922include_guard (GLOBAL )
2023
2124include (CheckSourceCompiles)
2225include (CheckSourceRuns)
26+ include (CheckSymbolExists)
2327include (CMakePushCheckState)
2428
25- message (CHECK_START "Checking for ptrace" )
26- check_source_compiles(C [[
27- #include <sys/types.h>
28- #include <sys/ptrace.h>
29-
30- int main(void)
31- {
32- ptrace(0, 0, (void *) 0, 0);
33- return 0;
34- }
35- ]] _have_ptrace)
36- if (_have_ptrace)
37- message (CHECK_PASS "yes" )
38- else ()
39- message (CHECK_FAIL "no" )
40- endif ()
29+ message (CHECK_START "Checking whether ptrace works" )
4130
42- if (_have_ptrace)
43- message (CHECK_START "Checking whether ptrace works" )
44- check_source_runs(C [[
45- #include <unistd.h>
46- #include <signal.h>
47- #include <sys/wait.h>
31+ cmake_push_check_state(RESET)
32+ set (CMAKE_REQUIRED_QUIET TRUE )
33+ check_source_compiles(C [[
4834 #include <sys/types.h>
4935 #include <sys/ptrace.h>
50- #include <errno.h>
51-
52- #if !defined(PTRACE_ATTACH) && defined(PT_ATTACH)
53- #define PTRACE_ATTACH PT_ATTACH
54- #endif
55-
56- #if !defined(PTRACE_DETACH) && defined(PT_DETACH)
57- #define PTRACE_DETACH PT_DETACH
58- #endif
59-
60- #if !defined(PTRACE_PEEKDATA) && defined(PT_READ_D)
61- #define PTRACE_PEEKDATA PT_READ_D
62- #endif
6336
6437 int main(void)
6538 {
66- /* copy will fail if sizeof(long) == 8 and we've got "int ptrace()" */
67- long v1 = (unsigned int) -1;
68- long v2;
69- pid_t child;
70- int status;
39+ ptrace(0, 0, (void *) 0, 0);
40+ return 0;
41+ }
42+ ]] _HAVE_PTRACE)
43+ cmake_pop_check_state()
44+
45+ if (_HAVE_PTRACE)
46+ cmake_push_check_state(RESET)
47+ set (CMAKE_REQUIRED_QUIET TRUE )
48+ check_source_runs(C [[
49+ #include <unistd.h>
50+ #include <signal.h>
51+ #include <sys/wait.h>
52+ #include <sys/types.h>
53+ #include <sys/ptrace.h>
54+ #include <errno.h>
55+
56+ #if !defined(PTRACE_ATTACH) && defined(PT_ATTACH)
57+ # define PTRACE_ATTACH PT_ATTACH
58+ #endif
59+
60+ #if !defined(PTRACE_DETACH) && defined(PT_DETACH)
61+ # define PTRACE_DETACH PT_DETACH
62+ #endif
63+
64+ #if !defined(PTRACE_PEEKDATA) && defined(PT_READ_D)
65+ # define PTRACE_PEEKDATA PT_READ_D
66+ #endif
67+
68+ int main(void)
69+ {
70+ /* copy will fail if sizeof(long) == 8 and we've got "int ptrace()" */
71+ long v1 = (unsigned int) -1;
72+ long v2;
73+ pid_t child;
74+ int status;
75+
76+ if ( (child = fork()) ) { /* parent */
77+ int ret = 0;
78+
79+ if (0 > ptrace(PTRACE_ATTACH, child, 0, 0)) {
80+ return 2;
81+ }
7182
72- if ( (child = fork()) ) { /* parent */
73- int ret = 0;
83+ waitpid(child, &status, 0);
7484
75- if (0 > ptrace(PTRACE_ATTACH, child, 0, 0)) {
76- return 2;
77- }
85+ #ifdef PT_IO
86+ struct ptrace_io_desc ptio = {
87+ .piod_op = PIOD_READ_D,
88+ .piod_offs = &v1,
89+ .piod_addr = &v2,
90+ .piod_len = sizeof(v1)
91+ };
7892
79- waitpid(child, &status, 0);
93+ if (0 > ptrace(PT_IO, child, (void *) &ptio, 0)) {
94+ ret = 3;
95+ }
96+ #else
97+ errno = 0;
8098
81- #ifdef PT_IO
82- struct ptrace_io_desc ptio = {
83- .piod_op = PIOD_READ_D,
84- .piod_offs = &v1,
85- .piod_addr = &v2,
86- .piod_len = sizeof(v1)
87- };
99+ v2 = ptrace(PTRACE_PEEKDATA, child, (void *) &v1, 0);
88100
89- if (0 > ptrace(PT_IO, child, (void *) &ptio, 0) ) {
90- ret = 3 ;
91- }
92- #else
93- errno = 0 ;
101+ if (errno ) {
102+ ret = 4 ;
103+ }
104+ #endif
105+ ptrace(PTRACE_DETACH, child, (void *) 1, 0) ;
94106
95- v2 = ptrace(PTRACE_PEEKDATA, child, (void *) &v1, 0 );
107+ kill( child, SIGKILL );
96108
97- if (errno) {
98- ret = 4;
109+ return ret ? ret : (v1 != v2);
110+ } else { /* child */
111+ sleep(10);
112+ return 0;
99113 }
100- #endif
101- ptrace(PTRACE_DETACH, child, (void *) 1, 0);
102-
103- kill(child, SIGKILL);
104-
105- return ret ? ret : (v1 != v2);
106- } else { /* child */
107- sleep(10);
108- return 0;
109114 }
110- }
111- ]] HAVE_PTRACE)
115+ ]] HAVE_PTRACE)
116+ cmake_pop_check_state()
117+ endif ()
112118
113- if (HAVE_PTRACE)
114- message (CHECK_PASS "yes" )
115- else ()
116- message (CHECK_FAIL "no" )
117- endif ()
119+ if (HAVE_PTRACE)
120+ message (CHECK_PASS "yes" )
121+ return ()
118122endif ()
123+ message (CHECK_FAIL "no" )
119124
120- if (NOT HAVE_PTRACE)
121- check_source_compiles(C [[
122- #include <mach/mach.h>
123- #include <mach/mach_vm.h>
125+ check_symbol_exists(mach_vm_read "mach/mach.h;mach/mach_vm.h" HAVE_MACH_VM_READ)
124126
125- int main(void)
126- {
127- mach_vm_read(
128- (vm_map_t)0,
129- (mach_vm_address_t)0,
130- (mach_vm_size_t)0,
131- (vm_offset_t *)0,
132- (mach_msg_type_number_t*)0
133- );
134- return 0;
135- }
136- ]] HAVE_MACH_VM_READ)
127+ if (HAVE_MACH_VM_READ)
128+ return ()
137129endif ()
138130
139- # TODO: Check if /proc/self is sufficient location instead of the /proc/$$ as in
140- # Autoconf.
141- message (CHECK_START "Checking for proc mem file" )
142- if (EXISTS /proc/self/mem)
143- set (_php_proc_mem_file "mem" )
144- elseif (EXISTS /proc/self/as)
145- set (_php_proc_mem_file "as" )
146- endif ()
131+ message (CHECK_START "Checking for process memory access file" )
132+
133+ if (NOT CMAKE_CROSSCOMPILING )
134+ set (PROC_MEM_FILE)
135+ if (EXISTS /proc/self/mem)
136+ set (PROC_MEM_FILE "mem" )
137+ elseif (EXISTS /proc/self/as)
138+ set (PROC_MEM_FILE "as" )
139+ endif ()
147140
148- if (_php_proc_mem_file)
149- if (NOT CMAKE_CROSSCOMPILING )
141+ if (PROC_MEM_FILE)
150142 cmake_push_check_state(RESET)
151143 set (CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
144+ set (CMAKE_REQUIRED_QUIET TRUE )
152145 check_source_runs(C "
153146 #define _FILE_OFFSET_BITS 64
154147 #include <stdint.h>
@@ -163,7 +156,7 @@ if(_php_proc_mem_file)
163156 long v1 = (unsigned int) -1, v2 = 0;
164157 char buf[128];
165158 int fd;
166- sprintf(buf, \" /proc/%d/${_php_proc_mem_file } \" , getpid());
159+ sprintf(buf, \" /proc/%d/${PROC_MEM_FILE } \" , getpid());
167160 fd = open(buf, O_RDONLY);
168161 if (0 > fd) {
169162 return 1;
@@ -175,29 +168,20 @@ if(_php_proc_mem_file)
175168 close(fd);
176169 return v1 != v2;
177170 }
178- " _php_proc_mem_successful )
171+ " _HAVE_PROC_MEM_FILE )
179172 cmake_pop_check_state()
173+
174+ if (NOT _HAVE_PROC_MEM_FILE)
175+ unset (PROC_MEM_FILE)
176+ endif ()
180177 endif ()
181178endif ()
182179
183- if (_php_proc_mem_file AND _php_proc_mem_successful)
184- set (
185- PROC_MEM_FILE "${_php_proc_mem_file} "
186- CACHE INTERNAL "/proc/pid/mem interface"
187- )
180+ if (PROC_MEM_FILE)
181+ message (CHECK_PASS "yes (${PROC_MEM_FILE} )" )
182+ return ()
188183endif ()
189184
190- if (HAVE_PTRACE)
191- set (PHP_TRACE_TYPE "ptrace" )
192- elseif (_php_proc_mem_file)
193- set (PHP_TRACE_TYPE "pread" )
194- elseif (HAVE_MACH_VM_READ)
195- set (PHP_TRACE_TYPE "mach" )
196- endif ()
185+ message (CHECK_FAIL "no" )
197186
198- if (PHP_TRACE_TYPE)
199- message (CHECK_PASS "${PHP_TRACE_TYPE} " )
200- else ()
201- message (CHECK_FAIL "not found" )
202- message (WARNING "FPM Trace - ptrace, pread, or mach: could not be found" )
203- endif ()
187+ message (WARNING "FPM trace - ptrace, pread, or mach: could not be found" )
0 commit comments