xref: /haiku/src/bin/debug/strace/mutex.cpp (revision 445d4fd926c569e7b9ae28017da86280aaecbae2)
1 /*
2  * Copyright 2023, Trung Nguyen, trungnt282910@gmail.com.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <string.h>
8 
9 #include <user_mutex_defs.h>
10 
11 #include "strace.h"
12 #include "Context.h"
13 #include "MemoryReader.h"
14 #include "TypeHandler.h"
15 
16 
17 #define FLAG_INFO_ENTRY(name) \
18 	{ name, #name }
19 
20 static const FlagsTypeHandler::FlagInfo kMutexFlagsInfo[] = {
21     FLAG_INFO_ENTRY(B_USER_MUTEX_LOCKED),
22     FLAG_INFO_ENTRY(B_USER_MUTEX_WAITING),
23     FLAG_INFO_ENTRY(B_USER_MUTEX_DISABLED),
24 
25 	{ 0, NULL }
26 };
27 
28 static FlagsTypeHandler::FlagsList kMutexFlags;
29 
30 
31 class MutexTypeHandler : public FlagsTypeHandler {
32 public:
33     MutexTypeHandler()
34         :
35         FlagsTypeHandler(kMutexFlags)
36     {
37     }
38 
39 	string GetParameterValue(Context &context, Parameter *param,
40 		const void *address)
41 	{
42         void *data = *(void **)address;
43 
44 		if (context.GetContents(Context::POINTER_VALUES)) {
45             int32 value, bytesRead;
46             status_t err = context.Reader().Read(data, &value, sizeof(value), bytesRead);
47             if (err != B_OK)
48                 return context.FormatPointer(data);
49 
50             string r = context.FormatPointer(data);
51             r += " [";
52             r += RenderValue(context, (unsigned int)value);
53             r += "]";
54             return r;
55         }
56 
57 		return context.FormatPointer(data);
58 	}
59 
60 	string GetReturnValue(Context &context, uint64 value)
61 	{
62 		return context.FormatPointer((void *)value);
63 	}
64 };
65 
66 
67 void
68 patch_mutex()
69 {
70     for (int i = 0; kMutexFlagsInfo[i].name != NULL; i++) {
71         kMutexFlags.push_back(kMutexFlagsInfo[i]);
72     }
73 
74     Syscall *mutex_lock = get_syscall("_kern_mutex_lock");
75     mutex_lock->GetParameter("mutex")->SetHandler(new MutexTypeHandler());
76 
77     Syscall *mutex_unlock = get_syscall("_kern_mutex_unblock");
78     mutex_unlock->GetParameter("mutex")->SetHandler(new MutexTypeHandler());
79 
80     Syscall *mutex_switch_lock = get_syscall("_kern_mutex_switch_lock");
81     mutex_switch_lock->GetParameter("fromMutex")->SetHandler(new MutexTypeHandler());
82     mutex_switch_lock->GetParameter("toMutex")->SetHandler(new MutexTypeHandler());
83 }
84