2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
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 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_REQUEST_INJECTION_DATA_H_
18 #define incl_HPHP_REQUEST_INJECTION_DATA_H_
20 #include "hphp/runtime/base/rds-header.h"
21 #include "hphp/runtime/base/surprise-flags.h"
22 #include "hphp/runtime/vm/async-flow-stepper.h"
23 #include "hphp/runtime/vm/pc-filter.h"
35 # include <dispatch/dispatch.h>
36 #elif defined(_MSC_VER)
38 # include <ppltasks.h>
43 //////////////////////////////////////////////////////////////////////
45 struct RequestInjectionData
;
47 //////////////////////////////////////////////////////////////////////
50 friend struct RequestInjectionData
;
52 #if defined(__APPLE__) || defined(_MSC_VER)
53 RequestTimer(RequestInjectionData
*);
55 RequestTimer(RequestInjectionData
*, clockid_t
);
60 void setTimeout(int seconds
);
62 int getRemainingTime() const;
65 RequestInjectionData
* m_reqInjectionData
;
66 int m_timeoutSeconds
{0};
68 #if defined(__APPLE__)
69 void cancelTimerSource();
70 dispatch_source_t m_timerSource
{nullptr};
71 dispatch_group_t m_timerGroup
;
72 #elif defined(_MSC_VER)
73 concurrency::task_completion_event
<void>* m_tce
{nullptr};
75 clockid_t m_clockType
;
77 TYPE_SCAN_IGNORE_FIELD(m_timerId
); // timer_t is void*
79 /* Whether we've created our timer yet. */
80 bool m_hasTimer
{false};
82 /* Set true when we activate a timer, cleared when the signal handler runs. */
83 std::atomic
<bool> m_timerActive
{false};
87 //////////////////////////////////////////////////////////////////////
90 * General-purpose bag of data and options for a request.
92 * This class contains a lot of debugger data that must be accessed via getter
93 * and setter methods. Updating data like the "debugger attached" field
94 * dynamically affects whether the request will use the JIT or not.
96 * Refrain from adding more fields to this class if you can help it. It's a
97 * better idea to add request local data to whatever extension you're working
100 struct RequestInjectionData
{
101 /* The state of the step out command. */
102 enum class StepOutState
: int8_t {
103 /* Command is inactive. */
105 /* Waiting for the corresponding function to exit. */
107 /* We have stepped out and will break on the next valid opcode. */
111 RequestInjectionData()
112 #if defined(__APPLE__) || defined(_MSC_VER)
116 : m_timer(this, CLOCK_REALTIME
)
117 , m_cpuTimer(this, CLOCK_THREAD_CPUTIME_ID
)
121 ~RequestInjectionData() = default;
123 static constexpr uint32_t debuggerReadOnlyOffset() {
124 return offsetof(RequestInjectionData
, m_debuggerAttached
);
129 void onSessionInit();
133 int getTimeout() const;
134 void setTimeout(int seconds
);
136 int getCPUTimeout() const;
137 void setCPUTimeout(int seconds
);
139 int getRemainingTime() const;
140 int getRemainingCPUTime() const;
142 void resetTimer(int seconds
= 0);
143 void resetCPUTimer(int seconds
= 0);
145 void onTimeout(RequestTimer
*);
148 * Intended to be used by threads other than the current thread. To get
149 * surprise flags for the current thread, use stackLimitAndSurprise() instead.
151 void clearFlag(SurpriseFlag
);
152 void setFlag(SurpriseFlag
);
155 * Whether the JIT is enabled.
161 * Whether the JIT is performing function folding.
163 bool getJitFolding() const;
164 void setJitFolding(bool);
167 * Whether to suppress the emission of Hack array compat notices.
169 bool getSuppressHackArrayCompatNotices() const;
170 void setSuppressHackArrayCompatNotices(bool);
173 * Whether coverage is being collected.
175 bool getCoverage() const;
176 void setCoverage(bool);
179 * Whether there is a debugger attached to the request. Controlled by
180 * DebuggerHook. This field gets read directly by JIT'd code.
182 bool getDebuggerAttached();
183 void setDebuggerAttached(bool);
186 * Returns true if the debugger should force interrupts due to any of the
187 * debugger interrupt conditions being true.
189 bool getDebuggerForceIntr() const;
192 * Indicating we should force interrupts for debuggers. This is intended to
193 * be used by debuggers for forcing onOpcode events.
195 bool getDebuggerIntr() const;
196 void setDebuggerIntr(bool);
199 * Whether the debugger is running a "step in" command.
201 bool getDebuggerStepIn() const;
202 void setDebuggerStepIn(bool);
205 * Whether the debugger is running a "next" command.
207 bool getDebuggerNext() const;
208 void setDebuggerNext(bool);
211 * Whether the debugger is running a "step out" command, and where it is in
214 StepOutState
getDebuggerStepOut() const;
215 void setDebuggerStepOut(StepOutState
);
218 * The stack depth registered by the debugger's most recent flow command.
219 * (e.g. step, next, etc.)
221 int getDebuggerFlowDepth() const;
222 void setDebuggerFlowDepth(int);
225 * Set to a line number if the request has hit a line breakpoint on the line,
226 * and hasn't left that line yet. This tracks a single line per stack frame.
227 * If there's no tracked line, then it is treated as line number -1.
229 int getActiveLineBreak() const;
230 void clearActiveLineBreak();
231 void setActiveLineBreak(int);
234 * Adds a slot to the active line stack upon entering or leaving a function.
236 void popActiveLineBreak();
237 void pushActiveLineBreak();
240 * Uses the active line break stack to compute the size of the stack when in
243 size_t getDebuggerStackDepth() const;
245 /* Getters and setters for user settable INI settings. */
247 const std::string
& getDefaultMimeType() const;
249 std::string
getDefaultIncludePath();
250 const std::vector
<std::string
>& getIncludePaths() const;
252 int64_t getErrorReportingLevel();
253 void setErrorReportingLevel(int64_t);
255 int64_t getMemoryLimitNumeric() const;
256 void setMemoryLimit(folly::StringPiece
);
258 const std::string
& getVariablesOrder() const;
259 void setVariablesOrder(const std::string
&);
261 const std::string
& getRequestOrder() const;
262 void setRequestOrder(const std::string
&);
264 int64_t getSocketDefaultTimeout() const;
266 const std::string
& getUserAgent() const;
267 void setUserAgent(const std::string
&);
269 const std::string
& getTimeZone() const;
270 void setTimeZone(const std::string
&);
272 bool setAllowedDirectories(const std::string
& value
);
274 const std::vector
<std::string
>& getAllowedDirectoriesProcessed() const;
276 // When safe file access is enabled only whitelisted by setAllowedDirectories
278 void setSafeFileAccess(bool b
);
279 bool hasSafeFileAccess() const;
280 bool hasTrackErrors() const;
281 bool hasHtmlErrors() const;
283 bool logFunctionCalls() const;
286 RequestTimer m_timer
;
287 RequestTimer m_cpuTimer
;
289 bool m_debuggerAttached
{false};
290 bool m_coverage
{false};
292 bool m_jitFolding
{false};
293 bool m_debuggerIntr
{false};
294 bool m_suppressHackArrayCompatNotices
{false};
296 bool m_debuggerStepIn
{false};
297 bool m_debuggerNext
{false};
298 StepOutState m_debuggerStepOut
{StepOutState::None
};
301 PCFilter m_breakPointFilter
;
302 PCFilter m_flowFilter
;
303 PCFilter m_lineBreakPointFilter
;
304 PCFilter m_callBreakPointFilter
;
305 PCFilter m_retBreakPointFilter
;
306 // Only allow one async stepper at a time.
307 AsyncFlowStepper m_asyncStepper
;
310 int m_debuggerFlowDepth
{0};
313 bool m_logErrors
{false};
314 bool m_trackErrors
{false};
315 bool m_htmlErrors
{false};
316 bool m_safeFileAccess
{false};
317 bool m_logFunctionCalls
{false};
319 /* Pointer to surprise flags stored in RDS. */
320 std::atomic
<size_t>* m_sflagsAndStkPtr
{nullptr};
322 std::stack
<int> m_activeLineBreaks
;
324 /* Things corresponding to user settable INI settings. */
326 std::string m_maxMemory
;
327 std::string m_argSeparatorOutput
;
328 std::string m_argSeparatorInput
;
329 std::string m_variablesOrder
;
330 std::string m_requestOrder
;
331 std::string m_defaultCharset
;
332 std::string m_defaultMimeType
;
333 std::string m_brotliEnabled
;
334 std::string m_brotliChunkedEnabled
;
335 std::string m_gzipCompressionLevel
= "-1";
336 std::string m_gzipCompression
;
337 std::string m_errorLog
;
338 std::string m_userAgent
;
339 std::string m_timezone
;
340 std::vector
<std::string
> m_include_paths
;
341 struct AllowedDirectoriesInfo
{
342 AllowedDirectoriesInfo(std::vector
<std::string
>&& v
,
344 vec(std::move(v
)), string(std::move(s
)) {}
345 std::vector
<std::string
> vec
;
348 std::unique_ptr
<AllowedDirectoriesInfo
> m_allowedDirectoriesInfo
;
349 int64_t m_errorReportingLevel
;
350 int64_t m_socketDefaultTimeout
;
351 int64_t m_maxMemoryNumeric
;
352 int64_t m_zendAssertions
;
353 int64_t m_brotliLgWindowSize
;
354 int64_t m_brotliQuality
;
357 * Keep track of the open_basedir_separator that may be used so we can
358 * have backwards compatibility with our current ;.
359 * This is a simple fix with the caveat that we don't mix the characters
360 * in an ini file or ini_set().
361 * Moving forward we should just use s_PATH_SEPARATOR and support only that
363 std::string m_open_basedir_separator
;
366 /* CmdInterrupts this thread is handling. */
367 std::stack
<void*> interrupts
;
370 //////////////////////////////////////////////////////////////////////
374 #define incl_HPHP_REQUEST_INJECTION_DATA_INL_H_
375 #include "hphp/runtime/base/request-injection-data-inl.h"
376 #undef incl_HPHP_REQUEST_INJECTION_DATA_INL_H_