-
Notifications
You must be signed in to change notification settings - Fork 296
/
main.cpp
181 lines (169 loc) · 5.72 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-CurrentYear, Open Source Modelica Consortium (OSMC),
* c/o Linköpings universitet, Department of Computer and Information Science,
* SE-58183 Linköping, Sweden.
*
* All rights reserved.
*
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR
* THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2.
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
* RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3,
* ACCORDING TO RECIPIENTS CHOICE.
*
* The OpenModelica software and the Open Source Modelica
* Consortium (OSMC) Public License (OSMC-PL) are obtained
* from OSMC, either from the above address,
* from the URLs: http://www.ida.liu.se/projects/OpenModelica or
* http://www.openmodelica.org, and in the OpenModelica distribution.
* GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
*
* This program is distributed WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
*
* See the full OSMC Public License conditions for more details.
*
*/
/*
* @author Adeel Asghar <adeel.asghar@liu.se>
*/
/*!
* \mainpage OMEdit - OpenModelica Connection Editor Documentation
* Source code documentation. Provides brief information about the classes used.
*/
#include "OMEditApplication.h"
#include "CrashReport/CrashReportDialog.h"
#define GC_THREADS
extern "C" {
#include "meta/meta_modelica.h"
}
#include <QMessageBox>
#ifdef QT_NO_DEBUG
#ifdef WIN32
#include "CrashReport/backtrace.h"
static char *g_output = NULL;
LONG WINAPI exceptionFilter(LPEXCEPTION_POINTERS info)
{
if (g_output == NULL) {
g_output = (char*) malloc(BUFFER_MAX);
}
struct output_buffer ob;
output_init(&ob, g_output, BUFFER_MAX);
if (!SymInitialize(GetCurrentProcess(), 0, TRUE)) {
output_print(&ob,"Failed to init symbol context\n");
} else {
bfd_init();
struct bfd_set *set = (bfd_set*)calloc(1,sizeof(*set));
_backtrace(&ob , set , 128 , info->ContextRecord);
release_set(set);
SymCleanup(GetCurrentProcess());
}
// show the CrashReportDialog
CrashReportDialog *pCrashReportDialog = new CrashReportDialog(QString(g_output));
pCrashReportDialog->exec();
exit(1);
}
#else // Unix
#include <signal.h>
#include <execinfo.h>
void signalHandler(int signalNumber)
{
// associate each signal with a signal name string.
const char* signalName = NULL;
switch (signalNumber) {
case SIGABRT: signalName = "SIGABRT"; break;
case SIGSEGV: signalName = "SIGSEGV"; break;
case SIGILL: signalName = "SIGILL"; break;
case SIGFPE: signalName = "SIGFPE"; break;
default: break;
}
QString stackTrace;
if (signalName) {
stackTrace.append(QString("Caught signal %1 (%2)\n").arg(QString::number(signalNumber)).arg(signalName));
} else {
stackTrace.append(QString("Caught signal %1\n").arg(QString::number(signalNumber)));
}
// storage array for stack trace address data
unsigned int max_frames = 50;
void* addrlist[max_frames+1];
// retrieve current stack addresses
int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*));
if (addrlen == 0) {
stackTrace.append("Stack address length is empty.\n");
} else {
// create readable strings to each frame.
char** symbollist = backtrace_symbols(addrlist, addrlen);
// print the stack trace.
for (int i = 0; i < addrlen; i++) {
stackTrace.append(QString("%1\n").arg(symbollist[i]));
char syscom[PATH_MAX];
sprintf(syscom,"addr2line %p -e %s > addr2lineOutput.txt", addrlist[i], qApp->applicationFilePath().toStdString().c_str());
system(syscom);
QFile file(QString("addr2lineOutput.txt"));
if (file.open(QIODevice::ReadOnly)) {
stackTrace.append(QString(file.readAll()));
file.close();
} else {
stackTrace.append(QString("Cannot read addr2lineOutput.txt file %1. addr2line has probably failed.").arg(file.errorString()));
}
}
free(symbollist);
}
// show the CrashReportDialog
CrashReportDialog *pCrashReportDialog = new CrashReportDialog(stackTrace);
pCrashReportDialog->exec();
exit(signalNumber);
}
#endif // #ifdef WIN32
#endif // #ifdef QT_NO_DEBUG
void printOMEditUsage()
{
printf("Usage: OMEdit --Debug=true|false] [files]\n");
printf(" --Debug=[true|false] Enables the debugging features like QUndoView, diffModelicaFileListings view. Default is false.\n");
printf(" files List of Modelica files(*.mo) to open.\n");
}
static int execution_failed()
{
fflush(NULL);
fprintf(stderr, "Execution failed!\n");
fflush(NULL);
return 1;
}
int main(int argc, char *argv[])
{
MMC_INIT();
MMC_TRY_TOP()
/* Do not use the signal handler OR exception filter if user is building a debug version. Perhaps the user wants to use gdb. */
#ifdef QT_NO_DEBUG
#ifdef WIN32
SetUnhandledExceptionFilter(exceptionFilter);
#else
/* Abnormal termination (abort) */
signal(SIGABRT, signalHandler);
/* Segmentation violation */
signal(SIGSEGV, signalHandler);
/* Illegal instruction */
signal(SIGILL, signalHandler);
/* Floating point error */
signal(SIGFPE, signalHandler);
#endif // #ifdef WIN32
#endif // #ifdef QT_NO_DEBUG
// if user asks for --help
for(int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--help") == 0) {
printOMEditUsage();
return 0;
}
}
Q_INIT_RESOURCE(resource_omedit);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
OMEditApplication a(argc, argv, threadData);
return a.exec();
MMC_CATCH_TOP(return execution_failed());
}