strace: handle parallel syscalls on different threads
If a thread executes a system call and meanwhile a different thread calls another one, then the ongoing call is marked as unfinished. When the call returns it will be marked as resumed. * remove PreSyscall, now unused. Change-Id: Iea45b866be2c40568d766c2ed3cc73e34b9d1293 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4765 Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
f18aba2ca8
commit
949005a59b
@@ -109,21 +109,10 @@ public:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsPreSyscall() const
|
|
||||||
{
|
|
||||||
return fPreSyscall;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPreSyscall(bool preSyscall)
|
|
||||||
{
|
|
||||||
fPreSyscall = preSyscall;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
string fName;
|
string fName;
|
||||||
Type *fReturnType;
|
Type *fReturnType;
|
||||||
vector<Parameter*> fParameters;
|
vector<Parameter*> fParameters;
|
||||||
bool fPreSyscall;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // STRACE_SYSCALL_H
|
#endif // STRACE_SYSCALL_H
|
||||||
|
|||||||
@@ -196,7 +196,8 @@ struct Team {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set team debugging flags
|
// set team debugging flags
|
||||||
int32 teamDebugFlags = (traceTeam ? B_TEAM_DEBUG_POST_SYSCALL : 0)
|
int32 teamDebugFlags =
|
||||||
|
(traceTeam ? B_TEAM_DEBUG_PRE_SYSCALL | B_TEAM_DEBUG_POST_SYSCALL : 0)
|
||||||
| (traceChildTeams ? B_TEAM_DEBUG_TEAM_CREATION : 0)
|
| (traceChildTeams ? B_TEAM_DEBUG_TEAM_CREATION : 0)
|
||||||
| (traceSignal ? B_TEAM_DEBUG_SIGNALS : 0);
|
| (traceSignal ? B_TEAM_DEBUG_SIGNALS : 0);
|
||||||
if (set_team_debugging_flags(fNubPort, teamDebugFlags) != B_OK)
|
if (set_team_debugging_flags(fNubPort, teamDebugFlags) != B_OK)
|
||||||
@@ -264,11 +265,9 @@ patch_syscalls()
|
|||||||
patch_ioctl();
|
patch_ioctl();
|
||||||
|
|
||||||
Syscall *poll = get_syscall("_kern_poll");
|
Syscall *poll = get_syscall("_kern_poll");
|
||||||
poll->SetPreSyscall(true);
|
|
||||||
poll->ParameterAt(0)->SetInOut(true);
|
poll->ParameterAt(0)->SetInOut(true);
|
||||||
|
|
||||||
Syscall *select = get_syscall("_kern_select");
|
Syscall *select = get_syscall("_kern_select");
|
||||||
select->SetPreSyscall(true);
|
|
||||||
select->ParameterAt(1)->SetInOut(true);
|
select->ParameterAt(1)->SetInOut(true);
|
||||||
select->ParameterAt(2)->SetInOut(true);
|
select->ParameterAt(2)->SetInOut(true);
|
||||||
select->ParameterAt(3)->SetInOut(true);
|
select->ParameterAt(3)->SetInOut(true);
|
||||||
@@ -350,7 +349,7 @@ print_to_string(char **_buffer, int32 *_length, const char *format, ...)
|
|||||||
static void
|
static void
|
||||||
print_syscall(FILE *outputFile, Syscall* syscall, debug_pre_syscall &message,
|
print_syscall(FILE *outputFile, Syscall* syscall, debug_pre_syscall &message,
|
||||||
MemoryReader &memoryReader, bool printArguments, uint32 contentsFlags,
|
MemoryReader &memoryReader, bool printArguments, uint32 contentsFlags,
|
||||||
bool colorize, bool decimal)
|
bool colorize, bool decimal, thread_id ¤tThreadID)
|
||||||
{
|
{
|
||||||
char buffer[4096], *string = buffer;
|
char buffer[4096], *string = buffer;
|
||||||
int32 length = (int32)sizeof(buffer);
|
int32 length = (int32)sizeof(buffer);
|
||||||
@@ -358,6 +357,12 @@ print_syscall(FILE *outputFile, Syscall* syscall, debug_pre_syscall &message,
|
|||||||
Context ctx(syscall, (char *)message.args, memoryReader,
|
Context ctx(syscall, (char *)message.args, memoryReader,
|
||||||
contentsFlags | Context::INPUT_VALUES, decimal);
|
contentsFlags | Context::INPUT_VALUES, decimal);
|
||||||
|
|
||||||
|
if (currentThreadID != message.origin.thread) {
|
||||||
|
if (currentThreadID != -1)
|
||||||
|
print_to_string(&string, &length, " <unfinished ...>\n");
|
||||||
|
currentThreadID = message.origin.thread;
|
||||||
|
}
|
||||||
|
|
||||||
// print syscall name, without the "_kern_"
|
// print syscall name, without the "_kern_"
|
||||||
if (colorize) {
|
if (colorize) {
|
||||||
print_to_string(&string, &length, "[%6" B_PRId32 "] %s%s%s(",
|
print_to_string(&string, &length, "[%6" B_PRId32 "] %s%s%s(",
|
||||||
@@ -393,45 +398,38 @@ print_syscall(FILE *outputFile, Syscall* syscall, debug_pre_syscall &message,
|
|||||||
static void
|
static void
|
||||||
print_syscall(FILE *outputFile, Syscall* syscall, debug_post_syscall &message,
|
print_syscall(FILE *outputFile, Syscall* syscall, debug_post_syscall &message,
|
||||||
MemoryReader &memoryReader, bool printArguments, uint32 contentsFlags,
|
MemoryReader &memoryReader, bool printArguments, uint32 contentsFlags,
|
||||||
bool printReturnValue, bool colorize, bool decimal)
|
bool printReturnValue, bool colorize, bool decimal,
|
||||||
|
thread_id ¤tThreadID)
|
||||||
{
|
{
|
||||||
char buffer[4096], *string = buffer;
|
char buffer[4096], *string = buffer;
|
||||||
int32 length = (int32)sizeof(buffer);
|
int32 length = (int32)sizeof(buffer);
|
||||||
|
bool threadChanged = false;
|
||||||
|
|
||||||
Context ctx(syscall, (char *)message.args, memoryReader,
|
Context ctx(syscall, (char *)message.args, memoryReader,
|
||||||
contentsFlags | Context::OUTPUT_VALUES, decimal, message.return_value);
|
contentsFlags | Context::OUTPUT_VALUES, decimal, message.return_value);
|
||||||
|
|
||||||
if (!syscall->IsPreSyscall()) {
|
if (currentThreadID != message.origin.thread) {
|
||||||
// print syscall name, without the "_kern_"
|
if (currentThreadID != -1) {
|
||||||
if (colorize) {
|
print_to_string(&string, &length, " <unfinished ...>\n");
|
||||||
print_to_string(&string, &length, "[%6" B_PRId32 "] %s%s%s(",
|
|
||||||
message.origin.thread, kTerminalTextBlue,
|
|
||||||
syscall->Name().c_str() + 6, kTerminalTextNormal);
|
|
||||||
} else {
|
|
||||||
print_to_string(&string, &length, "[%6" B_PRId32 "] %s(",
|
|
||||||
message.origin.thread, syscall->Name().c_str() + 6);
|
|
||||||
}
|
}
|
||||||
|
threadChanged = true;
|
||||||
// print arguments
|
|
||||||
if (printArguments) {
|
|
||||||
int32 count = syscall->CountParameters();
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
|
||||||
// get the value
|
|
||||||
Parameter *parameter = syscall->ParameterAt(i);
|
|
||||||
TypeHandler *handler = parameter->Handler();
|
|
||||||
::string value =
|
|
||||||
handler->GetParameterValue(ctx, parameter,
|
|
||||||
ctx.GetValue(parameter));
|
|
||||||
|
|
||||||
print_to_string(&string, &length, (i > 0 ? ", %s" : "%s"),
|
|
||||||
value.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
print_to_string(&string, &length, ")");
|
|
||||||
}
|
}
|
||||||
|
currentThreadID = -1;
|
||||||
|
|
||||||
// print return value
|
// print return value
|
||||||
if (printReturnValue) {
|
if (printReturnValue) {
|
||||||
|
if (threadChanged) {
|
||||||
|
// print syscall name, without the "_kern_"
|
||||||
|
if (colorize) {
|
||||||
|
print_to_string(&string, &length, "[%6" B_PRId32 "] <... "
|
||||||
|
"%s%s%s resumed> ", message.origin.thread, kTerminalTextBlue,
|
||||||
|
syscall->Name().c_str() + 6, kTerminalTextNormal);
|
||||||
|
} else {
|
||||||
|
print_to_string(&string, &length, "[%6" B_PRId32 "] <... %s"
|
||||||
|
" resumed> ", message.origin.thread,
|
||||||
|
syscall->Name().c_str() + 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
Type *returnType = syscall->ReturnType();
|
Type *returnType = syscall->ReturnType();
|
||||||
TypeHandler *handler = returnType->Handler();
|
TypeHandler *handler = returnType->Handler();
|
||||||
::string value = handler->GetReturnValue(ctx, message.return_value);
|
::string value = handler->GetReturnValue(ctx, message.return_value);
|
||||||
@@ -449,28 +447,26 @@ print_syscall(FILE *outputFile, Syscall* syscall, debug_post_syscall &message,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (syscall->IsPreSyscall()) {
|
// print arguments
|
||||||
// print arguments
|
if (printArguments) {
|
||||||
if (printArguments) {
|
int32 count = syscall->CountParameters();
|
||||||
int32 count = syscall->CountParameters();
|
int added = 0;
|
||||||
int added = 0;
|
print_to_string(&string, &length, " (");
|
||||||
print_to_string(&string, &length, " (");
|
for (int32 i = 0; i < count; i++) {
|
||||||
for (int32 i = 0; i < count; i++) {
|
// get the value
|
||||||
// get the value
|
Parameter *parameter = syscall->ParameterAt(i);
|
||||||
Parameter *parameter = syscall->ParameterAt(i);
|
if (!parameter->InOut())
|
||||||
if (!parameter->InOut())
|
continue;
|
||||||
continue;
|
TypeHandler *handler = parameter->Handler();
|
||||||
TypeHandler *handler = parameter->Handler();
|
::string value =
|
||||||
::string value =
|
handler->GetParameterValue(ctx, parameter,
|
||||||
handler->GetParameterValue(ctx, parameter,
|
ctx.GetValue(parameter));
|
||||||
ctx.GetValue(parameter));
|
|
||||||
|
|
||||||
print_to_string(&string, &length, (added > 0 ? ", %s" : "%s"),
|
print_to_string(&string, &length, (added > 0 ? ", %s" : "%s"),
|
||||||
value.c_str());
|
value.c_str());
|
||||||
added++;
|
added++;
|
||||||
}
|
|
||||||
print_to_string(&string, &length, ")");
|
|
||||||
}
|
}
|
||||||
|
print_to_string(&string, &length, ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colorize) {
|
if (colorize) {
|
||||||
@@ -775,6 +771,8 @@ main(int argc, const char *const *argv)
|
|||||||
resume_thread(threadID);
|
resume_thread(threadID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread_id currentThreadID = -1;
|
||||||
|
|
||||||
// debug loop
|
// debug loop
|
||||||
while (true) {
|
while (true) {
|
||||||
bool quitLoop = false;
|
bool quitLoop = false;
|
||||||
@@ -810,10 +808,10 @@ main(int argc, const char *const *argv)
|
|||||||
}
|
}
|
||||||
Syscall* syscall = sSyscallVector[syscallNumber];
|
Syscall* syscall = sSyscallVector[syscallNumber];
|
||||||
|
|
||||||
if (syscall->IsPreSyscall() && trace) {
|
if (trace) {
|
||||||
print_syscall(outputFile, syscall, message.pre_syscall,
|
print_syscall(outputFile, syscall, message.pre_syscall,
|
||||||
memoryReader, printArguments, contentsFlags,
|
memoryReader, printArguments, contentsFlags,
|
||||||
colorize, decimalFormat);
|
colorize, decimalFormat, currentThreadID);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -841,7 +839,8 @@ main(int argc, const char *const *argv)
|
|||||||
if (trace) {
|
if (trace) {
|
||||||
print_syscall(outputFile, syscall, message.post_syscall,
|
print_syscall(outputFile, syscall, message.post_syscall,
|
||||||
memoryReader, printArguments, contentsFlags,
|
memoryReader, printArguments, contentsFlags,
|
||||||
printReturnValues, colorize, decimalFormat);
|
printReturnValues, colorize, decimalFormat,
|
||||||
|
currentThreadID);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user