LCOV - code coverage report
Current view: top level - eventdispatcher - signal_profiler.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 37 0.0 %
Date: 2021-09-19 09:06:58 Functions: 0 2 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2012-2021  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/eventdispatcher
       4             : // contact@m2osw.com
       5             : //
       6             : // This program is free software; you can redistribute it and/or modify
       7             : // it under the terms of the GNU General Public License as published by
       8             : // the Free Software Foundation; either version 2 of the License, or
       9             : // (at your option) any later version.
      10             : //
      11             : // This program is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : //
      16             : // You should have received a copy of the GNU General Public License
      17             : // along with this program; if not, write to the Free Software
      18             : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
      19             : 
      20             : /** \file
      21             :  * \brief Implementation of the Signal Profiler class.
      22             :  *
      23             :  * The Signal Profiler class is at attempt to implement the SIGPROF without
      24             :  * stopping system functions such as poll(). At this point, this doesn't
      25             :  * work.
      26             :  *
      27             :  * To test with the profiler, use the `-pg` command line option on your g++
      28             :  * command line. See the g++ docs for more info.
      29             :  */
      30             : 
      31             : // self
      32             : //
      33             : #include    "eventdispatcher/signal_profiler.h"
      34             : 
      35             : 
      36             : // C lib
      37             : //
      38             : #include    <ucontext.h>
      39             : 
      40             : 
      41             : // last include
      42             : //
      43             : #include    <snapdev/poison.h>
      44             : 
      45             : 
      46             : 
      47             : namespace ed
      48             : {
      49             : 
      50             : /** \brief Initialize the profiler signal objects.
      51             :  *
      52             :  * This constructor sets up the signal within the event dispatcher
      53             :  * environment and then it retrieves the pointer to the gcc SIGPROF
      54             :  * function which is used to collect the necessary data.
      55             :  *
      56             :  * \todo
      57             :  * Make this whole thing work. It is very likely that the stack trace
      58             :  * is going to be wrong if the handler doesn't use the newer scheme
      59             :  * (i.e. the one where the context gets saved at the time the event
      60             :  * occurs and not at the time we're handling it here). At the moment,
      61             :  * Linux does it properly, so no worries here. That being said, so
      62             :  * far I've not been able to make it work properly.
      63             :  */
      64           0 : signal_profiler::signal_profiler()
      65           0 :     : signal(SIGPROF)
      66             : {
      67             :     // retrieve the handler so we can call it whenever the signal occurs
      68             :     //
      69           0 :     sigaction(SIGPROF, nullptr, &f_action);
      70           0 : }
      71             : 
      72           0 : void signal_profiler::process_signal()
      73             : {
      74           0 :     if((f_action.sa_flags & SA_SIGINFO) != 0)
      75             :     {
      76           0 :         if(f_action.sa_handler != SIG_IGN
      77           0 :         && f_action.sa_handler != SIG_DFL
      78           0 :         && f_action.sa_handler != nullptr)
      79             :         {
      80           0 :             (*f_action.sa_handler)(SIGPROF);
      81             :         }
      82             :     }
      83             :     else
      84             :     {
      85           0 :         if(f_action.sa_sigaction != nullptr)
      86             :         {
      87           0 :             signalfd_siginfo const * fdinfo(get_signal_info());
      88           0 :             siginfo_t info = siginfo_t();
      89           0 :             info.si_signo       = fdinfo->ssi_signo;
      90           0 :             info.si_errno       = fdinfo->ssi_errno;
      91           0 :             info.si_code        = fdinfo->ssi_code;
      92             :             //info.si_trapno      = fdinfo->ssi_trapno; // not defined on all machines
      93           0 :             info.si_pid         = fdinfo->ssi_pid;
      94           0 :             info.si_uid         = fdinfo->ssi_uid;
      95           0 :             info.si_status      = fdinfo->ssi_status;
      96           0 :             info.si_utime       = fdinfo->ssi_utime;
      97           0 :             info.si_stime       = fdinfo->ssi_stime;
      98           0 :             info.si_value.sival_int = 0;
      99           0 :             info.si_int         = fdinfo->ssi_int;
     100           0 :             info.si_ptr         = reinterpret_cast<void *>(fdinfo->ssi_ptr);
     101           0 :             info.si_overrun     = fdinfo->ssi_overrun;
     102           0 :             info.si_timerid     = 0;
     103           0 :             info.si_addr        = reinterpret_cast<void *>(fdinfo->ssi_addr);
     104           0 :             info.si_band        = fdinfo->ssi_band;
     105           0 :             info.si_fd          = fdinfo->ssi_fd;
     106           0 :             info.si_addr_lsb    = 0; //fdinfo->ssi_addr_lsb; // not on arch64 and doesn't help at this point
     107             : 
     108             :             // the following fields don't exist in 16.04, keep commented until we stop support
     109             :             //info.si_lower       = 0;
     110             :             //info.si_upper       = 0;
     111             :             //info.si_pkey        = 0;
     112             : 
     113           0 :             info.si_call_addr   = 0;
     114           0 :             info.si_syscall     = 0;
     115           0 :             info.si_arch        = 0;
     116             : 
     117           0 :             ucontext_t uc;
     118           0 :             getcontext(&uc);
     119             : 
     120           0 :             (*f_action.sa_sigaction)(SIGPROF, &info, &uc);
     121             :         }
     122             :     }
     123           0 : }
     124             : 
     125             : 
     126             : } // namespace ed
     127             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13