Kernel tracing of syscalls uses more information about the syscall

parameters, now. We print 64 bit values correctly, and also fetch
strings from userland and print them. 


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23620 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-01-18 19:33:09 +00:00
parent 8bd6d45df3
commit 8d3d1be1ca
+66 -13
View File
@@ -337,6 +337,27 @@ class PreSyscall : public AbstractTraceEntry {
if (syscall < (uint32)kSyscallCount) { if (syscall < (uint32)kSyscallCount) {
fParameters = alloc_tracing_buffer_memcpy(parameters, fParameters = alloc_tracing_buffer_memcpy(parameters,
kSyscallInfos[syscall].parameter_size, false); kSyscallInfos[syscall].parameter_size, false);
// copy string parameters, if any
if (fParameters != NULL) {
int32 stringIndex = 0;
const syscall_parameters_info& paramsInfo
= kSyscallParametersInfos[fSyscall];
for (int i = 0; i < paramsInfo.parameter_count; i++) {
const syscall_parameter_info& paramInfo
= paramsInfo.parameters[i];
if (paramInfo.type != B_STRING_TYPE)
continue;
const uint8* data
= (uint8*)fParameters + paramInfo.offset;
if (stringIndex < MAX_PARAM_STRINGS) {
fParameterStrings[stringIndex++]
= alloc_tracing_buffer_strcpy(
*(const char**)data, 64, true);
}
}
}
} }
Initialized(); Initialized();
@@ -352,21 +373,50 @@ class PreSyscall : public AbstractTraceEntry {
size -= bytesPrinted; size -= bytesPrinted;
if (fParameters != NULL) { if (fParameters != NULL) {
uint32* params = (uint32*)fParameters; int32 stringIndex = 0;
int32 paramSize = kSyscallInfos[fSyscall].parameter_size; const syscall_parameters_info& paramsInfo
bool first = true; = kSyscallParametersInfos[fSyscall];
while (paramSize >= 4 && size > 0) { for (int i = 0; i < paramsInfo.parameter_count; i++) {
if (first) { const syscall_parameter_info& paramInfo
snprintf(buffer, size, "0x%lx", *params); = paramsInfo.parameters[i];
first = false; const uint8* data = (uint8*)fParameters + paramInfo.offset;
} else uint64 value = 0;
snprintf(buffer, size, ", 0x%lx", *params); bool printValue = true;
switch (paramInfo.type) {
case B_INT8_TYPE:
value = *(uint8*)data;
break;
case B_INT16_TYPE:
value = *(uint16*)data;
break;
case B_INT32_TYPE:
value = *(uint32*)data;
break;
case B_INT64_TYPE:
value = *(uint64*)data;
break;
case B_POINTER_TYPE:
value = (uint64)*(void**)data;
break;
case B_STRING_TYPE:
if (stringIndex < MAX_PARAM_STRINGS) {
snprintf(buffer, size, "%s\"%s\"",
(i == 0 ? "" : ", "),
fParameterStrings[stringIndex++]);
printValue = false;
} else
value = (uint64)*(void**)data;
break;
}
if (printValue) {
snprintf(buffer, size, "%s0x%llx", (i == 0 ? "" : ", "),
value);
}
bytesPrinted = strlen(buffer); bytesPrinted = strlen(buffer);
buffer += bytesPrinted; buffer += bytesPrinted;
size -= bytesPrinted; size -= bytesPrinted;
params++;
paramSize -= 4;
} }
} }
@@ -374,8 +424,11 @@ class PreSyscall : public AbstractTraceEntry {
} }
private: private:
uint32 fSyscall; enum { MAX_PARAM_STRINGS = 3 };
void* fParameters;
uint32 fSyscall;
void* fParameters;
const char* fParameterStrings[MAX_PARAM_STRINGS];
}; };