Skip to content

Commit

Permalink
Add set_fatal_error_callback to public Log interface.
Browse files Browse the repository at this point in the history
GitOrigin-RevId: 3e7c3bb97d86fa753deae864fdf574de1de1aee4
  • Loading branch information
levlam committed Jan 24, 2018
1 parent 644a4ff commit 18e7b08
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 28 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ if (NOT CMAKE_CROSSCOMPILING)
target_include_directories(tg_cli SYSTEM PRIVATE ${READLINE_INCLUDE_DIR})
target_compile_definitions(tg_cli PRIVATE -DUSE_READLINE=1)
endif()
target_link_libraries(tg_cli PRIVATE memprof tdcore tdtl)
target_link_libraries(tg_cli PRIVATE memprof tdclient tdcore tdtl)
add_dependencies(tg_cli tl_generate_json)
endif()

Expand Down
16 changes: 16 additions & 0 deletions td/telegram/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ namespace td {
static FileLog file_log;
static TsLog ts_log(&file_log);
static int64 max_log_file_size = 10 << 20;
static Log::FatalErrorCallbackPtr fatal_error_callback;

static void fatal_error_callback_wrapper(CSlice message) {
CHECK(fatal_error_callback != nullptr);
fatal_error_callback(message.c_str());
}

void Log::set_file_path(string file_path) {
if (file_path.empty()) {
Expand All @@ -37,4 +43,14 @@ void Log::set_verbosity_level(int new_verbosity_level) {
SET_VERBOSITY_LEVEL(VERBOSITY_NAME(FATAL) + new_verbosity_level);
}

void Log::set_fatal_error_callback(FatalErrorCallbackPtr callback) {
if (callback == nullptr) {
fatal_error_callback = nullptr;
set_log_fatal_error_callback(nullptr);
} else {
fatal_error_callback = callback;
set_log_fatal_error_callback(fatal_error_callback_wrapper);
}
}

} // namespace td
18 changes: 18 additions & 0 deletions td/telegram/Log.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,24 @@ class Log {
* value greater than 5 and up to 1024 can be used to enable even more logging.
*/
static void set_verbosity_level(int new_verbosity_level);

/**
* A type of callback function that will be called when a fatal error happens.
*
* \param error_message Null-terminated string with a description of a happened fatal error.
*/
using FatalErrorCallbackPtr = void (*)(const char *error_message);

/**
* Sets the callback that will be called when a fatal error happens.
* None of the TDLib methods can be called from the callback.
* The TDLib will crash as soon as callback returns.
* By default the callback is not set.
*
* \param[in] callback Callback that will be called when a fatal error happens.
* Pass nullptr to remove the callback.
*/
static void set_fatal_error_callback(FatalErrorCallbackPtr callback);
};

} // namespace td
27 changes: 19 additions & 8 deletions td/telegram/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include "td/telegram/ClientActor.h"
#include "td/telegram/Log.h"

#include "td/telegram/td_api_json.h"

Expand Down Expand Up @@ -42,6 +43,7 @@
#include <cstdlib>
#include <cstring> // for strcmp
#include <ctime>
#include <iostream>
#include <limits>
#include <memory>
#include <queue>
Expand All @@ -56,7 +58,7 @@

namespace td {

void dump_memory_usage() {
static void dump_memory_usage() {
if (is_memprof_on()) {
LOG(WARNING) << "memory_dump";
clear_thread_locals();
Expand Down Expand Up @@ -87,7 +89,7 @@ static int32 saved_point;
static string saved_line;
static std::atomic_flag readline_lock = ATOMIC_FLAG_INIT;

void deactivate_readline() {
static void deactivate_readline() {
while (readline_lock.test_and_set(std::memory_order_acquire)) {
// spin
}
Expand All @@ -100,7 +102,7 @@ void deactivate_readline() {
rl_redisplay();
}

void reactivate_readline() {
static void reactivate_readline() {
rl_set_prompt(prompt);
rl_replace_line(saved_line.c_str(), 0);
rl_point = saved_point;
Expand All @@ -109,7 +111,7 @@ void reactivate_readline() {
readline_lock.clear(std::memory_order_release);
}

char *command_generator(const char *text, int state) {
static char *command_generator(const char *text, int state) {
static vector<CSlice> commands{"GetContacts",
"GetChats",
"GetHistory",
Expand Down Expand Up @@ -162,7 +164,7 @@ char *command_generator(const char *text, int state) {
return nullptr;
}

char **tg_cli_completion(const char *text, int start, int end) {
static char **tg_cli_completion(const char *text, int start, int end) {
char **matches = nullptr;
if (start == 0) {
matches = rl_completion_matches(text, command_generator);
Expand Down Expand Up @@ -2751,6 +2753,10 @@ class CliClient final : public Actor {
quit();
} else if (op == "dnq" || op == "DumpNetQueries") {
dump_pending_network_queries();
} else if (op == "fatal") {
LOG(FATAL) << "Fatal!";
} else if (op == "unreachable") {
UNREACHABLE();
} else {
op_not_found_count++;
}
Expand Down Expand Up @@ -2864,26 +2870,31 @@ class CliClient final : public Actor {
};
CliClient *CliClient::instance_ = nullptr;

void quit() {
static void quit() {
CliClient::quit_instance();
}

void fail_signal(int sig) {
static void fail_signal(int sig) {
signal_safe_write_signal_number(sig);
while (true) {
// spin forever to allow debugger to attach
}
}

void usage() {
static void usage() {
//TODO:
}

static void on_fatal_error(const char *error) {
std::cerr << "Fatal error: " << error << std::endl;
}

void main(int argc, char **argv) {
ignore_signal(SignalType::HangUp).ensure();
ignore_signal(SignalType::Pipe).ensure();
set_signal_handler(SignalType::Error, fail_signal).ensure();
set_signal_handler(SignalType::Abort, fail_signal).ensure();
td::Log::set_fatal_error_callback(on_fatal_error);

CliLog cli_log;
log_interface = &cli_log;
Expand Down
6 changes: 6 additions & 0 deletions td/telegram/td_log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#include "td/telegram/Log.h"

#include <cstdint>

void td_set_log_file_path(const char *file_path) {
td::Log::set_file_path(file_path == nullptr ? "" : file_path);
}
Expand All @@ -19,3 +21,7 @@ void td_set_log_max_file_size(long long max_file_size) {
void td_set_log_verbosity_level(int new_verbosity_level) {
td::Log::set_verbosity_level(new_verbosity_level);
}

void td_set_log_fatal_error_callback(td_log_fatal_error_callback_ptr callback) {
td::Log::set_fatal_error_callback(callback);
}
22 changes: 20 additions & 2 deletions td/telegram/td_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ extern "C" {
* By default TDLib writes logs to stderr or an OS specific log.
* Use this method to write the log to a file instead.
*
* \param[in] file_path Path to a file where the internal TDLib log will be written. Use an empty path to
* switch back to the default logging behaviour.
* \param[in] file_path Null-terminated path to a file where the internal TDLib log will be written.
* Use an empty path to switch back to the default logging behaviour.
*/
TDJSON_EXPORT void td_set_log_file_path(const char *file_path);

Expand Down Expand Up @@ -52,6 +52,24 @@ TDJSON_EXPORT void td_set_log_max_file_size(long long max_file_size);
*/
TDJSON_EXPORT void td_set_log_verbosity_level(int new_verbosity_level);

/**
* A type of callback function that will be called when a fatal error happens.
*
* \param error_message Null-terminated string with a description of a happened fatal error.
*/
using td_log_fatal_error_callback_ptr = void (*)(const char *error_message);

/**
* Sets the callback that will be called when a fatal error happens.
* None of the TDLib methods can be called from the callback.
* The TDLib will crash as soon as callback returns.
* By default the callback is not set.
*
* \param[in] callback Callback that will be called when a fatal error happens.
* Pass NULL to remove the callback.
*/
TDJSON_EXPORT void td_set_log_fatal_error_callback(td_log_fatal_error_callback_ptr callback);

#ifdef __cplusplus
} // extern "C"
#endif
1 change: 1 addition & 0 deletions tdclientjson_export_list
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ _td_json_client_execute
_td_set_log_file_path
_td_set_log_max_file_size
_td_set_log_verbosity_level
_td_set_log_fatal_error_callback
13 changes: 6 additions & 7 deletions tdutils/td/utils/FileLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "td/utils/port/path.h"
#include "td/utils/Slice.h"

#include <cstdlib>
#include <limits>

namespace td {
Expand All @@ -23,25 +22,25 @@ class FileLog : public LogInterface {
static constexpr int DEFAULT_ROTATE_THRESHOLD = 10 * (1 << 20);

public:
void append(CSlice xslice, int log_level) override {
Slice slice = xslice;
void append(CSlice cslice, int log_level) override {
Slice slice = cslice;
while (!slice.empty()) {
auto r_size = fd_.write(slice);
if (r_size.is_error()) {
std::abort();
process_fatal_error(r_size.error().message());
}
auto written = r_size.ok();
size_ += static_cast<int64>(written);
slice.remove_prefix(written);
}
if (log_level == VERBOSITY_NAME(FATAL)) {
std::abort();
process_fatal_error(cslice);
}

if (size_ > rotate_threshold_) {
auto status = rename(path_, path_ + ".old");
if (status.is_error()) {
std::abort();
process_fatal_error(status.message());
}
do_rotate();
}
Expand Down Expand Up @@ -83,7 +82,7 @@ class FileLog : public LogInterface {
fd_.close();
auto r_fd = FileFd::open(path_, FileFd::Create | FileFd::Truncate | FileFd::Write);
if (r_fd.is_error()) {
std::abort();
process_fatal_error(r_fd.error().message());
}
fd_ = r_fd.move_as_ok();
Fd::duplicate(fd_.get_fd(), Fd::Stderr()).ignore();
Expand Down
4 changes: 4 additions & 0 deletions tdutils/td/utils/MemoryLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ class MemoryLog : public LogInterface {
size_t printed = std::snprintf(&buffer_[start_pos + 1], magic_size - 1, "LOG:%08x: ", real_pos);
CHECK(printed == magic_size - 2);
buffer_[start_pos + magic_size - 1] = ' ';

if (log_level == VERBOSITY_NAME(FATAL)) {
process_fatal_error(new_slice);
}
}

void rotate() override {
Expand Down
21 changes: 15 additions & 6 deletions tdutils/td/utils/logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,7 @@ class DefaultLog : public LogInterface {
TsCerr() << slice;
#endif
if (log_level == VERBOSITY_NAME(FATAL)) {
auto f = default_log_on_fatal_error;
if (f) {
f(slice);
}
std::abort();
process_fatal_error(slice);
}
}
void rotate() override {
Expand All @@ -230,6 +226,19 @@ static DefaultLog default_log;

LogInterface *const default_log_interface = &default_log;
LogInterface *log_interface = default_log_interface;
OnFatalErrorF default_log_on_fatal_error = nullptr;

static OnFatalErrorCallback on_fatal_error_callback = nullptr;

void set_log_fatal_error_callback(OnFatalErrorCallback callback) {
on_fatal_error_callback = callback;
}

void process_fatal_error(CSlice message) {
auto callback = on_fatal_error_callback;
if (callback) {
callback(message);
}
std::abort();
}

} // namespace td
10 changes: 6 additions & 4 deletions tdutils/td/utils/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include "td/utils/StringBuilder.h"

#include <atomic>
#include <cstdlib>
#include <type_traits>

#define PSTR_IMPL(...) ::td::Logger(::td::NullLog().ref(), 0, true).printf(__VA_ARGS__)
Expand Down Expand Up @@ -98,7 +97,7 @@ inline bool no_return_func() {

#define UNREACHABLE(...) \
LOG(FATAL, __VA_ARGS__); \
std::abort()
::td::process_fatal_error("Unreachable in " __FILE__ " at " TD_DEFINE_STR(__LINE__))

constexpr int VERBOSITY_NAME(PLAIN) = -1;
constexpr int VERBOSITY_NAME(FATAL) = 0;
Expand Down Expand Up @@ -148,8 +147,11 @@ class NullLog : public LogInterface {

extern LogInterface *const default_log_interface;
extern LogInterface *log_interface;
typedef void (*OnFatalErrorF)(CSlice msg);
extern OnFatalErrorF default_log_on_fatal_error;

using OnFatalErrorCallback = void (*)(CSlice message);
void set_log_fatal_error_callback(OnFatalErrorCallback callback);

[[noreturn]] void process_fatal_error(CSlice message);

#define TC_RED "\e[1;31m"
#define TC_BLUE "\e[1;34m"
Expand Down

0 comments on commit 18e7b08

Please sign in to comment.