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 <team.h>
|
||||
#include <thread.h>
|
||||
#include <tracing.h>
|
||||
#include <user_debugger.h>
|
||||
#include <util/AutoLock.h>
|
||||
|
||||
@@ -32,6 +33,7 @@
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
//#define SIGNAL_TRACING
|
||||
|
||||
#define BLOCKABLE_SIGNALS (~(KILL_SIGNALS | SIGNAL_TO_MASK(SIGSTOP)))
|
||||
#define STOP_SIGNALS \
|
||||
@@ -54,6 +56,136 @@ static status_t deliver_signal(struct thread *thread, uint signal,
|
||||
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.
|
||||
Interrupts must be disabled and the thread lock must be held.
|
||||
*/
|
||||
@@ -121,6 +253,8 @@ handle_signals(struct thread *thread)
|
||||
if (signalMask == 0)
|
||||
return 0;
|
||||
|
||||
T(HandleSignals(signalMask));
|
||||
|
||||
for (i = 0; i < NSIG; i++) {
|
||||
bool debugSignal;
|
||||
int32 signal = i + 1;
|
||||
@@ -401,6 +535,8 @@ send_signal_etc(pid_t id, uint signal, uint32 flags)
|
||||
if (signal < 0 || signal > MAX_SIGNO)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
T(SendSignal(id, signal, flags));
|
||||
|
||||
if ((flags & SIGNAL_FLAG_TEAMS_LOCKED) == 0)
|
||||
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);
|
||||
|
||||
if (set != NULL) {
|
||||
T(SigProcMask(how, *set));
|
||||
|
||||
switch (how) {
|
||||
case SIG_BLOCK:
|
||||
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) {
|
||||
T(SigAction(thread, signal, act));
|
||||
|
||||
// set new sigaction structure
|
||||
memcpy(&thread->sig_action[signal - 1], act,
|
||||
sizeof(struct sigaction));
|
||||
|
||||
Reference in New Issue
Block a user