Home | History | Annotate | Download | only in trace_processor
      1 #!/usr/bin/python
      2 # Copyright (C) 2019 The Android Open Source Project
      3 #
      4 # Licensed under the Apache License, Version 2.0 (the "License");
      5 # you may not use this file except in compliance with the License.
      6 # You may obtain a copy of the License at
      7 #
      8 #      http://www.apache.org/licenses/LICENSE-2.0
      9 #
     10 # Unless required by applicable law or agreed to in writing, software
     11 # distributed under the License is distributed on an "AS IS" BASIS,
     12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 # See the License for the specific language governing permissions and
     14 # limitations under the License.
     15 
     16 
     17 # This synthetic trace is designed to test the process tracking logic. It
     18 # synthesizes a combination of sched_switch, task_newtask, and process tree
     19 # packets (i.e. the result of the userspace /proc/pid scraper).
     20 
     21 from synth_common import CLONE_THREAD
     22 import synth_common
     23 from os import sys, path
     24 
     25 sys.path.append(path.dirname(path.abspath(__file__)))
     26 
     27 trace = synth_common.create_trace()
     28 
     29 
     30 # Create the first process (pid=10) with three threads(tids=10,11,12).
     31 # In this synthetic trace we will pretend we never saw the start of this threads
     32 # (i.e. the task_newtask event). Process association for these threads will
     33 # leverage only the /proc/pid scraper.
     34 trace.add_ftrace_packet(0)
     35 trace.add_sched(ts=1, prev_pid=0, next_pid=10, next_comm='p1-t0')
     36 trace.add_sched(ts=2, prev_pid=10, next_pid=11,
     37                 prev_comm='p1-t0', next_comm='p1-t1')
     38 trace.add_sched(ts=3, prev_pid=11, next_pid=12,
     39                 prev_comm='p1-t1', next_comm='p1-t2')
     40 trace.add_sched(ts=4, prev_pid=12, next_pid=0, prev_comm='p1-t2')
     41 
     42 # In the synthetic /proc/pic scraper packet, we pretend we missed p1-1. At the
     43 # SQL level we should be able to tell that p1-t0 and p1-t2 belong to 'process1'
     44 # but p1-t1 should be left unjoinable.
     45 trace.add_process_tree_packet(ts=5)
     46 trace.add_process(10, 0, "process1")
     47 trace.add_thread(12, 10, "p1-t2")
     48 
     49 # Now create another process (pid=20) with three threads(tids=20,21,22).
     50 # This will be slightly more complicated. We'll pretend that tids=20,21 were
     51 # created before the start of the trace, and 22 is created only later.
     52 trace.add_ftrace_packet(0)
     53 trace.add_sched(ts=10, prev_pid=0, next_pid=20, next_comm='p2-t0')
     54 trace.add_sched(ts=11, prev_pid=20, next_pid=21,
     55                 prev_comm='p2-t0', next_comm='p2-t1')
     56 trace.add_newtask(ts=12, tid=21, new_tid=22,
     57                   new_comm='p2-t2', flags=CLONE_THREAD)
     58 trace.add_sched(ts=13, prev_pid=21, next_pid=22,
     59                 prev_comm='p2-t1', next_comm='p2-t2')
     60 trace.add_sched(ts=14, prev_pid=22, next_pid=0, prev_comm='p2-t2')
     61 
     62 # From the process tracker viewpoint we pretend we only scraped tids=20,21.
     63 trace.add_process_tree_packet(ts=15)
     64 trace.add_process(20, 0, "process_2")
     65 trace.add_thread(21, 20, "p2-t1")
     66 
     67 # Finally the very complex case: a third process (pid=30) which spawns threads
     68 # in the following order (notation: A->B means thread A spawns thread B).
     69 # 31->32, 31->33, 32->34.
     70 # Last but not least we spawn a further process (pid=40) which spawns a thread
     71 # which, unluckily, recycles TID=34. We expect a new UTID for TID=34 then.
     72 trace.add_ftrace_packet(0)
     73 trace.add_sched(ts=20, prev_pid=0, next_pid=30, next_comm='p3-t0')
     74 trace.add_sched(ts=21, prev_pid=30, next_pid=31,
     75                 prev_comm='p3-t0', next_comm='p3-t1')
     76 trace.add_newtask(ts=22, tid=31, new_tid=32,
     77                   new_comm='p3-t2', flags=CLONE_THREAD)
     78 trace.add_newtask(ts=23, tid=31, new_tid=33,
     79                   new_comm='p3-t3', flags=CLONE_THREAD)
     80 trace.add_sched(ts=24, prev_pid=31, next_pid=32,
     81                 prev_comm='p3-t1', next_comm='p3-t2')
     82 trace.add_newtask(ts=25, tid=32, new_tid=34,
     83                   new_comm='p3-t4', flags=CLONE_THREAD)
     84 trace.add_process_tree_packet(ts=26)
     85 trace.add_process(30, 0, "process_3")
     86 trace.add_thread(31, 30, "p3-t1")
     87 
     88 # This event pretends that TID=32 forks() a new process 40 (note the absence of
     89 # CLONE_THREAD in the add_newtask flags).
     90 trace.add_ftrace_packet(0)
     91 trace.add_newtask(ts=27, tid=32, new_tid=40, new_comm='p4-t0', flags=0)
     92 trace.add_sched(ts=28, prev_pid=32, next_pid=40,
     93                 prev_comm='p3-t2', next_comm='p4-t0')
     94 
     95 trace.add_process_tree_packet(ts=29)
     96 trace.add_process(40, 0, "process_4")
     97 
     98 # And now, this new process starts a new thread that recycles TID=31 (previously
     99 # used as p3-t1, now becomes p4-t1).
    100 trace.add_ftrace_packet(0)
    101 trace.add_newtask(ts=30, tid=40, new_tid=31,
    102                   new_comm='p4-t1', flags=CLONE_THREAD)
    103 trace.add_sched(ts=31, prev_pid=40, next_pid=31,
    104                 prev_comm='p4-t0', next_comm='p4-t1')
    105 
    106 
    107 print(trace.trace.SerializeToString())
    108