3 #include <asm/ptrace.h>
5 #include <lib/base/eerror.h>
6 #include <lib/base/smartptr.h>
7 #include <lib/gdi/grc.h>
8 #include <lib/gdi/gfbdc.h>
12 /************************************************/
14 #define CRASH_EMAILADDR "crashlog@dream-multimedia-tv.de"
16 #define RINGBUFFER_SIZE 16384
17 static char ringbuffer[RINGBUFFER_SIZE];
18 static int ringbuffer_head;
20 static void addToLogbuffer(const char *data, int len)
24 int remaining = RINGBUFFER_SIZE - ringbuffer_head;
29 memcpy(ringbuffer + ringbuffer_head, data, remaining);
32 ringbuffer_head += remaining;
33 if (ringbuffer_head >= RINGBUFFER_SIZE)
38 static std::string getLogBuffer()
40 int begin = ringbuffer_head;
41 while (ringbuffer[begin] == 0)
44 if (begin == RINGBUFFER_SIZE)
46 if (begin == ringbuffer_head)
49 if (begin < ringbuffer_head)
50 return std::string(ringbuffer + begin, ringbuffer_head - begin);
53 return std::string(ringbuffer + begin, RINGBUFFER_SIZE - begin) + std::string(ringbuffer, ringbuffer_head);
57 static void addToLogbuffer(int level, const std::string &log)
59 addToLogbuffer(log.c_str(), log.size());
63 extern std::string getLogBuffer();
68 sprintf(logfile, "/media/hdd/enigma2_crash_%u.log", (unsigned int)time(0));
69 FILE *f = fopen(logfile, "wb");
71 std::string lines = getLogBuffer();
76 fprintf(f, "enigma2 crashed on %s", ctime(&t));
77 #ifdef ENIGMA2_CHECKOUT_TAG
78 fprintf(f, "enigma2 CVS TAG: " ENIGMA2_CHECKOUT_TAG "\n");
80 fprintf(f, "enigma2 compiled on " __DATE__ "\n");
82 #ifdef ENIGMA2_CHECKOUT_ROOT
83 fprintf(f, "enigma2 checked out from " ENIGMA2_CHECKOUT_ROOT "\n");
85 fprintf(f, "please email this file to " CRASH_EMAILADDR "\n");
86 std::string buffer = getLogBuffer();
87 fwrite(buffer.c_str(), buffer.size(), 1, f);
91 sprintf(cmd, "find /usr/lib/enigma2/python/ -name \"*.py\" | xargs md5sum >> %s", logfile);
96 gFBDC::getInstance(my_dc);
101 p.resetClip(eRect(ePoint(0, 0), my_dc->size()));
102 p.setBackgroundColor(gRGB(0x0000C0));
103 p.setForegroundColor(gRGB(0xFFFFFF));
105 ePtr<gFont> font = new gFont("Regular", 20);
109 eRect usable_area = eRect(100, 70, my_dc->size().width() - 150, 100);
111 p.renderText(usable_area,
112 "We are really sorry. Something happened "
113 "which should not have happened, and "
114 "resulted in a crash. If you want to help "
115 "us in improving this situation, please send "
116 "the logfile created in /hdd/ to " CRASH_EMAILADDR "."
117 "Your receiver restarts in 10 seconds !", gPainter::RT_WRAP|gPainter::RT_HALIGN_LEFT);
119 usable_area = eRect(100, 170, my_dc->size().width() - 180, my_dc->size().height() - 20);
123 size_t start = std::string::npos + 1;
126 start = lines.rfind('\n', start - 1);
127 if (start == std::string::npos)
134 font = new gFont("Regular", 14);
137 p.renderText(usable_area,
138 lines.substr(start), gPainter::RT_HALIGN_LEFT);
145 #if defined(__MIPSEL__)
146 void oops(const mcontext_t &context, int dumpcode)
148 eDebug("PC: %08lx, vaddr: %08lx", (unsigned long)context.pc, (unsigned long)context.badvaddr);
152 eDebugNoNewLine(" %08x", (int)context.gregs[i]);
156 /* this is temporary debug stuff. */
157 if (dumpcode && ((unsigned long)context.pc) > 0x10000) /* not a zero pointer */
159 eDebug("As a final action, i will try to dump a bit of code.");
160 eDebug("I just hope that this won't crash.");
162 eDebugNoNewLine("%08lx:", (unsigned long)context.pc);
163 for (i=0; i<0x20; ++i)
164 eDebugNoNewLine(" %02x", ((unsigned char*)context.pc)[i]);
169 #warning "no oops support!"
170 #define NO_OOPS_SUPPORT
173 void handleFatalSignal(int signum, siginfo_t *si, void *ctx)
175 ucontext_t *uc = (ucontext_t*)ctx;
176 eDebug("KILLED BY signal %d", signum);
177 #ifndef NO_OOPS_SUPPORT
178 oops(uc->uc_mcontext, signum == SIGSEGV || signum == SIGABRT);
184 void bsodCatchSignals()
186 struct sigaction act;
187 act.sa_handler = SIG_DFL;
188 act.sa_sigaction = handleFatalSignal;
189 act.sa_flags = SA_RESTART | SA_SIGINFO;
190 if (sigemptyset(&act.sa_mask) == -1)
191 perror("sigemptyset");
193 /* start handling segfaults etc. */
194 sigaction(SIGSEGV, &act, 0);
195 sigaction(SIGILL, &act, 0);
196 sigaction(SIGBUS, &act, 0);
197 sigaction(SIGABRT, &act, 0);
202 logOutput.connect(addToLogbuffer);