Arquivos
hhvm/hphp/runtime/ext/ext_error.cpp
T
huzhiguang 506329b7ce error_log add message_type=3 function
add f_error_log message_type=3 function
hhvm defult error_log message_type 0,so it can't support user-defind error_log mode(message_type=3)

Closes #831

Github: https://github.com/facebook/hiphop-php/pull/831
2013-07-18 17:28:41 -07:00

245 linhas
7.9 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 1997-2010 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include "hphp/runtime/ext/ext_error.h"
#include "hphp/runtime/base/exceptions.h"
#include "hphp/runtime/base/string_buffer.h"
#include "hphp/runtime/ext/ext_file.h"
#include "hphp/util/logger.h"
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
const int DEBUG_BACKTRACE_PROVIDE_OBJECT = 1;
const int DEBUG_BACKTRACE_IGNORE_ARGS = 2;
Array f_debug_backtrace(int64_t options /* = 1 */, int64_t limit /* = 0 */) {
bool provide_object = options & DEBUG_BACKTRACE_PROVIDE_OBJECT;
bool ignore_args = options & DEBUG_BACKTRACE_IGNORE_ARGS;
return g_vmContext->debugBacktrace(
true, false, provide_object, nullptr, ignore_args, limit
);
}
/**
* hphp_debug_caller_info - returns an array of info about the "caller"
*
* For clarity, we refer to the function that called hphp_debug_caller_info()
* as the "callee", and we refer to the function that called the callee as
* the "caller".
*
* This function returns an array containing two keys "file" and "line" which
* indicate the the filename and line number where the "caller" called the
* "callee".
*/
Array f_hphp_debug_caller_info() {
if (RuntimeOption::InjectedStackTrace) {
return g_vmContext->getCallerInfo();
}
return Array::Create();
}
void f_debug_print_backtrace(int64_t options /* = 0 */,
int64_t limit /* = 0 */) {
bool ignore_args = options & DEBUG_BACKTRACE_IGNORE_ARGS;
echo(debug_string_backtrace(true, ignore_args, limit));
}
const StaticString
s_class("class"),
s_type("type"),
s_function("function"),
s_file("file"),
s_line("line"),
s_message("message"),
s_args("args");
String debug_string_backtrace(bool skip, bool ignore_args /* = false */,
int limit /* = 0 */) {
if (RuntimeOption::InjectedStackTrace) {
Array bt;
StringBuffer buf;
bt = g_vmContext->debugBacktrace(skip, false, false, nullptr,
ignore_args, limit);
int i = 0;
for (ArrayIter it = bt.begin(); !it.end(); it.next(), i++) {
Array frame = it.second().toArray();
buf.append('#');
buf.append(i);
if (i < 10) buf.append(' ');
buf.append(' ');
if (frame.exists(s_class)) {
buf.append(frame->get(s_class).toString());
buf.append(frame->get(s_type).toString());
}
buf.append(frame->get(s_function).toString());
buf.append("(");
if (!ignore_args) {
bool first = true;
for (ArrayIter it = frame->get(s_args).begin(); !it.end(); it.next()) {
if (!first) {
buf.append(", ");
} else {
first = false;
}
buf.append(it.second().toString());
}
}
buf.append(")");
if (frame.exists(s_file)) {
buf.append(" called at [");
buf.append(frame->get(s_file).toString());
buf.append(':');
buf.append(frame->get(s_line).toString());
buf.append(']');
}
buf.append('\n');
}
return buf.detach();
} else {
StackTrace st;
return String(st.toString());
}
}
Array f_error_get_last() {
String lastError = g_context->getLastError();
if (lastError.isNull()) {
return (ArrayData *)NULL;
}
return CREATE_MAP2(s_message, g_context->getLastError(),
s_type, g_context->getLastErrorNumber());
}
bool f_error_log(CStrRef message, int message_type /* = 0 */,
CStrRef destination /* = null_string */,
CStrRef extra_headers /* = null_string */) {
// error_log() should not invoke the user error handler,
// so we use Logger::Error() instead of raise_warning() or raise_error()
switch (message_type) {
case 0:
{
std::string line(message.data(),
// Truncate to 512k
message.size() > (1<<19) ? (1<<19) : message.size());
Logger::Error(line);
if (!RuntimeOption::ServerExecutionMode() &&
Logger::UseLogFile && Logger::Output) {
// otherwise errors will go to error log without displaying on screen
std::cerr << line;
}
return true;
}
case 3:
{
Variant outfile = f_fopen(destination, "a"); // open for append only
if (outfile.isNull()) {
Logger::Error("can't open error_log file!\n");
return false;
}
f_fwrite(outfile.toObject(), message);
f_fclose(outfile.toObject());
return true;
}
case 2: // not used per PHP
default:
Logger::Error("error_log does not support message_type %d!", message_type);
break;
}
return false;
}
int64_t f_error_reporting(CVarRef level /* = null */) {
int oldErrorReportingLevel = g_context->getErrorReportingLevel();
if (!level.isNull()) {
g_context->setErrorReportingLevel(level.toInt32());
}
return oldErrorReportingLevel;
}
bool f_restore_error_handler() {
g_context->popUserErrorHandler();
return true;
}
bool f_restore_exception_handler() {
g_context->popUserExceptionHandler();
return false;
}
Variant f_set_error_handler(CVarRef error_handler,
int error_types /* = k_E_ALL */) {
return g_context->pushUserErrorHandler(error_handler, error_types);
}
Variant f_set_exception_handler(CVarRef exception_handler) {
return g_context->pushUserExceptionHandler(exception_handler);
}
void f_hphp_set_error_page(CStrRef page) {
g_context->setErrorPage(page);
}
void f_hphp_throw_fatal_error(CStrRef error_msg) {
std::string msg = error_msg.data();
raise_error(msg);
}
void f_hphp_clear_unflushed() {
g_context->obEndAll();
g_context->obStart();
g_context->obProtect(true);
}
bool f_trigger_error(CStrRef error_msg,
int error_type /* = k_E_USER_NOTICE */) {
std::string msg = error_msg.data();
if (g_context->getThrowAllErrors()) throw error_type;
if (error_type == k_E_USER_ERROR) {
g_context->handleError(msg, error_type, true,
ExecutionContext::ErrorThrowMode::IfUnhandled,
"HipHop Recoverable error: ");
} else if (error_type == k_E_USER_WARNING) {
g_context->handleError(msg, error_type, true,
ExecutionContext::ErrorThrowMode::Never,
"HipHop Warning: ");
} else if (error_type == k_E_USER_NOTICE) {
g_context->handleError(msg, error_type, true,
ExecutionContext::ErrorThrowMode::Never,
"HipHop Notice: ");
} else if (error_type == k_E_USER_DEPRECATED) {
g_context->handleError(msg, error_type, true,
ExecutionContext::ErrorThrowMode::Never,
"HipHop Deprecated: ");
} else {
return false;
}
return true;
}
bool f_user_error(CStrRef error_msg, int error_type /* = k_E_USER_NOTICE */) {
return f_trigger_error(error_msg, error_type);
}
const int64_t k_DEBUG_BACKTRACE_PROVIDE_OBJECT = 1;
const int64_t k_DEBUG_BACKTRACE_IGNORE_ARGS = 2;
///////////////////////////////////////////////////////////////////////////////
}