bcc/tools: Fix renaming of the state field of task_struct

Kernel commit 2f064a59a1 ("sched: Change task_struct::state") changes
the name of task_struct::state to task_struct::__state, which breaks
several bcc tools. Fix this issue by checking field existence in vmlinux
BTF. Since this change was intruduce in kernel v5.14, we should have
BTF support. Closes #3658 .

Signed-off-by: Hengqi Chen <chenhengqi@outlook.com>
diff --git a/tools/offwaketime.py b/tools/offwaketime.py
index 753eee9..b52d472 100755
--- a/tools/offwaketime.py
+++ b/tools/offwaketime.py
@@ -139,12 +139,12 @@
 struct key_t {
     char waker[TASK_COMM_LEN];
     char target[TASK_COMM_LEN];
-    int w_k_stack_id;
-    int w_u_stack_id;
-    int t_k_stack_id;
-    int t_u_stack_id;
-    u32 t_pid;
-    u32 t_tgid;
+    s64 w_k_stack_id;
+    s64 w_u_stack_id;
+    s64 t_k_stack_id;
+    s64 t_u_stack_id;
+    u64 t_pid;
+    u64 t_tgid;
     u32 w_pid;
     u32 w_tgid;
 };
@@ -254,14 +254,18 @@
 else:
     thread_filter = '1'
 if args.state == 0:
-    state_filter = 'p->state == 0'
+    state_filter = 'p->STATE_FIELD == 0'
 elif args.state:
     # these states are sometimes bitmask checked
-    state_filter = 'p->state & %d' % args.state
+    state_filter = 'p->STATE_FIELD & %d' % args.state
 else:
     state_filter = '1'
 bpf_text = bpf_text.replace('THREAD_FILTER', thread_filter)
 bpf_text = bpf_text.replace('STATE_FILTER', state_filter)
+if BPF.kernel_struct_has_field(b'task_struct', b'__state') == 1:
+    bpf_text = bpf_text.replace('STATE_FIELD', '__state')
+else:
+    bpf_text = bpf_text.replace('STATE_FIELD', 'state')
 
 # set stack storage size
 bpf_text = bpf_text.replace('STACK_STORAGE_SIZE', str(args.stack_storage_size))