kernel: Print the first 4 chars of cvar names in KDL "threads" command.
Condition variables are now a pretty common way the kernel blocks threads. That means the "threads" command was getting difficult to navigate, since at any given time, a lot of threads could be blocked on "cvar". Now we try (carefully, because it could fault!) to fetch the first 4 characters of the "type" name and display then. This suffices to distinguish the most common object block types in the list at a glance (e.g. "cvar:port" for port reads, the most common.) Change-Id: I94f4b59fd78b7ebdce913944551a5e98f0ca2e33 Reviewed-on: https://review.haiku-os.org/c/haiku/+/6605 Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
f0e9ed4488
commit
6554d7448d
@ -97,6 +97,8 @@ protected:
|
||||
|
||||
friend struct ConditionVariableEntry;
|
||||
friend struct ConditionVariableHashDefinition;
|
||||
friend ssize_t debug_condition_variable_type_strlcpy(ConditionVariable* cvar,
|
||||
char* name, size_t size);
|
||||
};
|
||||
|
||||
|
||||
|
@ -47,46 +47,6 @@ static ConditionVariableHash sConditionVariableHash;
|
||||
static rw_spinlock sConditionVariableHashLock;
|
||||
|
||||
|
||||
static int
|
||||
list_condition_variables(int argc, char** argv)
|
||||
{
|
||||
ConditionVariable::ListAll();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dump_condition_variable(int argc, char** argv)
|
||||
{
|
||||
if (argc != 2) {
|
||||
print_debugger_command_usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr_t address = parse_expression(argv[1]);
|
||||
if (address == 0)
|
||||
return 0;
|
||||
|
||||
ConditionVariable* variable = sConditionVariableHash.Lookup((void*)address);
|
||||
|
||||
if (variable == NULL) {
|
||||
// It must be a direct pointer to a condition variable.
|
||||
variable = (ConditionVariable*)address;
|
||||
}
|
||||
|
||||
if (variable != NULL) {
|
||||
variable->Dump();
|
||||
|
||||
set_debug_variable("_cvar", (addr_t)variable);
|
||||
set_debug_variable("_object", (addr_t)variable->Object());
|
||||
|
||||
} else
|
||||
kprintf("no condition variable at or with key %p\n", (void*)address);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - ConditionVariableEntry
|
||||
|
||||
|
||||
@ -463,6 +423,9 @@ ConditionVariable::_NotifyLocked(bool all, status_t result)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
/*static*/ void
|
||||
ConditionVariable::ListAll()
|
||||
{
|
||||
@ -494,6 +457,46 @@ ConditionVariable::Dump() const
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
list_condition_variables(int argc, char** argv)
|
||||
{
|
||||
ConditionVariable::ListAll();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dump_condition_variable(int argc, char** argv)
|
||||
{
|
||||
if (argc != 2) {
|
||||
print_debugger_command_usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr_t address = parse_expression(argv[1]);
|
||||
if (address == 0)
|
||||
return 0;
|
||||
|
||||
ConditionVariable* variable = sConditionVariableHash.Lookup((void*)address);
|
||||
|
||||
if (variable == NULL) {
|
||||
// It must be a direct pointer to a condition variable.
|
||||
variable = (ConditionVariable*)address;
|
||||
}
|
||||
|
||||
if (variable != NULL) {
|
||||
variable->Dump();
|
||||
|
||||
set_debug_variable("_cvar", (addr_t)variable);
|
||||
set_debug_variable("_object", (addr_t)variable->Object());
|
||||
|
||||
} else
|
||||
kprintf("no condition variable at or with key %p\n", (void*)address);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
@ -517,5 +520,20 @@ condition_variable_init()
|
||||
add_debugger_command_etc("cvars", &list_condition_variables,
|
||||
"List condition variables",
|
||||
"\n"
|
||||
"Lists all existing condition variables\n", 0);
|
||||
"Lists all published condition variables\n", 0);
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
debug_condition_variable_type_strlcpy(ConditionVariable* cvar, char* name, size_t size)
|
||||
{
|
||||
const int32 typePointerOffset = offsetof(ConditionVariable, fObjectType);
|
||||
|
||||
const char* pointer;
|
||||
status_t status = debug_memcpy(B_CURRENT_TEAM, &pointer,
|
||||
(int8*)cvar + typePointerOffset, sizeof(const char*));
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return debug_strlcpy(B_CURRENT_TEAM, name, pointer, size);
|
||||
}
|
||||
|
@ -1701,8 +1701,16 @@ _dump_thread_info(Thread *thread, bool shortInfo)
|
||||
}
|
||||
|
||||
case THREAD_BLOCK_TYPE_CONDITION_VARIABLE:
|
||||
kprintf("cvar %p ", thread->wait.object);
|
||||
{
|
||||
char name[5];
|
||||
ssize_t length = debug_condition_variable_type_strlcpy(
|
||||
(ConditionVariable*)thread->wait.object, name, sizeof(name));
|
||||
if (length > 0)
|
||||
kprintf("cvar:%*s %p ", 4, name, thread->wait.object);
|
||||
else
|
||||
kprintf("cvar %p ", thread->wait.object);
|
||||
break;
|
||||
}
|
||||
|
||||
case THREAD_BLOCK_TYPE_SNOOZE:
|
||||
kprintf("%*s", B_PRINTF_POINTER_WIDTH + 15, "");
|
||||
|
Loading…
Reference in New Issue
Block a user