Patch Detail
Show a patch.
GET /api/patches/2346/?format=api
{ "id": 2346, "url": "https://patchwork.libcamera.org/api/patches/2346/?format=api", "web_url": "https://patchwork.libcamera.org/patch/2346/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20191123124302.25863-1-laurent.pinchart@ideasonboard.com>", "date": "2019-11-23T12:43:02", "name": "[libcamera-devel] libcamera: Print backtrace on fatal errors", "commit_ref": "442f516c6215aa0bbdeec4c7f2d6c406521a92fd", "pull_url": null, "state": "accepted", "archived": false, "hash": "64264ad5631976d20b84f089c42b88416ed4295f", "submitter": { "id": 2, "url": "https://patchwork.libcamera.org/api/people/2/?format=api", "name": "Laurent Pinchart", "email": "laurent.pinchart@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/2346/mbox/", "series": [ { "id": 577, "url": "https://patchwork.libcamera.org/api/series/577/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=577", "date": "2019-11-23T12:43:02", "name": "[libcamera-devel] libcamera: Print backtrace on fatal errors", "version": 1, "mbox": "https://patchwork.libcamera.org/series/577/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/2346/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/2346/checks/", "tags": {}, "headers": { "Return-Path": "<laurent.pinchart@ideasonboard.com>", "Received": [ "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1434B6136C\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 23 Nov 2019 13:43:18 +0100 (CET)", "from pendragon.ideasonboard.com (fs96f9c64d.tkyc509.ap.nuro.jp\n\t[150.249.198.77])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 7CF22440\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 23 Nov 2019 13:43:16 +0100 (CET)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1574512997;\n\tbh=IEwooAWK+6st23gE0ydFRUG5O5s7awDMmlxL+ysUBx8=;\n\th=From:To:Subject:Date:From;\n\tb=kPVGYzQZNHPuUDNoIjFelDaNuRKTCAfJlerqkiwlQn/Z1p+VG1GWBweEd4T2mSWfW\n\tiBaD1XPIhMAU+xbUQsHQkEqAh0XP2Jm2+RKA4RzqVi5yAM5I1+IR9ZobpcE/qCVMNy\n\t+UpNEJH0mqkL4q6Q9CwuYfeBZxhidP1OF5ejgsqo=", "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Sat, 23 Nov 2019 14:43:02 +0200", "Message-Id": "<20191123124302.25863-1-laurent.pinchart@ideasonboard.com>", "X-Mailer": "git-send-email 2.23.0", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH] libcamera: Print backtrace on fatal errors", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "X-List-Received-Date": "Sat, 23 Nov 2019 12:43:18 -0000" }, "content": "When a fatal error occurs the program aborts, and all the logger\nprovides is the location of the line that caused the error. Extend this\nwith a full backtrace to help debugging.\n\nThe backtrace is generated using the backtrace() call, a GNU extension\nto the C library. It is available in glibc and uClibc but not in musl.\nTest for availability of the function to condition compilation of the\nbacktrace printing. Implementing backtrace support with musl is an\nexercise left to the reader if desired.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n meson.build | 4 ++\n src/libcamera/log.cpp | 93 ++++++++++++++++++++++++++++++++++---------\n 2 files changed, 79 insertions(+), 18 deletions(-)", "diff": "diff --git a/meson.build b/meson.build\nindex 0a222ba96dcb..634488589a46 100644\n--- a/meson.build\n+++ b/meson.build\n@@ -26,6 +26,10 @@ libcamera_version = libcamera_git_version.split('+')[0]\n cc = meson.get_compiler('c')\n config_h = configuration_data()\n \n+if cc.has_header_symbol('execinfo.h', 'backtrace')\n+ config_h.set('HAVE_BACKTRACE', 1)\n+endif\n+\n if cc.has_header_symbol('stdlib.h', 'secure_getenv', prefix : '#define _GNU_SOURCE')\n config_h.set('HAVE_SECURE_GETENV', 1)\n endif\ndiff --git a/src/libcamera/log.cpp b/src/libcamera/log.cpp\nindex 50f345b98c74..f4eb8c11adc3 100644\n--- a/src/libcamera/log.cpp\n+++ b/src/libcamera/log.cpp\n@@ -7,6 +7,9 @@\n \n #include \"log.h\"\n \n+#if HAVE_BACKTRACE\n+#include <execinfo.h>\n+#endif\n #include <fstream>\n #include <iostream>\n #include <list>\n@@ -108,10 +111,11 @@ public:\n \n \tbool isValid() const;\n \tvoid write(const LogMessage &msg);\n+\tvoid write(const std::string &msg);\n \n private:\n-\tvoid writeSyslog(const LogMessage &msg);\n-\tvoid writeStream(const LogMessage &msg);\n+\tvoid writeSyslog(LogSeverity severity, const std::string &msg);\n+\tvoid writeStream(const std::string &msg);\n \n \tstd::ostream *stream_;\n \tLoggingTarget target_;\n@@ -180,34 +184,55 @@ bool LogOutput::isValid() const\n * \\param[in] msg Message to write\n */\n void LogOutput::write(const LogMessage &msg)\n+{\n+\tstd::string str;\n+\n+\tswitch (target_) {\n+\tcase LoggingTargetSyslog:\n+\t\tstr = std::string(log_severity_name(msg.severity())) + \" \"\n+\t\t + msg.category().name() + \" \" + msg.fileInfo() + \" \"\n+\t\t + msg.msg();\n+\t\twriteSyslog(msg.severity(), str);\n+\t\tbreak;\n+\tcase LoggingTargetStream:\n+\tcase LoggingTargetFile:\n+\t\tstr = \"[\" + utils::time_point_to_string(msg.timestamp()) + \"]\"\n+\t\t + log_severity_name(msg.severity()) + \" \"\n+\t\t + msg.category().name() + \" \" + msg.fileInfo() + \" \"\n+\t\t + msg.msg();\n+\t\twriteStream(str);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+}\n+\n+/**\n+ * \\brief Write string to log output\n+ * \\param[in] str String to write\n+ */\n+void LogOutput::write(const std::string &str)\n {\n \tswitch (target_) {\n \tcase LoggingTargetSyslog:\n-\t\twriteSyslog(msg);\n+\t\twriteSyslog(LogDebug, str);\n \t\tbreak;\n \tcase LoggingTargetStream:\n \tcase LoggingTargetFile:\n-\t\twriteStream(msg);\n+\t\twriteStream(str);\n \t\tbreak;\n \tdefault:\n \t\tbreak;\n \t}\n }\n \n-void LogOutput::writeSyslog(const LogMessage &msg)\n+void LogOutput::writeSyslog(LogSeverity severity, const std::string &str)\n {\n-\tstd::string str = std::string(log_severity_name(msg.severity())) + \" \" +\n-\t \t\t msg.category().name() + \" \" + msg.fileInfo() + \" \" +\n-\t\t\t msg.msg();\n-\tsyslog(log_severity_to_syslog(msg.severity()), \"%s\", str.c_str());\n+\tsyslog(log_severity_to_syslog(severity), \"%s\", str.c_str());\n }\n \n-void LogOutput::writeStream(const LogMessage &msg)\n+void LogOutput::writeStream(const std::string &str)\n {\n-\tstd::string str = \"[\" + utils::time_point_to_string(msg.timestamp()) +\n-\t\t\t \"]\" + log_severity_name(msg.severity()) + \" \" +\n-\t\t\t msg.category().name() + \" \" + msg.fileInfo() + \" \" +\n-\t\t\t msg.msg();\n \tstream_->write(str.c_str(), str.size());\n \tstream_->flush();\n }\n@@ -223,6 +248,7 @@ public:\n \tstatic Logger *instance();\n \n \tvoid write(const LogMessage &msg);\n+\tvoid backtrace();\n \n \tint logSetFile(const char *path);\n \tint logSetStream(std::ostream *stream);\n@@ -240,9 +266,6 @@ private:\n \tvoid registerCategory(LogCategory *category);\n \tvoid unregisterCategory(LogCategory *category);\n \n-\tvoid writeSyslog(const LogMessage &msg);\n-\tvoid writeStream(const LogMessage &msg);\n-\n \tstd::unordered_set<LogCategory *> categories_;\n \tstd::list<std::pair<std::string, LogSeverity>> levels_;\n \n@@ -370,6 +393,38 @@ void Logger::write(const LogMessage &msg)\n \toutput->write(msg);\n }\n \n+/**\n+ * \\brief Write a backtrace to the log\n+ */\n+void Logger::backtrace()\n+{\n+#if HAVE_BACKTRACE\n+\tstd::shared_ptr<LogOutput> output = std::atomic_load(&output_);\n+\tif (!output)\n+\t\treturn;\n+\n+\tvoid *buffer[32];\n+\tint num_entries = ::backtrace(buffer, ARRAY_SIZE(buffer));\n+\tchar **strings = backtrace_symbols(buffer, num_entries);\n+\tif (!strings)\n+\t\treturn;\n+\n+\tstd::ostringstream msg;\n+\tmsg << \"Backtrace:\" << std::endl;\n+\n+\t/*\n+\t * Skip the first two entries that correspond to this method and\n+\t * ~LogMessage().\n+\t */\n+\tfor (int i = 2; i < num_entries; ++i)\n+\t\tmsg << strings[i] << std::endl;\n+\n+\toutput->write(msg.str());\n+\n+\tfree(strings);\n+#endif\n+}\n+\n /**\n * \\brief Set the log file\n * \\param[in] path Full path to the log file\n@@ -783,8 +838,10 @@ LogMessage::~LogMessage()\n \tif (severity_ >= category_.severity())\n \t\tLogger::instance()->write(*this);\n \n-\tif (severity_ == LogSeverity::LogFatal)\n+\tif (severity_ == LogSeverity::LogFatal) {\n+\t\tLogger::instance()->backtrace();\n \t\tstd::abort();\n+\t}\n }\n \n /**\n", "prefixes": [ "libcamera-devel" ] }