Kernel tracing for signals.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23621 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
#include <sem.h>
|
#include <sem.h>
|
||||||
#include <team.h>
|
#include <team.h>
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
|
#include <tracing.h>
|
||||||
#include <user_debugger.h>
|
#include <user_debugger.h>
|
||||||
#include <util/AutoLock.h>
|
#include <util/AutoLock.h>
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@
|
|||||||
# define TRACE(x) ;
|
# define TRACE(x) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//#define SIGNAL_TRACING
|
||||||
|
|
||||||
#define BLOCKABLE_SIGNALS (~(KILL_SIGNALS | SIGNAL_TO_MASK(SIGSTOP)))
|
#define BLOCKABLE_SIGNALS (~(KILL_SIGNALS | SIGNAL_TO_MASK(SIGSTOP)))
|
||||||
#define STOP_SIGNALS \
|
#define STOP_SIGNALS \
|
||||||
@@ -54,6 +56,136 @@ static status_t deliver_signal(struct thread *thread, uint signal,
|
|||||||
uint32 flags);
|
uint32 flags);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - signal tracing
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SIGNAL_TRACING
|
||||||
|
|
||||||
|
namespace SignalTracing {
|
||||||
|
|
||||||
|
|
||||||
|
class HandleSignals : public AbstractTraceEntry {
|
||||||
|
public:
|
||||||
|
HandleSignals(uint32 signals)
|
||||||
|
:
|
||||||
|
fSignals(signals)
|
||||||
|
{
|
||||||
|
Initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void AddDump(char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
snprintf(buffer, size, "signal handle: 0x%lx",
|
||||||
|
fSignals);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32 fSignals;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SendSignal : public AbstractTraceEntry {
|
||||||
|
public:
|
||||||
|
SendSignal(pid_t target, uint32 signal, uint32 flags)
|
||||||
|
:
|
||||||
|
fTarget(target),
|
||||||
|
fSignal(signal),
|
||||||
|
fFlags(flags)
|
||||||
|
{
|
||||||
|
Initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void AddDump(char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
snprintf(buffer, size, "signal send: target: %ld, signal: %lu "
|
||||||
|
"(%s), flags: 0x%lx", fTarget, fSignal,
|
||||||
|
(fSignal < NSIG ? sigstr[fSignal] : "invalid"), fFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
pid_t fTarget;
|
||||||
|
uint32 fSignal;
|
||||||
|
uint32 fFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SigAction : public AbstractTraceEntry {
|
||||||
|
public:
|
||||||
|
SigAction(struct thread* thread, uint32 signal,
|
||||||
|
const struct sigaction* act)
|
||||||
|
:
|
||||||
|
fThread(thread->id),
|
||||||
|
fSignal(signal),
|
||||||
|
fAction(*act)
|
||||||
|
{
|
||||||
|
Initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void AddDump(char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
snprintf(buffer, size, "signal action: thread: %ld, signal: %lu "
|
||||||
|
"(%s), action: {handler: %p, flags: 0x%x, mask: 0x%lx}",
|
||||||
|
fThread, fSignal,
|
||||||
|
(fSignal < NSIG ? sigstr[fSignal] : "invalid"),
|
||||||
|
fAction.sa_handler, fAction.sa_flags, fAction.sa_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
thread_id fThread;
|
||||||
|
uint32 fSignal;
|
||||||
|
struct sigaction fAction;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SigProcMask : public AbstractTraceEntry {
|
||||||
|
public:
|
||||||
|
SigProcMask(int how, sigset_t mask)
|
||||||
|
:
|
||||||
|
fHow(how),
|
||||||
|
fMask(mask),
|
||||||
|
fOldMask(thread_get_current_thread()->sig_block_mask)
|
||||||
|
{
|
||||||
|
Initialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void AddDump(char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
const char* how = "invalid";
|
||||||
|
switch (fHow) {
|
||||||
|
case SIG_BLOCK:
|
||||||
|
how = "block";
|
||||||
|
break;
|
||||||
|
case SIG_UNBLOCK:
|
||||||
|
how = "unblock";
|
||||||
|
break;
|
||||||
|
case SIG_SETMASK:
|
||||||
|
how = "set";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buffer, size, "signal proc mask: %s 0x%lx, "
|
||||||
|
"old mask: 0x%lx", how, fMask, fOldMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int fHow;
|
||||||
|
sigset_t fMask;
|
||||||
|
sigset_t fOldMask;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace SignalTracing
|
||||||
|
|
||||||
|
# define T(x) new(std::nothrow) SignalTracing::x
|
||||||
|
|
||||||
|
#else
|
||||||
|
# define T(x)
|
||||||
|
#endif // SIGNAL_TRACING
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
/*! Updates the thread::flags field according to what signals are pending.
|
/*! Updates the thread::flags field according to what signals are pending.
|
||||||
Interrupts must be disabled and the thread lock must be held.
|
Interrupts must be disabled and the thread lock must be held.
|
||||||
*/
|
*/
|
||||||
@@ -121,6 +253,8 @@ handle_signals(struct thread *thread)
|
|||||||
if (signalMask == 0)
|
if (signalMask == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
T(HandleSignals(signalMask));
|
||||||
|
|
||||||
for (i = 0; i < NSIG; i++) {
|
for (i = 0; i < NSIG; i++) {
|
||||||
bool debugSignal;
|
bool debugSignal;
|
||||||
int32 signal = i + 1;
|
int32 signal = i + 1;
|
||||||
@@ -401,6 +535,8 @@ send_signal_etc(pid_t id, uint signal, uint32 flags)
|
|||||||
if (signal < 0 || signal > MAX_SIGNO)
|
if (signal < 0 || signal > MAX_SIGNO)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
T(SendSignal(id, signal, flags));
|
||||||
|
|
||||||
if ((flags & SIGNAL_FLAG_TEAMS_LOCKED) == 0)
|
if ((flags & SIGNAL_FLAG_TEAMS_LOCKED) == 0)
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
|
|
||||||
@@ -498,6 +634,8 @@ sigprocmask(int how, const sigset_t *set, sigset_t *oldSet)
|
|||||||
sigset_t oldMask = atomic_get(&thread->sig_block_mask);
|
sigset_t oldMask = atomic_get(&thread->sig_block_mask);
|
||||||
|
|
||||||
if (set != NULL) {
|
if (set != NULL) {
|
||||||
|
T(SigProcMask(how, *set));
|
||||||
|
|
||||||
switch (how) {
|
switch (how) {
|
||||||
case SIG_BLOCK:
|
case SIG_BLOCK:
|
||||||
atomic_or(&thread->sig_block_mask, *set & BLOCKABLE_SIGNALS);
|
atomic_or(&thread->sig_block_mask, *set & BLOCKABLE_SIGNALS);
|
||||||
@@ -555,6 +693,8 @@ sigaction_etc(thread_id threadID, int signal, const struct sigaction *act,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (act) {
|
if (act) {
|
||||||
|
T(SigAction(thread, signal, act));
|
||||||
|
|
||||||
// set new sigaction structure
|
// set new sigaction structure
|
||||||
memcpy(&thread->sig_action[signal - 1], act,
|
memcpy(&thread->sig_action[signal - 1], act,
|
||||||
sizeof(struct sigaction));
|
sizeof(struct sigaction));
|
||||||
|
|||||||
Reference in New Issue
Block a user