Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
U
uniset2
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
UniSet project repositories
uniset2
Commits
e21c7412
Commit
e21c7412
authored
Jul 22, 2016
by
Pavel Vainerman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(UniSetActivator): добавил отдельный stack при обработке SIGSEGV
и добавил по умолчанию вывод в cerr.
parent
71329ec7
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
36 additions
and
16 deletions
+36
-16
UniSetActivator.cc
src/ObjectRepository/UniSetActivator.cc
+36
-16
No files found.
src/ObjectRepository/UniSetActivator.cc
View file @
e21c7412
...
...
@@ -52,7 +52,7 @@ using namespace std;
Завершение работы организовано следующим образом:
-------------------------------------------------
Т.к. UniSetActivator в системе только один (singleton), он заказывает на себя
все сигналы связанные с завершением работы, а также устанавливает обработчики на штатный выход из про
раммы (atexit)
все сигналы связанные с завершением работы, а также устанавливает обработчики на штатный выход из прог
раммы (atexit)
и обработчик на выход по исключению (set_terminate).
В качестве обработчика сигналов регистрируется функция activator_terminate( int signo ).
При вызове run() (в функции work) создаётся "глобальный" поток g_term_thread, который
...
...
@@ -77,6 +77,15 @@ using namespace std;
В случае, если для UniSetActivator был создан отдельный поток ( run(true) ) при завершении работы программы
срабатывает обработчик UniSetActivator::normalexit или UniSetActivator::normalterminate, которые
делают тоже самое. Будят процесс завершения.. и дожидаются завершения его работы.
// Обработка SIGSEGV
Для обработки SIGSEGV выделен отдельный обработчик (activator_terminate_with_calltrace),
который выводит stack trace и завершает работу.
Если для ulog включён SYSTEM, то trace выводится в него для возможности (если получиться)
увидеть его удалённо через logserver (если он запушен).
Если не включён, то выводиться в cerr.
Сам обработчик только выводит trace и завершает работу, восстановив обработчик SIGSEGV по умолчанию,
без какой-либо специальной обработки завершения.
*/
// ------------------------------------------------------------------------------------------
static
std
::
shared_ptr
<
UniSetActivator
>
g_act
;
...
...
@@ -104,12 +113,10 @@ static const int KILL_TIMEOUT = 8;
// выделим необходимое для stacktrace зараннее
// ----------
#define FUNCNAMESIZE 256
static
size_t
funcnamesize
=
FUNCNAMESIZE
;
static
char
funcname
[
FUNCNAMESIZE
];
// storage array for stack trace address data
#define MAXFRAMES 64
static
void
*
addrlist
[
MAXFRAMES
];
// выделение специального стека заранее
static
char
g_stack_body
[
MAXFRAMES
*
FUNCNAMESIZE
+
500
];
static
stack_t
g_sigseg_stack
;
// ------------------------------------------------------------------------------------------
// код функции printStackTrace взят с https://oroboro.com/stack-trace-on-crash/
// будет работать только под LINUX (т.к. используется backtrace)
...
...
@@ -118,16 +125,20 @@ static void* addrlist[MAXFRAMES];
// Выводим используя ulog() чтобы можно было удалённо увидеть через LogServer
// (хотя конечно это как повезёт и зависит от того где собственно произошла ошибка)
// ------------------------------------------------------------------------------------------
#define TRACELOG ( to_cerr ? cerr : log->system(false) )
static
inline
void
printStackTrace
()
{
auto
log
=
ulog
();
if
(
!
log
)
return
;
if
(
!
log
->
is_system
()
)
return
;
// если логи отключены, то и выводить не будем
bool
to_cerr
=
(
!
log
||
!
log
->
is_system
()
);
// первый лог выводим с датой, а дальше уже просто
(
to_cerr
?
cerr
:
log
->
system
()
)
<<
"stack trace:
\n
"
;
TRACELOG
<<
"-----------------------------------------"
<<
endl
;
log
->
system
()
<<
"stack trace:
\n
"
;
void
*
addrlist
[
MAXFRAMES
]
;
// retrieve current stack addresses
unsigned
int
addrlen
=
backtrace
(
addrlist
,
MAXFRAMES
);
...
...
@@ -143,7 +154,10 @@ static inline void printStackTrace()
// this array must be free()-ed
char
**
symbollist
=
backtrace_symbols
(
addrlist
,
addrlen
);
log
->
system
()
<<
std
::
left
;
TRACELOG
<<
std
::
left
;
size_t
funcnamesize
=
FUNCNAMESIZE
;
char
funcname
[
FUNCNAMESIZE
];
// iterate over the returned symbol lines. skip the first, it is the
// address of this function.
...
...
@@ -186,7 +200,7 @@ static inline void printStackTrace()
if
(
begin_offset
)
{
log
->
system
()
<<
setw
(
30
)
<<
symbollist
[
i
]
TRACELOG
<<
setw
(
30
)
<<
symbollist
[
i
]
<<
" ( "
<<
setw
(
40
)
<<
fname
<<
" +"
<<
setw
(
6
)
<<
begin_offset
<<
") "
<<
end_offset
...
...
@@ -194,7 +208,7 @@ static inline void printStackTrace()
}
else
{
log
->
system
()
<<
setw
(
30
)
<<
symbollist
[
i
]
TRACELOG
<<
setw
(
30
)
<<
symbollist
[
i
]
<<
" ( "
<<
setw
(
40
)
<<
fname
<<
" "
<<
setw
(
6
)
<<
""
<<
") "
<<
end_offset
...
...
@@ -204,12 +218,12 @@ static inline void printStackTrace()
else
{
// couldn't parse the line? print the whole line.
log
->
system
()
<<
setw
(
40
)
<<
symbollist
[
i
]
<<
endl
;
TRACELOG
<<
setw
(
40
)
<<
symbollist
[
i
]
<<
endl
;
}
}
std
::
free
(
symbollist
);
log
->
system
()
<<
endl
<<
"..end of trace..
"
<<
endl
<<
flush
;
TRACELOG
<<
"-----------------------------------------
"
<<
endl
<<
flush
;
}
// ------------------------------------------------------------------------------------------
static
void
activator_terminate
(
int
signo
)
...
...
@@ -722,6 +736,12 @@ void UniSetActivator::set_signals(bool ask)
act
.
sa_flags
|=
SA_RESTART
;
act
.
sa_flags
|=
SA_RESETHAND
;
g_sigseg_stack
.
ss_sp
=
g_stack_body
;
g_sigseg_stack
.
ss_flags
=
SS_ONSTACK
;
g_sigseg_stack
.
ss_size
=
sizeof
(
g_stack_body
);
assert
(
!
sigaltstack
(
&
g_sigseg_stack
,
nullptr
));
act
.
sa_flags
|=
SA_ONSTACK
;
if
(
ask
)
act
.
sa_handler
=
activator_terminate_with_calltrace
;
else
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment