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# This synthetic trace tests handling of the mm_id field in the rss_stat 17# event during clone events which have various flag combinations set. 18 19from os import sys, path 20 21sys.path.append(path.dirname(path.dirname(path.abspath(__file__)))) 22import synth_common 23 24trace = synth_common.create_trace() 25 26trace.add_packet(ts=1) 27trace.add_process(10, 1, "parent_process") 28trace.add_process(3, 2, "kernel_thread") 29 30# In this packet, check what happens to userspace processes with different 31# clone flags. 32trace.add_ftrace_packet(1) 33 34# Emit an rss stat event for the main thread of the process to associate it 35# with an mm_id. 36trace.add_rss_stat(100, tid=10, member=0, size=100, mm_id=0x1234, curr=1) 37 38# Create a newtask event emulating vfork/posix_spawn (i.e. CLONE_VM and 39# CLONE_VFORK set). 40trace.add_newtask( 41 101, 42 tid=10, 43 new_tid=11, 44 new_comm="child_process", 45 flags=synth_common.CLONE_VFORK | synth_common.CLONE_VM) 46 47# The child process will now change its own (and parent's) VM space with 48# |curr| set to 1 (emulating cleaning up some memory in parent). 49trace.add_rss_stat(102, tid=11, member=0, size=90, mm_id=0x1234, curr=1) 50 51# At this point, the child process will obtain a new mm struct. From this 52# point on, all mm_ids from the child should be different from the parent. 53 54# The child process will now change its parents VM space with curr set to 55# 0 (emulating e.g. cleaning up its stack). 56trace.add_rss_stat(103, tid=11, member=0, size=85, mm_id=0x1234, curr=0) 57 58# Now the child process should exec another process. 59 60# The child can now change its own memory. 61trace.add_rss_stat(104, tid=11, member=0, size=10, mm_id=0x5678, curr=1) 62 63# The parent can now resume execution and may emit another rss event. 64trace.add_rss_stat(105, tid=10, member=0, size=95, mm_id=0x1234, curr=1) 65 66# The parent can now go ahead and start a new thread. 67trace.add_newtask( 68 106, 69 tid=10, 70 new_tid=12, 71 new_comm="parent_thread", 72 flags=synth_common.CLONE_VM | synth_common.CLONE_THREAD) 73 74# Since this thread shares mm space with the parent, it should have the 75# same mm id and have curr set to 1. 76trace.add_rss_stat(107, tid=12, member=0, size=105, mm_id=0x1234, curr=1) 77 78# The parent can also emit events with the same mm struct at the same time. 79trace.add_rss_stat(108, tid=10, member=0, size=110, mm_id=0x1234, curr=1) 80 81# In this packet, we check what happens to kernel threads in RSS stat. 82trace.add_ftrace_packet(1) 83 84# Emit an rss stat event for the the existing kernel thread. 85trace.add_rss_stat(100, tid=3, member=0, size=10, mm_id=0x2345, curr=1) 86 87# Start a new kernel thread. 88trace.add_newtask( 89 101, 90 tid=2, 91 new_tid=4, 92 new_comm="kernel_thread2", 93 flags=synth_common.CLONE_VM) 94 95# Emit a rss stat for the new kernel thread. 96trace.add_rss_stat(102, tid=4, member=0, size=20, mm_id=0x2345, curr=1) 97 98print(trace.trace.SerializeToString()) 99