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