[{"id":19886,"web_url":"https://patchwork.libcamera.org/comment/19886/","msgid":"<dbf8dc14af5d188c0f3c5cedea82b48e3f9326e4.camel@ndufresne.ca>","date":"2021-09-27T14:01:15","subject":"Re: [libcamera-devel] [PATCH v1 2/4] libcamera: base: backtrace:\n\tUse libdw to provide symbolic names","submitter":{"id":30,"url":"https://patchwork.libcamera.org/api/people/30/","name":"Nicolas Dufresne","email":"nicolas@ndufresne.ca"},"content":"Le vendredi 24 septembre 2021 à 13:23 +0300, Laurent Pinchart a écrit :\n> libdw provides access to debugging information. This allows creating\n> better stack trace entries, with file names and line numbers, but also\n> with demangled symbols as the symbol name is available and can be passed\n> to abi::__cxa_demangle().\n> \n> With libdw, the backtrace previously generated by backtrace_symbols()\n> \n> src/cam/../libcamera/libcamera.so(_ZN9libcamera14VimcCameraData4initEv+0xbd) [0x7f7dbb73222d]\n> src/cam/../libcamera/libcamera.so(_ZN9libcamera19PipelineHandlerVimc5matchEPNS_16DeviceEnumeratorE+0x3e0) [0x7f7dbb731c40]\n> src/cam/../libcamera/libcamera.so(_ZN9libcamera13CameraManager7Private22createPipelineHandlersEv+0x1a7) [0x7f7dbb5ea027]\n> src/cam/../libcamera/libcamera.so(_ZN9libcamera13CameraManager7Private4initEv+0x98) [0x7f7dbb5e9dc8]\n> src/cam/../libcamera/libcamera.so(_ZN9libcamera13CameraManager7Private3runEv+0x9f) [0x7f7dbb5e9c5f]\n> src/cam/../libcamera/base/libcamera-base.so(_ZN9libcamera6Thread11startThreadEv+0xee) [0x7f7dbb3e95be]\n> src/cam/../libcamera/base/libcamera-base.so(+0x4f9d7) [0x7f7dbb3ec9d7]\n> src/cam/../libcamera/base/libcamera-base.so(+0x4f90e) [0x7f7dbb3ec90e]\n> src/cam/../libcamera/base/libcamera-base.so(+0x4f2c2) [0x7f7dbb3ec2c2]\n> /lib64/libpthread.so.0(+0x7e8e) [0x7f7dbab65e8e]\n> /lib64/libc.so.6(clone+0x3f) [0x7f7dbb10b26f]\n> \n> becomes\n> \n> libcamera::VimcCameraData::init()+0xbd (src/libcamera/libcamera.so [0x00007f9de605b22d])\n> libcamera::PipelineHandlerVimc::match(libcamera::DeviceEnumerator*)+0x3e0 (src/libcamera/libcamera.so [0x00007f9de605ac40])\n> libcamera::CameraManager::Private::createPipelineHandlers()+0x1a7 (src/libcamera/libcamera.so [0x00007f9de5f13027])\n> libcamera::CameraManager::Private::init()+0x98 (src/libcamera/libcamera.so [0x00007f9de5f12dc8])\n> libcamera::CameraManager::Private::run()+0x9f (src/libcamera/libcamera.so [0x00007f9de5f12c5f])\n> libcamera::Thread::startThread()+0xee (src/libcamera/base/libcamera-base.so [0x00007f9de5d125be])\n> decltype(*(std::__1::forward<libcamera::Thread*>(fp0)).*fp()) std::__1::__invoke<void (libcamera::Thread::*)(), libcamera::Thread*, void>(void (libcamera::Thread::*&&)(), libcamera::Thread*&&)+0x77 (src/libcamera/base/libcamera-base.so [0x00007f9de5d159d7])\n> void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*, 2ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*>&, std::__1::__tuple_indices<2ul>)+0x3e (src/libcamera/base/libcamera-base.so [0x00007f9de5d1590e])\n> void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*> >(void*)+0x62 (src/libcamera/base/libcamera-base.so [0x00007f9de5d152c2])\n> start_thread+0xde (/var/tmp/portage/sys-libs/glibc-2.33-r1/work/glibc-2.33/nptl/pthread_create.c:482)\n> __clone+0x3f (../sysdeps/unix/sysv/linux/x86_64/clone.S:97)\n> \n> The stack entries related to libcamera are missing source file name and\n> line information, which will be investigated separately, but this is\n> still an improvement.\n> \n> Use libdw when available, falling back to backtrace_symbols() otherwise,\n> or if libdw fails for any reason.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  src/libcamera/base/backtrace.cpp | 120 +++++++++++++++++++++++++++++++\n>  src/libcamera/base/meson.build   |   7 ++\n>  2 files changed, 127 insertions(+)\n> \n> diff --git a/src/libcamera/base/backtrace.cpp b/src/libcamera/base/backtrace.cpp\n> index 913f7ba71b03..011f2e428d5d 100644\n> --- a/src/libcamera/base/backtrace.cpp\n> +++ b/src/libcamera/base/backtrace.cpp\n> @@ -12,9 +12,16 @@\n>  #include <stdlib.h>\n>  #endif\n>  \n> +#ifdef HAVE_DW\n> +#include <cxxabi.h>\n> +#include <elfutils/libdwfl.h>\n> +#include <unistd.h>\n> +#endif\n> +\n>  #include <sstream>\n>  \n>  #include <libcamera/base/span.h>\n> +#include <libcamera/base/utils.h>\n>  \n>  /**\n>   * \\file backtrace.h\n> @@ -23,6 +30,101 @@\n>  \n>  namespace libcamera {\n>  \n> +namespace {\n> +\n> +#if HAVE_DW\n> +class DwflParser\n> +{\n> +public:\n> +\tDwflParser();\n> +\t~DwflParser();\n> +\n> +\tbool isValid() const { return valid_; }\n> +\tstd::string stackEntry(const void *ip);\n> +\n> +private:\n> +\tDwfl_Callbacks callbacks_;\n> +\tDwfl *dwfl_;\n> +\tbool valid_;\n> +};\n> +\n> +DwflParser::DwflParser()\n> +\t: callbacks_({}), dwfl_(nullptr), valid_(false)\n> +{\n> +\tcallbacks_.find_elf = dwfl_linux_proc_find_elf;\n> +\tcallbacks_.find_debuginfo = dwfl_standard_find_debuginfo;\n> +\n> +\tdwfl_ = dwfl_begin(&callbacks_);\n> +\tif (!dwfl_)\n> +\t\treturn;\n> +\n> +\tint ret = dwfl_linux_proc_report(dwfl_, getpid());\n> +\tif (ret)\n> +\t\treturn;\n> +\n> +\tret = dwfl_report_end(dwfl_, nullptr, nullptr);\n> +\tif (ret)\n> +\t\treturn;\n> +\n> +\tvalid_ = true;\n> +}\n> +\n> +DwflParser::~DwflParser()\n> +{\n> +\tif (dwfl_)\n> +\t\tdwfl_end(dwfl_);\n> +}\n> +\n> +std::string DwflParser::stackEntry(const void *ip)\n> +{\n> +\tDwarf_Addr addr = reinterpret_cast<Dwarf_Addr>(ip);\n> +\n> +\tDwfl_Module *module = dwfl_addrmodule(dwfl_, addr);\n> +\tif (!module)\n> +\t\treturn std::string();\n> +\n> +\tstd::ostringstream entry;\n> +\n> +\tGElf_Off offset;\n> +\tGElf_Sym sym;\n> +\tconst char *symbol = dwfl_module_addrinfo(module, addr, &offset, &sym,\n> +\t\t\t\t\t\t  nullptr, nullptr, nullptr);\n> +\tif (symbol) {\n> +\t\tchar *name = abi::__cxa_demangle(symbol, nullptr, nullptr, nullptr);\n\nA suggestion, and yes, you have to choose between memory safety and ugly code.\n\n                std::unique_ptr<char[], decltype(free)*>{\n\t\t\tabi::__cxa_demangle(symbol, nullptr, nullptr, nullptr),\n\t\t\tfree};\n\nThis is needed as by default C++ will assume that delete[] is to be used rather\nthen free.\n\n> +\t\tentry << (name ? name : symbol) << \"+0x\" << std::hex << offset\n> +\t\t      << std::dec;\n> +\t\tfree(name);\n\nAnd this error prone free is not longer needed, since you have a smart pointer.\n\n> +\t} else {\n> +\t\tentry << \"??? [\" << utils::hex(addr) << \"]\";\n> +\t}\n> +\n> +\tentry << \" (\";\n> +\n> +\tDwfl_Line *line = dwfl_module_getsrc(module, addr);\n> +\tif (line) {\n> +\t\tconst char *filename;\n> +\t\tint lineNumber = 0;\n> +\n> +\t\tfilename = dwfl_lineinfo(line, &addr, &lineNumber, nullptr,\n> +\t\t\t\t\t nullptr, nullptr);\n> +\n> +\t\tentry << (filename ? filename : \"???\") << \":\" << lineNumber;\n> +\t} else {\n> +\t\tconst char *filename = nullptr;\n> +\n> +\t\tdwfl_module_info(module, nullptr, nullptr, nullptr, nullptr,\n> +\t\t\t\t nullptr, &filename, nullptr);\n> +\n> +\t\tentry << (filename ? filename : \"???\") << \" [\" << utils::hex(addr) << \"]\";\n> +\t}\n> +\n> +\tentry << \")\";\n> +\treturn entry.str();\n> +}\n> +#endif /* HAVE_DW */\n> +\n> +} /* namespace */\n> +\n>  /**\n>   * \\class Backtrace\n>   * \\brief Representation of a call stack backtrace\n> @@ -85,6 +187,24 @@ std::string Backtrace::toString(unsigned int skipLevels) const\n>  \tif (backtrace_.size() <= skipLevels)\n>  \t\treturn std::string();\n>  \n> +#if HAVE_DW\n> +\tDwflParser dwfl;\n> +\n> +\tif (dwfl.isValid()) {\n> +\t\tstd::ostringstream msg;\n> +\n> +\t\tSpan<void *const> trace{ backtrace_ };\n> +\t\tfor (const void *ip : trace.subspan(skipLevels)) {\n> +\t\t\tif (ip)\n> +\t\t\t\tmsg << dwfl.stackEntry(ip) << std::endl;\n> +\t\t\telse\n> +\t\t\t\tmsg << \"???\" << std::endl;\n> +\t\t}\n> +\n> +\t\treturn msg.str();\n> +\t}\n> +#endif\n> +\n>  #if HAVE_BACKTRACE\n>  \tSpan<void *const> trace{ backtrace_ };\n>  \ttrace = trace.subspan(skipLevels);\n> diff --git a/src/libcamera/base/meson.build b/src/libcamera/base/meson.build\n> index 85af01a19365..1fa894cf1896 100644\n> --- a/src/libcamera/base/meson.build\n> +++ b/src/libcamera/base/meson.build\n> @@ -19,13 +19,20 @@ libcamera_base_sources = files([\n>      'utils.cpp',\n>  ])\n>  \n> +libdw = cc.find_library('libdw', required : false)\n> +\n>  if cc.has_header_symbol('execinfo.h', 'backtrace')\n>      config_h.set('HAVE_BACKTRACE', 1)\n>  endif\n>  \n> +if libdw.found()\n> +    config_h.set('HAVE_DW', 1)\n> +endif\n> +\n>  libcamera_base_deps = [\n>      dependency('threads'),\n>      libatomic,\n> +    libdw,\n>  ]\n>  \n>  # Internal components must use the libcamera_base_private dependency to enable","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 00E1BBDC71\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Sep 2021 14:01:19 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 52C896918B;\n\tMon, 27 Sep 2021 16:01:19 +0200 (CEST)","from mail-qt1-x835.google.com (mail-qt1-x835.google.com\n\t[IPv6:2607:f8b0:4864:20::835])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8304E6012C\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Sep 2021 16:01:18 +0200 (CEST)","by mail-qt1-x835.google.com with SMTP id z7so3051690qto.7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Sep 2021 07:01:18 -0700 (PDT)","from nicolas-tpx395.localdomain (173-246-12-168.qc.cable.ebox.net.\n\t[173.246.12.168]) by smtp.gmail.com with ESMTPSA id\n\tc26sm9553773qka.33.2021.09.27.07.01.16\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 27 Sep 2021 07:01:16 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=ndufresne-ca.20210112.gappssmtp.com\n\theader.i=@ndufresne-ca.20210112.gappssmtp.com\n\theader.b=\"tSIjLiQw\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ndufresne-ca.20210112.gappssmtp.com; s=20210112;\n\th=message-id:subject:from:to:date:in-reply-to:references:user-agent\n\t:mime-version:content-transfer-encoding;\n\tbh=dDQ0/lEEeveQiJ9nidJ1G4l/wypr9M8SZLLYqkxyI68=;\n\tb=tSIjLiQw62leMw657KBig97t/whtl7V7hD5jRUYkntOF8Rn36vW2wu7Ui1eBmCIkpR\n\tGkoru00quQtHi5IY3g7QGj64FO6x/OqOY7l5H6llMulSLEZ2c6NzgdW6xOk4JM0D7eF+\n\tSPhdf/gGLsVnWI+vYfrjKpM8HhNpwgbf8/QEnMmHmgdOrZXUvc+JncjvU9T3kfbdGviz\n\tzDJ9yeweK9MiOFRBx8Bzt9bsRumkUSOaXXD02z1NRI+wIhrLLit/i1+SbokOjS+CfnMD\n\t1udbh+m/3vtoZLBTZ9Sho0mlOsWWu8R0HBNTg7SY7+3AGq2ku1s6kJHvWgLIrmzpa5Eg\n\t58IQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:message-id:subject:from:to:date:in-reply-to\n\t:references:user-agent:mime-version:content-transfer-encoding;\n\tbh=dDQ0/lEEeveQiJ9nidJ1G4l/wypr9M8SZLLYqkxyI68=;\n\tb=KTha/2sqJCMurbQLHCQ9aJnZbMtghEzmnUHDEmmioHTdCc8a3BcGbAjkC+q6EtJkee\n\tAoOgV5RagXUWWB9yLcwy3NDDwVCN7sQgY1sV5NfbStw4An4kWvgzy7lIfjGqmfXP54xH\n\trIhfBs00E9EmKSG8p8e+IFxBK7v/Nr3AAouxA4MUbmbzg6YEokswM6Iesl6nRjpeRoSX\n\t/C2ww/ZqaETXoNncPe6rNGoP/7ETJEfrq/vXCw2uW/gEvps0cgI/PzKqhjfswPsNM7gx\n\tDdkGanGxvH0bEHCsM1DzAxCs5S57LxN7TF/R8VA525K0YS0IMcmZH/YedHq+VUIANQfh\n\tTSfQ==","X-Gm-Message-State":"AOAM532qku0DX/0KlJkXFaPnnIY03skOuVpYslXjSyG9J1jTUZ46NI91\n\tzPXlcUHU9o8HdeDX/iF8wsBsj4xQKu5Rrg==","X-Google-Smtp-Source":"ABdhPJytoj1YuqOabNip2pLaklofQ4alhGyo+RzgmYIVvFN79VHjeuAZgxnJsyJ9khLTwqmcVXF1dw==","X-Received":"by 2002:ac8:7dc7:: with SMTP id c7mr16532qte.0.1632751277348;\n\tMon, 27 Sep 2021 07:01:17 -0700 (PDT)","Message-ID":"<dbf8dc14af5d188c0f3c5cedea82b48e3f9326e4.camel@ndufresne.ca>","From":"Nicolas Dufresne <nicolas@ndufresne.ca>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>, \n\tlibcamera-devel@lists.libcamera.org","Date":"Mon, 27 Sep 2021 10:01:15 -0400","In-Reply-To":"<20210924102323.26787-3-laurent.pinchart@ideasonboard.com>","References":"<20210924102323.26787-1-laurent.pinchart@ideasonboard.com>\n\t<20210924102323.26787-3-laurent.pinchart@ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","User-Agent":"Evolution 3.40.4 (3.40.4-1.fc34) ","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Subject":"Re: [libcamera-devel] [PATCH v1 2/4] libcamera: base: backtrace:\n\tUse libdw to provide symbolic names","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":19910,"web_url":"https://patchwork.libcamera.org/comment/19910/","msgid":"<YVJ/B8pOiJN0eXhH@pendragon.ideasonboard.com>","date":"2021-09-28T02:33:43","subject":"Re: [libcamera-devel] [PATCH v1 2/4] libcamera: base: backtrace:\n\tUse libdw to provide symbolic names","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Nicolas,\n\nOn Mon, Sep 27, 2021 at 10:01:15AM -0400, Nicolas Dufresne wrote:\n> Le vendredi 24 septembre 2021 à 13:23 +0300, Laurent Pinchart a écrit :\n> > libdw provides access to debugging information. This allows creating\n> > better stack trace entries, with file names and line numbers, but also\n> > with demangled symbols as the symbol name is available and can be passed\n> > to abi::__cxa_demangle().\n> > \n> > With libdw, the backtrace previously generated by backtrace_symbols()\n> > \n> > src/cam/../libcamera/libcamera.so(_ZN9libcamera14VimcCameraData4initEv+0xbd) [0x7f7dbb73222d]\n> > src/cam/../libcamera/libcamera.so(_ZN9libcamera19PipelineHandlerVimc5matchEPNS_16DeviceEnumeratorE+0x3e0) [0x7f7dbb731c40]\n> > src/cam/../libcamera/libcamera.so(_ZN9libcamera13CameraManager7Private22createPipelineHandlersEv+0x1a7) [0x7f7dbb5ea027]\n> > src/cam/../libcamera/libcamera.so(_ZN9libcamera13CameraManager7Private4initEv+0x98) [0x7f7dbb5e9dc8]\n> > src/cam/../libcamera/libcamera.so(_ZN9libcamera13CameraManager7Private3runEv+0x9f) [0x7f7dbb5e9c5f]\n> > src/cam/../libcamera/base/libcamera-base.so(_ZN9libcamera6Thread11startThreadEv+0xee) [0x7f7dbb3e95be]\n> > src/cam/../libcamera/base/libcamera-base.so(+0x4f9d7) [0x7f7dbb3ec9d7]\n> > src/cam/../libcamera/base/libcamera-base.so(+0x4f90e) [0x7f7dbb3ec90e]\n> > src/cam/../libcamera/base/libcamera-base.so(+0x4f2c2) [0x7f7dbb3ec2c2]\n> > /lib64/libpthread.so.0(+0x7e8e) [0x7f7dbab65e8e]\n> > /lib64/libc.so.6(clone+0x3f) [0x7f7dbb10b26f]\n> > \n> > becomes\n> > \n> > libcamera::VimcCameraData::init()+0xbd (src/libcamera/libcamera.so [0x00007f9de605b22d])\n> > libcamera::PipelineHandlerVimc::match(libcamera::DeviceEnumerator*)+0x3e0 (src/libcamera/libcamera.so [0x00007f9de605ac40])\n> > libcamera::CameraManager::Private::createPipelineHandlers()+0x1a7 (src/libcamera/libcamera.so [0x00007f9de5f13027])\n> > libcamera::CameraManager::Private::init()+0x98 (src/libcamera/libcamera.so [0x00007f9de5f12dc8])\n> > libcamera::CameraManager::Private::run()+0x9f (src/libcamera/libcamera.so [0x00007f9de5f12c5f])\n> > libcamera::Thread::startThread()+0xee (src/libcamera/base/libcamera-base.so [0x00007f9de5d125be])\n> > decltype(*(std::__1::forward<libcamera::Thread*>(fp0)).*fp()) std::__1::__invoke<void (libcamera::Thread::*)(), libcamera::Thread*, void>(void (libcamera::Thread::*&&)(), libcamera::Thread*&&)+0x77 (src/libcamera/base/libcamera-base.so [0x00007f9de5d159d7])\n> > void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*, 2ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*>&, std::__1::__tuple_indices<2ul>)+0x3e (src/libcamera/base/libcamera-base.so [0x00007f9de5d1590e])\n> > void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*> >(void*)+0x62 (src/libcamera/base/libcamera-base.so [0x00007f9de5d152c2])\n> > start_thread+0xde (/var/tmp/portage/sys-libs/glibc-2.33-r1/work/glibc-2.33/nptl/pthread_create.c:482)\n> > __clone+0x3f (../sysdeps/unix/sysv/linux/x86_64/clone.S:97)\n> > \n> > The stack entries related to libcamera are missing source file name and\n> > line information, which will be investigated separately, but this is\n> > still an improvement.\n> > \n> > Use libdw when available, falling back to backtrace_symbols() otherwise,\n> > or if libdw fails for any reason.\n> > \n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >  src/libcamera/base/backtrace.cpp | 120 +++++++++++++++++++++++++++++++\n> >  src/libcamera/base/meson.build   |   7 ++\n> >  2 files changed, 127 insertions(+)\n> > \n> > diff --git a/src/libcamera/base/backtrace.cpp b/src/libcamera/base/backtrace.cpp\n> > index 913f7ba71b03..011f2e428d5d 100644\n> > --- a/src/libcamera/base/backtrace.cpp\n> > +++ b/src/libcamera/base/backtrace.cpp\n> > @@ -12,9 +12,16 @@\n> >  #include <stdlib.h>\n> >  #endif\n> >  \n> > +#ifdef HAVE_DW\n> > +#include <cxxabi.h>\n> > +#include <elfutils/libdwfl.h>\n> > +#include <unistd.h>\n> > +#endif\n> > +\n> >  #include <sstream>\n> >  \n> >  #include <libcamera/base/span.h>\n> > +#include <libcamera/base/utils.h>\n> >  \n> >  /**\n> >   * \\file backtrace.h\n> > @@ -23,6 +30,101 @@\n> >  \n> >  namespace libcamera {\n> >  \n> > +namespace {\n> > +\n> > +#if HAVE_DW\n> > +class DwflParser\n> > +{\n> > +public:\n> > +\tDwflParser();\n> > +\t~DwflParser();\n> > +\n> > +\tbool isValid() const { return valid_; }\n> > +\tstd::string stackEntry(const void *ip);\n> > +\n> > +private:\n> > +\tDwfl_Callbacks callbacks_;\n> > +\tDwfl *dwfl_;\n> > +\tbool valid_;\n> > +};\n> > +\n> > +DwflParser::DwflParser()\n> > +\t: callbacks_({}), dwfl_(nullptr), valid_(false)\n> > +{\n> > +\tcallbacks_.find_elf = dwfl_linux_proc_find_elf;\n> > +\tcallbacks_.find_debuginfo = dwfl_standard_find_debuginfo;\n> > +\n> > +\tdwfl_ = dwfl_begin(&callbacks_);\n> > +\tif (!dwfl_)\n> > +\t\treturn;\n> > +\n> > +\tint ret = dwfl_linux_proc_report(dwfl_, getpid());\n> > +\tif (ret)\n> > +\t\treturn;\n> > +\n> > +\tret = dwfl_report_end(dwfl_, nullptr, nullptr);\n> > +\tif (ret)\n> > +\t\treturn;\n> > +\n> > +\tvalid_ = true;\n> > +}\n> > +\n> > +DwflParser::~DwflParser()\n> > +{\n> > +\tif (dwfl_)\n> > +\t\tdwfl_end(dwfl_);\n> > +}\n> > +\n> > +std::string DwflParser::stackEntry(const void *ip)\n> > +{\n> > +\tDwarf_Addr addr = reinterpret_cast<Dwarf_Addr>(ip);\n> > +\n> > +\tDwfl_Module *module = dwfl_addrmodule(dwfl_, addr);\n> > +\tif (!module)\n> > +\t\treturn std::string();\n> > +\n> > +\tstd::ostringstream entry;\n> > +\n> > +\tGElf_Off offset;\n> > +\tGElf_Sym sym;\n> > +\tconst char *symbol = dwfl_module_addrinfo(module, addr, &offset, &sym,\n> > +\t\t\t\t\t\t  nullptr, nullptr, nullptr);\n> > +\tif (symbol) {\n> > +\t\tchar *name = abi::__cxa_demangle(symbol, nullptr, nullptr, nullptr);\n> \n> A suggestion, and yes, you have to choose between memory safety and ugly code.\n> \n>                 std::unique_ptr<char[], decltype(free)*>{\n> \t\t\tabi::__cxa_demangle(symbol, nullptr, nullptr, nullptr),\n> \t\t\tfree};\n> \n> This is needed as by default C++ will assume that delete[] is to be used rather\n> then free.\n> \n> > +\t\tentry << (name ? name : symbol) << \"+0x\" << std::hex << offset\n> > +\t\t      << std::dec;\n> > +\t\tfree(name);\n> \n> And this error prone free is not longer needed, since you have a smart pointer.\n\nI've actually written something similar to the above initially, but then\nconsidered that the free was close enough to the allocation, and the\ncode unlikely enough to change in dangerous ways, that it wasn't worth\nit. I wouldn't mind changing it if a unique_ptr is preferred.\n\n> > +\t} else {\n> > +\t\tentry << \"??? [\" << utils::hex(addr) << \"]\";\n> > +\t}\n> > +\n> > +\tentry << \" (\";\n> > +\n> > +\tDwfl_Line *line = dwfl_module_getsrc(module, addr);\n> > +\tif (line) {\n> > +\t\tconst char *filename;\n> > +\t\tint lineNumber = 0;\n> > +\n> > +\t\tfilename = dwfl_lineinfo(line, &addr, &lineNumber, nullptr,\n> > +\t\t\t\t\t nullptr, nullptr);\n> > +\n> > +\t\tentry << (filename ? filename : \"???\") << \":\" << lineNumber;\n> > +\t} else {\n> > +\t\tconst char *filename = nullptr;\n> > +\n> > +\t\tdwfl_module_info(module, nullptr, nullptr, nullptr, nullptr,\n> > +\t\t\t\t nullptr, &filename, nullptr);\n> > +\n> > +\t\tentry << (filename ? filename : \"???\") << \" [\" << utils::hex(addr) << \"]\";\n> > +\t}\n> > +\n> > +\tentry << \")\";\n> > +\treturn entry.str();\n> > +}\n> > +#endif /* HAVE_DW */\n> > +\n> > +} /* namespace */\n> > +\n> >  /**\n> >   * \\class Backtrace\n> >   * \\brief Representation of a call stack backtrace\n> > @@ -85,6 +187,24 @@ std::string Backtrace::toString(unsigned int skipLevels) const\n> >  \tif (backtrace_.size() <= skipLevels)\n> >  \t\treturn std::string();\n> >  \n> > +#if HAVE_DW\n> > +\tDwflParser dwfl;\n> > +\n> > +\tif (dwfl.isValid()) {\n> > +\t\tstd::ostringstream msg;\n> > +\n> > +\t\tSpan<void *const> trace{ backtrace_ };\n> > +\t\tfor (const void *ip : trace.subspan(skipLevels)) {\n> > +\t\t\tif (ip)\n> > +\t\t\t\tmsg << dwfl.stackEntry(ip) << std::endl;\n> > +\t\t\telse\n> > +\t\t\t\tmsg << \"???\" << std::endl;\n> > +\t\t}\n> > +\n> > +\t\treturn msg.str();\n> > +\t}\n> > +#endif\n> > +\n> >  #if HAVE_BACKTRACE\n> >  \tSpan<void *const> trace{ backtrace_ };\n> >  \ttrace = trace.subspan(skipLevels);\n> > diff --git a/src/libcamera/base/meson.build b/src/libcamera/base/meson.build\n> > index 85af01a19365..1fa894cf1896 100644\n> > --- a/src/libcamera/base/meson.build\n> > +++ b/src/libcamera/base/meson.build\n> > @@ -19,13 +19,20 @@ libcamera_base_sources = files([\n> >      'utils.cpp',\n> >  ])\n> >  \n> > +libdw = cc.find_library('libdw', required : false)\n> > +\n> >  if cc.has_header_symbol('execinfo.h', 'backtrace')\n> >      config_h.set('HAVE_BACKTRACE', 1)\n> >  endif\n> >  \n> > +if libdw.found()\n> > +    config_h.set('HAVE_DW', 1)\n> > +endif\n> > +\n> >  libcamera_base_deps = [\n> >      dependency('threads'),\n> >      libatomic,\n> > +    libdw,\n> >  ]\n> >  \n> >  # Internal components must use the libcamera_base_private dependency to enable","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 0B9E2BDC71\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 28 Sep 2021 02:33:54 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 38C3B69189;\n\tTue, 28 Sep 2021 04:33:53 +0200 (CEST)","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 BCFA9684C7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Sep 2021 04:33:51 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 283133F1;\n\tTue, 28 Sep 2021 04:33:51 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"jhWPIYG9\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1632796431;\n\tbh=olqL3i7I1oikH2ZwzdC7kACP3/MRc6eagiDXYHnWQMk=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=jhWPIYG94gELiHSgIalL4fxCmHDWfTW9nZbNUhif9OrwOPqbr/Hid1dMoKVawTvrO\n\t8VmLLYOLv1Q9r+TXG5EnZ20my1ClPxwM/lTMJe7y5wQznea3RTIVmdjV0smkvSzyHA\n\tuuZQ4zHhbDN05jsfsMB2M/qQ3DaZR6F3OQ8PSOEo=","Date":"Tue, 28 Sep 2021 05:33:43 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Nicolas Dufresne <nicolas@ndufresne.ca>","Message-ID":"<YVJ/B8pOiJN0eXhH@pendragon.ideasonboard.com>","References":"<20210924102323.26787-1-laurent.pinchart@ideasonboard.com>\n\t<20210924102323.26787-3-laurent.pinchart@ideasonboard.com>\n\t<dbf8dc14af5d188c0f3c5cedea82b48e3f9326e4.camel@ndufresne.ca>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<dbf8dc14af5d188c0f3c5cedea82b48e3f9326e4.camel@ndufresne.ca>","Subject":"Re: [libcamera-devel] [PATCH v1 2/4] libcamera: base: backtrace:\n\tUse libdw to provide symbolic names","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":19930,"web_url":"https://patchwork.libcamera.org/comment/19930/","msgid":"<25cbfad53d5d5f696adef68e7eb4ded82386a4f1.camel@ndufresne.ca>","date":"2021-09-28T14:25:03","subject":"Re: [libcamera-devel] [PATCH v1 2/4] libcamera: base: backtrace:\n\tUse libdw to provide symbolic names","submitter":{"id":30,"url":"https://patchwork.libcamera.org/api/people/30/","name":"Nicolas Dufresne","email":"nicolas@ndufresne.ca"},"content":"Le mardi 28 septembre 2021 à 05:33 +0300, Laurent Pinchart a écrit :\n> Hi Nicolas,\n> \n> On Mon, Sep 27, 2021 at 10:01:15AM -0400, Nicolas Dufresne wrote:\n> > Le vendredi 24 septembre 2021 à 13:23 +0300, Laurent Pinchart a écrit :\n> > > libdw provides access to debugging information. This allows creating\n> > > better stack trace entries, with file names and line numbers, but also\n> > > with demangled symbols as the symbol name is available and can be passed\n> > > to abi::__cxa_demangle().\n> > > \n> > > With libdw, the backtrace previously generated by backtrace_symbols()\n> > > \n> > > src/cam/../libcamera/libcamera.so(_ZN9libcamera14VimcCameraData4initEv+0xbd) [0x7f7dbb73222d]\n> > > src/cam/../libcamera/libcamera.so(_ZN9libcamera19PipelineHandlerVimc5matchEPNS_16DeviceEnumeratorE+0x3e0) [0x7f7dbb731c40]\n> > > src/cam/../libcamera/libcamera.so(_ZN9libcamera13CameraManager7Private22createPipelineHandlersEv+0x1a7) [0x7f7dbb5ea027]\n> > > src/cam/../libcamera/libcamera.so(_ZN9libcamera13CameraManager7Private4initEv+0x98) [0x7f7dbb5e9dc8]\n> > > src/cam/../libcamera/libcamera.so(_ZN9libcamera13CameraManager7Private3runEv+0x9f) [0x7f7dbb5e9c5f]\n> > > src/cam/../libcamera/base/libcamera-base.so(_ZN9libcamera6Thread11startThreadEv+0xee) [0x7f7dbb3e95be]\n> > > src/cam/../libcamera/base/libcamera-base.so(+0x4f9d7) [0x7f7dbb3ec9d7]\n> > > src/cam/../libcamera/base/libcamera-base.so(+0x4f90e) [0x7f7dbb3ec90e]\n> > > src/cam/../libcamera/base/libcamera-base.so(+0x4f2c2) [0x7f7dbb3ec2c2]\n> > > /lib64/libpthread.so.0(+0x7e8e) [0x7f7dbab65e8e]\n> > > /lib64/libc.so.6(clone+0x3f) [0x7f7dbb10b26f]\n> > > \n> > > becomes\n> > > \n> > > libcamera::VimcCameraData::init()+0xbd (src/libcamera/libcamera.so [0x00007f9de605b22d])\n> > > libcamera::PipelineHandlerVimc::match(libcamera::DeviceEnumerator*)+0x3e0 (src/libcamera/libcamera.so [0x00007f9de605ac40])\n> > > libcamera::CameraManager::Private::createPipelineHandlers()+0x1a7 (src/libcamera/libcamera.so [0x00007f9de5f13027])\n> > > libcamera::CameraManager::Private::init()+0x98 (src/libcamera/libcamera.so [0x00007f9de5f12dc8])\n> > > libcamera::CameraManager::Private::run()+0x9f (src/libcamera/libcamera.so [0x00007f9de5f12c5f])\n> > > libcamera::Thread::startThread()+0xee (src/libcamera/base/libcamera-base.so [0x00007f9de5d125be])\n> > > decltype(*(std::__1::forward<libcamera::Thread*>(fp0)).*fp()) std::__1::__invoke<void (libcamera::Thread::*)(), libcamera::Thread*, void>(void (libcamera::Thread::*&&)(), libcamera::Thread*&&)+0x77 (src/libcamera/base/libcamera-base.so [0x00007f9de5d159d7])\n> > > void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*, 2ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*>&, std::__1::__tuple_indices<2ul>)+0x3e (src/libcamera/base/libcamera-base.so [0x00007f9de5d1590e])\n> > > void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*> >(void*)+0x62 (src/libcamera/base/libcamera-base.so [0x00007f9de5d152c2])\n> > > start_thread+0xde (/var/tmp/portage/sys-libs/glibc-2.33-r1/work/glibc-2.33/nptl/pthread_create.c:482)\n> > > __clone+0x3f (../sysdeps/unix/sysv/linux/x86_64/clone.S:97)\n> > > \n> > > The stack entries related to libcamera are missing source file name and\n> > > line information, which will be investigated separately, but this is\n> > > still an improvement.\n> > > \n> > > Use libdw when available, falling back to backtrace_symbols() otherwise,\n> > > or if libdw fails for any reason.\n> > > \n> > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > > ---\n> > >  src/libcamera/base/backtrace.cpp | 120 +++++++++++++++++++++++++++++++\n> > >  src/libcamera/base/meson.build   |   7 ++\n> > >  2 files changed, 127 insertions(+)\n> > > \n> > > diff --git a/src/libcamera/base/backtrace.cpp b/src/libcamera/base/backtrace.cpp\n> > > index 913f7ba71b03..011f2e428d5d 100644\n> > > --- a/src/libcamera/base/backtrace.cpp\n> > > +++ b/src/libcamera/base/backtrace.cpp\n> > > @@ -12,9 +12,16 @@\n> > >  #include <stdlib.h>\n> > >  #endif\n> > >  \n> > > +#ifdef HAVE_DW\n> > > +#include <cxxabi.h>\n> > > +#include <elfutils/libdwfl.h>\n> > > +#include <unistd.h>\n> > > +#endif\n> > > +\n> > >  #include <sstream>\n> > >  \n> > >  #include <libcamera/base/span.h>\n> > > +#include <libcamera/base/utils.h>\n> > >  \n> > >  /**\n> > >   * \\file backtrace.h\n> > > @@ -23,6 +30,101 @@\n> > >  \n> > >  namespace libcamera {\n> > >  \n> > > +namespace {\n> > > +\n> > > +#if HAVE_DW\n> > > +class DwflParser\n> > > +{\n> > > +public:\n> > > +\tDwflParser();\n> > > +\t~DwflParser();\n> > > +\n> > > +\tbool isValid() const { return valid_; }\n> > > +\tstd::string stackEntry(const void *ip);\n> > > +\n> > > +private:\n> > > +\tDwfl_Callbacks callbacks_;\n> > > +\tDwfl *dwfl_;\n> > > +\tbool valid_;\n> > > +};\n> > > +\n> > > +DwflParser::DwflParser()\n> > > +\t: callbacks_({}), dwfl_(nullptr), valid_(false)\n> > > +{\n> > > +\tcallbacks_.find_elf = dwfl_linux_proc_find_elf;\n> > > +\tcallbacks_.find_debuginfo = dwfl_standard_find_debuginfo;\n> > > +\n> > > +\tdwfl_ = dwfl_begin(&callbacks_);\n> > > +\tif (!dwfl_)\n> > > +\t\treturn;\n> > > +\n> > > +\tint ret = dwfl_linux_proc_report(dwfl_, getpid());\n> > > +\tif (ret)\n> > > +\t\treturn;\n> > > +\n> > > +\tret = dwfl_report_end(dwfl_, nullptr, nullptr);\n> > > +\tif (ret)\n> > > +\t\treturn;\n> > > +\n> > > +\tvalid_ = true;\n> > > +}\n> > > +\n> > > +DwflParser::~DwflParser()\n> > > +{\n> > > +\tif (dwfl_)\n> > > +\t\tdwfl_end(dwfl_);\n> > > +}\n> > > +\n> > > +std::string DwflParser::stackEntry(const void *ip)\n> > > +{\n> > > +\tDwarf_Addr addr = reinterpret_cast<Dwarf_Addr>(ip);\n> > > +\n> > > +\tDwfl_Module *module = dwfl_addrmodule(dwfl_, addr);\n> > > +\tif (!module)\n> > > +\t\treturn std::string();\n> > > +\n> > > +\tstd::ostringstream entry;\n> > > +\n> > > +\tGElf_Off offset;\n> > > +\tGElf_Sym sym;\n> > > +\tconst char *symbol = dwfl_module_addrinfo(module, addr, &offset, &sym,\n> > > +\t\t\t\t\t\t  nullptr, nullptr, nullptr);\n> > > +\tif (symbol) {\n> > > +\t\tchar *name = abi::__cxa_demangle(symbol, nullptr, nullptr, nullptr);\n> > \n> > A suggestion, and yes, you have to choose between memory safety and ugly code.\n> > \n> >                 std::unique_ptr<char[], decltype(free)*>{\n> > \t\t\tabi::__cxa_demangle(symbol, nullptr, nullptr, nullptr),\n> > \t\t\tfree};\n> > \n> > This is needed as by default C++ will assume that delete[] is to be used rather\n> > then free.\n> > \n> > > +\t\tentry << (name ? name : symbol) << \"+0x\" << std::hex << offset\n> > > +\t\t      << std::dec;\n> > > +\t\tfree(name);\n> > \n> > And this error prone free is not longer needed, since you have a smart pointer.\n> \n> I've actually written something similar to the above initially, but then\n> considered that the free was close enough to the allocation, and the\n> code unlikely enough to change in dangerous ways, that it wasn't worth\n> it. I wouldn't mind changing it if a unique_ptr is preferred.\n\nI agree. I think in the long term, we'll just add a helper that makes it less\nugly, and we will be more keen to use it.\n\n> \n> > > +\t} else {\n> > > +\t\tentry << \"??? [\" << utils::hex(addr) << \"]\";\n> > > +\t}\n> > > +\n> > > +\tentry << \" (\";\n> > > +\n> > > +\tDwfl_Line *line = dwfl_module_getsrc(module, addr);\n> > > +\tif (line) {\n> > > +\t\tconst char *filename;\n> > > +\t\tint lineNumber = 0;\n> > > +\n> > > +\t\tfilename = dwfl_lineinfo(line, &addr, &lineNumber, nullptr,\n> > > +\t\t\t\t\t nullptr, nullptr);\n> > > +\n> > > +\t\tentry << (filename ? filename : \"???\") << \":\" << lineNumber;\n> > > +\t} else {\n> > > +\t\tconst char *filename = nullptr;\n> > > +\n> > > +\t\tdwfl_module_info(module, nullptr, nullptr, nullptr, nullptr,\n> > > +\t\t\t\t nullptr, &filename, nullptr);\n> > > +\n> > > +\t\tentry << (filename ? filename : \"???\") << \" [\" << utils::hex(addr) << \"]\";\n> > > +\t}\n> > > +\n> > > +\tentry << \")\";\n> > > +\treturn entry.str();\n> > > +}\n> > > +#endif /* HAVE_DW */\n> > > +\n> > > +} /* namespace */\n> > > +\n> > >  /**\n> > >   * \\class Backtrace\n> > >   * \\brief Representation of a call stack backtrace\n> > > @@ -85,6 +187,24 @@ std::string Backtrace::toString(unsigned int skipLevels) const\n> > >  \tif (backtrace_.size() <= skipLevels)\n> > >  \t\treturn std::string();\n> > >  \n> > > +#if HAVE_DW\n> > > +\tDwflParser dwfl;\n> > > +\n> > > +\tif (dwfl.isValid()) {\n> > > +\t\tstd::ostringstream msg;\n> > > +\n> > > +\t\tSpan<void *const> trace{ backtrace_ };\n> > > +\t\tfor (const void *ip : trace.subspan(skipLevels)) {\n> > > +\t\t\tif (ip)\n> > > +\t\t\t\tmsg << dwfl.stackEntry(ip) << std::endl;\n> > > +\t\t\telse\n> > > +\t\t\t\tmsg << \"???\" << std::endl;\n> > > +\t\t}\n> > > +\n> > > +\t\treturn msg.str();\n> > > +\t}\n> > > +#endif\n> > > +\n> > >  #if HAVE_BACKTRACE\n> > >  \tSpan<void *const> trace{ backtrace_ };\n> > >  \ttrace = trace.subspan(skipLevels);\n> > > diff --git a/src/libcamera/base/meson.build b/src/libcamera/base/meson.build\n> > > index 85af01a19365..1fa894cf1896 100644\n> > > --- a/src/libcamera/base/meson.build\n> > > +++ b/src/libcamera/base/meson.build\n> > > @@ -19,13 +19,20 @@ libcamera_base_sources = files([\n> > >      'utils.cpp',\n> > >  ])\n> > >  \n> > > +libdw = cc.find_library('libdw', required : false)\n> > > +\n> > >  if cc.has_header_symbol('execinfo.h', 'backtrace')\n> > >      config_h.set('HAVE_BACKTRACE', 1)\n> > >  endif\n> > >  \n> > > +if libdw.found()\n> > > +    config_h.set('HAVE_DW', 1)\n> > > +endif\n> > > +\n> > >  libcamera_base_deps = [\n> > >      dependency('threads'),\n> > >      libatomic,\n> > > +    libdw,\n> > >  ]\n> > >  \n> > >  # Internal components must use the libcamera_base_private dependency to enable\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 40521BDC71\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 28 Sep 2021 14:25:08 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0951F6918E;\n\tTue, 28 Sep 2021 16:25:08 +0200 (CEST)","from mail-qv1-xf31.google.com (mail-qv1-xf31.google.com\n\t[IPv6:2607:f8b0:4864:20::f31])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7636869185\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Sep 2021 16:25:06 +0200 (CEST)","by mail-qv1-xf31.google.com with SMTP id n6so5294651qvp.7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Sep 2021 07:25:06 -0700 (PDT)","from nicolas-tpx395.localdomain (173-246-12-168.qc.cable.ebox.net.\n\t[173.246.12.168]) by smtp.gmail.com with ESMTPSA id\n\tl3sm12815116qtu.47.2021.09.28.07.25.04\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 28 Sep 2021 07:25:04 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=ndufresne-ca.20210112.gappssmtp.com\n\theader.i=@ndufresne-ca.20210112.gappssmtp.com\n\theader.b=\"3DsruoZT\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ndufresne-ca.20210112.gappssmtp.com; s=20210112;\n\th=message-id:subject:from:to:cc:date:in-reply-to:references\n\t:user-agent:mime-version:content-transfer-encoding;\n\tbh=JwPB9u0K+sZ5DrIt0uhxBXdVBbnO/MvVclDmltp9kO4=;\n\tb=3DsruoZTS/A7yBZm7zj2lo6W/iQ8NBxNKA1rXbqAghgYXZinukxPUjxXL3mi0Dhol9\n\t6h+xWnv1+2/Ku/EKUDDUEvWvx/Db1gYYtzH9Xydklehsvmi0Ktmj8v+QvZcfi8m/urT/\n\tSKojoygWu05kB45UAssFW9WN1rT5gV+AR1lPaMsIy9Kwu+KXJYH2HyNYHA/fjcx8UOSa\n\tMhhByqukH6vIMhLYTUmrNz1iLCwf9YwMy6KJU1G06F4fHDMI6Lu5rXCGHkcan8bYeP6J\n\tBulf3Pxx2Pc/wnI5TxEY5D83uNE5dO9pFSDiQeA97oBCxjjGlJvWwsxEkuFtsYeYAiuL\n\tqrMg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:message-id:subject:from:to:cc:date:in-reply-to\n\t:references:user-agent:mime-version:content-transfer-encoding;\n\tbh=JwPB9u0K+sZ5DrIt0uhxBXdVBbnO/MvVclDmltp9kO4=;\n\tb=iQriHQMO+5vvjDSFQNgWM//XO+OMWYOHTrewVqsMsr3c0tvaUqoNevzR7rXWthDWuc\n\t20c2YeA1S1xf7vqE4gSo7iAiNGuYLlvYeuV9gRcMTUMmMnCBEWKEq71U40Cn85M5WzJ3\n\t1Hn6o95c8jkXxkjzm7460r1GvAzclnEHICnqldYNOEk8ao8UYRQRdjlwacttLyMGJ0ed\n\tjCdbEtCbuaeeIKEZQroSENi/W71B+9plHuK1ScHmhfjjMonTBiwseBxSsPSxp9H/FNLm\n\tJV5yuzgF32LJ3HUWcSu36Zh2PyAFciwCp95ibzPG6WI5R8dbaPvRZrmGMW8fXJ1bU3rc\n\tNCvw==","X-Gm-Message-State":"AOAM532Mn1J1XBpGqqeG90KHHlduCN8skwO05Xe2rm5Zit8Aio6m4snn\n\tyB5geuc0vqjIMsBrPwVQecns9g==","X-Google-Smtp-Source":"ABdhPJwiqD/1fjZi8LKraNv4WXoCsIlUTm86pHPy6/CwU1OKKcgvGSg/xgawaotouUcGn79y8JqkQA==","X-Received":"by 2002:a05:6214:1402:: with SMTP id\n\tn2mr5879736qvx.45.1632839105344; \n\tTue, 28 Sep 2021 07:25:05 -0700 (PDT)","Message-ID":"<25cbfad53d5d5f696adef68e7eb4ded82386a4f1.camel@ndufresne.ca>","From":"Nicolas Dufresne <nicolas@ndufresne.ca>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Date":"Tue, 28 Sep 2021 10:25:03 -0400","In-Reply-To":"<YVJ/B8pOiJN0eXhH@pendragon.ideasonboard.com>","References":"<20210924102323.26787-1-laurent.pinchart@ideasonboard.com>\n\t<20210924102323.26787-3-laurent.pinchart@ideasonboard.com>\n\t<dbf8dc14af5d188c0f3c5cedea82b48e3f9326e4.camel@ndufresne.ca>\n\t<YVJ/B8pOiJN0eXhH@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","User-Agent":"Evolution 3.40.4 (3.40.4-1.fc34) ","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Subject":"Re: [libcamera-devel] [PATCH v1 2/4] libcamera: base: backtrace:\n\tUse libdw to provide symbolic names","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]