root/assert_handler.cc

Revision 6c86e7ccc32f1c99d204262844a52b1b06359145, 3.4 KB (checked in by Antti-Juhani Kaijanaho <antti-juhani@…>, 18 months ago)

 boost::assertion_failed Improve on the logging speed.

Signed-off-by: Antti-Juhani Kaijanaho <antti-juhani@…>

  • Property mode set to 100644
Line 
1/*  This file is part of Alue, the multiprotocol Internet discussion daemon
2
3    Copyright © 2010 Antti-Juhani Kaijanaho
4
5    Alue is free software: you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    Alue is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with Alue.  If not, see <http://www.gnu.org/licenses/>.
17
18 */
19
20#include "config.hh"
21#include "logger/logline.hh"
22
23#include <boost/assert.hpp>
24#include <execinfo.h>
25#include <stdio.h>
26
27namespace boost
28{
29        void assertion_failed(char const *expr,
30                              char const *function,
31                              char const *file,
32                              long line)
33        {
34                logger::logline ll;
35                ll << "ASSERTION FAILED at "
36                   << file << ":"
37                   << line
38                   << " [" << function << "]: "
39                   << expr;
40                ll.close();
41                logger::logger.flush();
42
43                static void *array[250];
44                size_t size;
45                size = backtrace(array, sizeof array / sizeof *array);
46                char **bt = backtrace_symbols(array, size);
47
48                ll.open();
49                ll << "BACKTRACE FOLLOWS:";
50                for (size_t i = 0; i < size; i++)
51                {
52                        ll << "\t" << bt[i] << "\n";
53                }
54                logger::logger.flush();
55                std::string gdb = "gdb --batch ";
56                for (size_t i = 0; i < size; i++)
57                {
58                        std::string bta = bt[i];
59                        size_t ob = bta.find('[');
60                        size_t cb = bta.rfind(']');
61                        if (ob == std::string::npos ||
62                            cb == std::string::npos)
63                                continue;
64                        bta = bta.substr(ob + 1, cb - ob - 1);
65                        gdb += "--ex 'info line *";
66                        gdb += bta.c_str();
67                        gdb += "' ";
68                }
69                gdb += config["executable"].as<std::string>();
70                gdb += " </dev/null";
71                ll.open();
72                ll << gdb;
73                ll.close();
74                FILE *fp = ::popen(gdb.c_str(), "r");
75                if (fp != 0)
76                {
77                        ll.open();
78                        ll << "LINE INFORMATION FOLLOWS:";
79                        ll.nl();
80                        while (true)
81                        {
82                                char buf[128];
83                                int n = ::fread(buf, 1, sizeof buf, fp);
84                                ll << std::string(buf, n);
85                                if (n == 0) break;
86                        }
87                        ::pclose(fp);
88                        ll.close();
89                        logger::logger.flush();
90                }
91
92                std::free(bt);
93
94                throw std::logic_error("internal error");
95        }
96
97}
Note: See TracBrowser for help on using the browser.