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
7ea7bb95
Commit
7ea7bb95
authored
Jul 28, 2016
by
Pavel Vainerman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(UActivator): Пока что убрал pipe, т.к. приводит к зависанию на получении
stack trace.
parent
175b0632
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
32 additions
and
47 deletions
+32
-47
libuniset2.spec
conf/libuniset2.spec
+4
-1
abort-script-example.sh
extensions/tests/SMemoryTest/abort-script-example.sh
+1
-1
UniSetActivator.cc
src/ObjectRepository/UniSetActivator.cc
+27
-45
No files found.
conf/libuniset2.spec
View file @
7ea7bb95
...
...
@@ -14,7 +14,7 @@
Name: libuniset2
Version: 2.4
Release: alt3
Release: alt3
.1
Summary: UniSet - library for building distributed industrial control systems
License: LGPL
...
...
@@ -484,6 +484,9 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
# ..
%changelog
* Thu Jul 28 2016 Pavel Vainerman <pv@altlinux.ru> 2.4-alt3.1
- test build
* Tue Jul 26 2016 Pavel Vainerman <pv@altlinux.ru> 2.4-alt3
- merge devel/master
...
...
extensions/tests/SMemoryTest/abort-script-example.sh
View file @
7ea7bb95
#!/bin/sh
gdb
--batch
-n
-ex
"thread apply all bt"
$1
$2
exec
gdb
--batch
-n
-ex
"thread apply all bt"
$1
$2
# | ssh xxxxxx
# gcore $2
src/ObjectRepository/UniSetActivator.cc
View file @
7ea7bb95
...
...
@@ -22,6 +22,7 @@
#include <sys/types.h>
#include <signal.h>
#include <sstream>
#include <fstream>
#include <condition_variable>
#include <thread>
...
...
@@ -110,9 +111,9 @@ static std::condition_variable g_trace_doneevent;
static
std
::
shared_ptr
<
std
::
thread
>
g_term_thread
;
static
std
::
shared_ptr
<
std
::
thread
>
g_fini_thread
;
static
std
::
shared_ptr
<
std
::
thread
>
g_kill_thread
;
static
const
int
TERMINATE_TIMEOUT
=
3
;
// время отведенное на завершение процесса [сек]
static
const
int
TERMINATE_TIMEOUT
_SEC
=
3
;
// время отведенное на завершение процесса [сек]
static
const
int
THREAD_TERMINATE_PAUSE
=
500
;
// [мсек] пауза при завершении потока (см. work())
static
const
int
KILL_TIMEOUT
=
8
;
static
const
int
KILL_TIMEOUT
_SEC
=
8
;
static
pid_t
g_stacktrace_proc_pid
=
0
;
// pid процесса делающего stack trace (для защиты от зависания)
// ------------------------------------------------------------------------------------------
// Чтобы не выделять память во время "вылета",
...
...
@@ -123,6 +124,7 @@ static pid_t g_stacktrace_proc_pid = 0; // pid процесса делающег
// выделение специального стека заранее
// +60 - это на всякие переменные при обработке stack trace и т.п.
static
char
g_stack_body
[(
MAXFRAMES
+
60
)
*
FUNCNAMESIZE
];
static
char
trace_buf
[
10000
];
static
stack_t
g_sigseg_stack
;
static
void
on_stacktrace_timeout
();
// поток для защиты от зависания "процесса создания stack trace"
// ------------------------------------------------------------------------------------------
...
...
@@ -247,13 +249,7 @@ bool gdb_print_trace()
char
name_buf
[
512
];
name_buf
[
readlink
(
"/proc/self/exe"
,
name_buf
,
511
)]
=
0
;
// Чтобы перенаправить вывод в свой log, делаем pipe
int
cp
[
2
];
/* Child to parent pipe */
if
(
pipe
(
cp
)
<
0
)
{
perror
(
"Can't make pipe"
);
return
false
;
}
TRACELOG
<<
"stack trace: for "
<<
name_buf
<<
" pid="
<<
pid_buf
<<
endl
;
int
child_pid
=
fork
();
...
...
@@ -263,18 +259,12 @@ bool gdb_print_trace()
return
false
;
}
if
(
!
child_pid
)
{
close
(
cp
[
0
]);
close
(
fileno
(
stdout
)
);
dup2
(
cp
[
1
],
fileno
(
stdout
));
close
(
fileno
(
stderr
)
);
dup2
(
fileno
(
stdout
),
fileno
(
stderr
));
TRACELOG
<<
"stack trace for "
<<
name_buf
<<
" pid="
<<
pid_buf
<<
endl
;
if
(
child_pid
==
0
)
// CHILD
{
msleep
(
300
);
// пауза чтобы родитель успел подготовиться..
if
(
g_act
&&
!
g_act
->
getAbortScript
().
empty
()
)
{
TRACELOG
<<
"run abort script "
<<
g_act
->
getAbortScript
()
<<
endl
;
execlp
(
g_act
->
getAbortScript
().
c_str
(),
g_act
->
getAbortScript
().
c_str
(),
name_buf
,
pid_buf
,
NULL
);
}
else
...
...
@@ -284,38 +274,24 @@ bool gdb_print_trace()
execlp
(
"gdb"
,
"gdb"
,
"--batch"
,
"-n"
,
"-ex"
,
"thread apply all bt"
,
name_buf
,
pid_buf
,
NULL
);
}
//abort(); /* If gdb failed to start */
//
abort(); /* If gdb failed to start */
return
false
;
}
else
else
// PARENT
{
close
(
cp
[
1
]);
if
(
g_act
&&
!
g_act
->
getAbortScript
().
empty
()
)
{
TRACELOG
<<
"stack trace: run script "
<<
g_act
->
getAbortScript
()
<<
endl
;
}
g_stacktrace_proc_pid
=
child_pid
;
g_trace_done
=
false
;
std
::
thread
t
(
on_stacktrace_timeout
);
// запускаем поток "защищающий" от зависания процесса создания stack trace
char
buf
[
FUNCNAMESIZE
];
// как минимум у нас есть буфер такого размера выделенный зараннее
while
(
true
)
{
ssize_t
r
=
::
read
(
cp
[
0
],
&
buf
,
sizeof
(
buf
)
-
1
);
if
(
r
>
0
)
{
buf
[
r
]
=
'\0'
;
TRACELOG
<<
buf
;
continue
;
}
break
;
}
waitpid
(
child_pid
,
NULL
,
0
);
{
std
::
unique_lock
<
std
::
mutex
>
lk
(
g_trace_donemutex
);
g_trace_done
=
true
;
g_trace_doneevent
.
notify_all
();
}
g_trace_done
=
true
;
g_trace_doneevent
.
notify_all
();
t
.
join
();
}
...
...
@@ -325,8 +301,10 @@ bool gdb_print_trace()
// ------------------------------------------------------------------------------------------
static
void
on_stacktrace_timeout
()
{
ulogsys
<<
"****** STACK TRACE guard thread start (for pid="
<<
g_stacktrace_proc_pid
<<
") ******"
<<
endl
<<
flush
;
std
::
unique_lock
<
std
::
mutex
>
lk
(
g_trace_donemutex
);
g_trace_doneevent
.
wait_for
(
lk
,
std
::
chrono
::
milliseconds
(
KILL_TIMEOUT
*
1000
),
[]()
g_trace_doneevent
.
wait_for
(
lk
,
std
::
chrono
::
milliseconds
(
KILL_TIMEOUT_SEC
*
1000
),
[]()
{
return
(
g_trace_done
==
true
);
}
);
...
...
@@ -336,6 +314,8 @@ static void on_stacktrace_timeout()
ulogsys
<<
"****** STACK TRACE TIMEOUT.. (kill process) *******"
<<
endl
<<
flush
;
kill
(
g_stacktrace_proc_pid
,
SIGKILL
);
}
else
ulogsys
<<
"****** STACK TRACE guard thread finish ******"
<<
endl
<<
flush
;
}
// ------------------------------------------------------------------------------------------
static
void
activator_terminate
(
int
signo
)
...
...
@@ -389,7 +369,7 @@ void finished_thread()
g_finished
=
true
;
std
::
unique_lock
<
std
::
mutex
>
lkw
(
g_workmutex
);
g_finievent
.
wait_for
(
lkw
,
std
::
chrono
::
milliseconds
(
TERMINATE_TIMEOUT
*
1000
),
[]()
g_finievent
.
wait_for
(
lkw
,
std
::
chrono
::
milliseconds
(
TERMINATE_TIMEOUT
_SEC
*
1000
),
[]()
{
return
(
g_work_stopped
==
true
);
}
);
...
...
@@ -403,7 +383,7 @@ void on_finish_timeout()
if
(
g_done
)
return
;
g_doneevent
.
wait_for
(
lk
,
std
::
chrono
::
milliseconds
(
KILL_TIMEOUT
*
1000
),
[]()
g_doneevent
.
wait_for
(
lk
,
std
::
chrono
::
milliseconds
(
KILL_TIMEOUT
_SEC
*
1000
),
[]()
{
return
(
g_done
==
true
);
}
);
...
...
@@ -851,14 +831,16 @@ void UniSetActivator::set_signals(bool ask)
sigemptyset
(
&
act
.
sa_mask
);
sigaddset
(
&
act
.
sa_mask
,
SIGSEGV
);
act
.
sa_flags
=
0
;
act
.
sa_flags
|=
SA_RESTART
;
//
act.sa_flags |= SA_RESTART;
act
.
sa_flags
|=
SA_RESETHAND
;
#if 1
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
;
#endif
if
(
ask
)
act
.
sa_handler
=
activator_terminate_with_calltrace
;
...
...
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