this repo has no description
1#import <Foundation/NSXMLElement.h>
2#import <Foundation/NSXMLDocument.h>
3#import <Foundation/NSXMLNode.h>
4#import <Foundation/NSString.h>
5#import <Foundation/NSAutoreleasePool.h>
6#include <signal.h>
7#include <string.h>
8#include <stdlib.h>
9#include <unistd.h>
10#include <stdio.h>
11//#include "../../config.h"
12
13#ifndef TEST
14__attribute__((constructor))
15#endif
16 static void setSignalHandlers();
17
18__attribute__((destructor)) static void freeMemory();
19static void crashHandler(int signo, siginfo_t* info, void*);
20
21// Defined in Darling dyld
22extern char** g_argv asm("NXArgv");
23extern int g_argc asm("NXArgc");
24static char** g_argvCopy = NULL; // out private copy
25static char* g_originalCwd = NULL;
26
27void setSignalHandlers()
28{
29 if (getenv("DARLING_NO_HANDLER") == NULL)
30 {
31 struct sigaction act;
32
33 g_argvCopy = (char**) malloc(sizeof(char**) * (g_argc+1));
34 for (int i = 0; i < g_argc; i++)
35 g_argvCopy[i] = strdup(g_argv[i]);
36 g_argvCopy[g_argc] = NULL;
37
38 g_originalCwd = getcwd(NULL, 0);
39
40 memset(&act, 0, sizeof act);
41 act.sa_sigaction = crashHandler;
42 act.sa_flags = SA_SIGINFO;
43 sigemptyset (&act.sa_mask);
44
45 sigaction(SIGSEGV, &act, NULL);
46 sigaction(SIGABRT, &act, NULL);
47 sigaction(SIGILL, &act, NULL);
48 sigaction(SIGFPE, &act, NULL);
49 sigaction(SIGBUS, &act, NULL);
50 }
51}
52
53void freeMemory()
54{
55 if (g_argvCopy)
56 {
57 for (int i = 0; g_argvCopy[i] != NULL; i++)
58 free(g_argvCopy[i]);
59 free(g_argvCopy);
60 g_argvCopy = NULL;
61 }
62 free(g_originalCwd);
63}
64
65void crashHandler(int signo, siginfo_t* info, void* p)
66{
67 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
68 // Generate a XML file with error description
69 NSXMLElement *root = (NSXMLElement *)[NSXMLNode elementWithName:@"crash"];
70 NSXMLDocument *xmlDoc = [[NSXMLDocument alloc] initWithRootElement:root];
71 NSXMLElement* sroot;
72 NSXMLElement* sub;
73
74 [xmlDoc setVersion:@"1.0"];
75 [xmlDoc setCharacterEncoding:@"UTF-8"];
76
77 // Add runtime information
78 sroot = (NSXMLElement *)[NSXMLNode elementWithName:@"application"];
79 sub = (NSXMLElement *) [NSXMLNode elementWithName: @"wd" stringValue:[NSString stringWithUTF8String: g_originalCwd]];
80 [sroot addChild:sub];
81
82 // Add arguments (to restart the app)
83 sub = (NSXMLElement *)[NSXMLNode elementWithName:@"arguments"];
84 for (int i = 0; i < g_argc; i++)
85 {
86 NSXMLElement* value = (NSXMLElement *)[NSXMLNode elementWithName:@"argument" stringValue:[NSString stringWithUTF8String: g_argvCopy[i]]];
87 [sub addChild: value];
88 }
89 [sroot addChild:sub];
90 [root addChild:sroot];
91
92 // Signal information
93 sroot = (NSXMLElement *) [NSXMLNode elementWithName: @"signal" stringValue:[NSString stringWithFormat: @"%d", info->si_signo ]];
94 [root addChild:sroot];
95
96 // Save the file
97 NSData *xmlData = [xmlDoc XMLDataWithOptions:NSXMLNodePreserveAll];
98 NSString* path = [NSString stringWithFormat: @"/tmp/crashinfo.%d.xml", getpid()];
99 [xmlData writeToFile:path atomically:YES];
100
101 NSLog(@"Crash info stored at %@\n", path);
102
103 [pool release];
104
105 // Execute the crash dialog
106
107 exit(signo);
108}
109
110#ifdef TEST
111int g_argc;
112char** g_argv;
113int main(int argc, char** argv)
114{
115 g_argc = argc;
116 g_argv = argv;
117
118 setSignalHandlers();
119 *((volatile int*) NULL) = 0;
120
121 return 0;
122}
123#endif
124