From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from AS4PR08MB8143.eurprd08.prod.outlook.com (2603:10a6:20b:58e::6) by PAXPR08MB6942.eurprd08.prod.outlook.com with HTTPS; Wed, 16 Sep 2026 13:34:28 +0000 Received: from PA7P264CA0178.FRAP264.PROD.OUTLOOK.COM (2603:10a6:102:36f::10) by AS4PR08MB8143.eurprd08.prod.outlook.com (2603:10a6:20b:58e::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.451.5; Wed, 16 Sep 2026 13:34:21 +0000 Received: from MI3PEPF00008482.eurprd02.prod.outlook.com (2603:10a6:102:36f:cafe::ae) by PA7P264CA0178.outlook.office365.com (2603:10a6:102:36f::10) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.428.11 via Frontend Transport; Wed, 16 Sep 2026 13:34:21 +0000 Authentication-Results: spf=softfail (sender IP is 99.81.216.78) smtp.mailfrom=openvz.org; dkim=pass (signature was verified) header.d=openvz.org;dmarc=pass action=none header.from=openvz.org;compauth=pass reason=100 Received-SPF: SoftFail (protection.outlook.com: domain of transitioning openvz.org discourages use of 99.81.216.78 as permitted sender) Received: from nat.eu.perception-point.io (99.81.216.78) by MI3PEPF00008482.mail.protection.outlook.com (10.167.240.169) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.428.7 via Frontend Transport; Wed, 16 Sep 2026 13:34:20 +0000 X-PERCEPTION-POINT-VERDICT: CLN X-PERCEPTION-POINT-SPF: X-PERCEPTION-POINT-SPAM: PASS X-PERCEPTION-POINT-SENDER-IP: 2a00:1450:4864:31::10 X-PP-Forefront-Antispam-Report: CIP:2a00:1450:4864:31::10;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail-wm2-x10.google.com;PTR:mail-wm2-x10.google.com;CAT:NONE;SFS:(13230040)(82310400026)(43022699015)(6059299003)(12012899012)(3072899012)(2092899012)(5023799004)(5063699009)(10067099003)(19002099009)(18002099003)(55112099003)(57112099003)(16102099003)(22082099003);DIR:INB; Received: from AM0PR07CU002.outbound.protection.outlook.com (mail-am0pr07cu00203.outbound.protection.outlook.com [40.93.65.67]) by inbound-smtp.eu-west-1.amazonaws.com with SMTP id br51l1vecg5vbaonod23rb41iprunjj9kprufm81; Wed, 16 Sep 2026 13:34:16 +0000 (UTC) X-SES-Spam-Verdict: PASS X-SES-Virus-Verdict: PASS Received-SPF: softfail (spfCheck: transitioning domain of openvz.org does not designate 40.93.65.67 as permitted sender) client-ip=40.93.65.67; envelope-from=den@openvz.org; helo=AM0PR07CU002.outbound.protection.outlook.com; Authentication-Results-Original: amazonses.com; spf=softfail (spfCheck: transitioning domain of openvz.org does not designate 40.93.65.67 as permitted sender) client-ip=40.93.65.67; envelope-from=den@openvz.org; helo=AM0PR07CU002.outbound.protection.outlook.com; dkim=pass header.i=@openvz.org; dmarc=pass header.from=openvz.org; X-SES-RECEIPT: AEFBQUFBQUFBQUFFRTFDdGdSdVo2cHQxRFRFR0w4WnZnR0c5bE9HTEFhaHZUTy9OcVRKSjJGald1NzJJZWlnMDV2UGNxbGtCc1JiZ1FtcnNRNDBMMndJSDB4aGRIdFFzTUVOUkdGRWdwSDV3K0JlSnI5NFEzVlJUcHJ3eUE4Y2Z5UVNXSWVBQW41UVdtVHN1bnBtU1BVUVBSQyt2K21OeithN3YvRkxuRU9mWVlXSzBHeHF5K1p0SzlmZ2NDK1dRT2loU1pKMi9pbUNIWlNnUGozekZYelhPOWM0R1FPYVdMTHVNZk5lak9scTlqdWcyWi8wSS8wZ1g1SmNqV0M3UVI2U0k5VGoxcjNQUjdxeG1odVdNNUVRMUowRnBQSFVlMjJIZUNvU3k5STBmcW83d1lSSnplL0E9PQ== X-SES-DKIM-SIGNATURE: a=rsa-sha256; q=dns/txt; b=ZZlbzdbyQo/MwJnGwV+abujttj/E42LftHCISxu1PgXzkC0p/yo9ijpUzumQ7NYPwC7d0cHVHuqJfg9L7LGP8gHOM5NLRW4dr+r4vl3BEu5mSXJqPic0vn/zsbywy3/amOHrhXdEg1avzi0on0UHHRvioJT2WoD/UmrHN1u4FVY=; c=relaxed/simple; s=shh3fegwg5fppqsuzphvschd53n6ihuv; d=amazonses.com; t=1789565657; v=1; bh=qnO0dIx/s7LG+NLZlR7jIO2PCxi7XRP8lzChWz4Es5A=; h=From:To:Cc:Bcc:Subject:Date:Message-ID:MIME-Version:Content-Type:X-SES-RECEIPT; Received: from PA7P264CA0173.FRAP264.PROD.OUTLOOK.COM (2603:10a6:102:36f::9) by DB9PR08MB7471.eurprd08.prod.outlook.com (2603:10a6:10:36d::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.428.8; Wed, 16 Sep 2026 13:34:12 +0000 Received: from MI3PEPF00008482.eurprd02.prod.outlook.com (2603:10a6:102:36f:cafe::1e) by PA7P264CA0173.outlook.office365.com (2603:10a6:102:36f::9) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.428.11 via Frontend Transport; Wed, 16 Sep 2026 13:34:12 +0000 Authentication-Results-Original: spf=pass (sender IP is 2a00:1450:4864:31::10) smtp.mailfrom=openvz.org; dkim=pass (signature was verified) header.d=openvz.org;dmarc=pass action=none header.from=openvz.org;compauth=pass reason=100 Received-SPF: Pass (protection.outlook.com: domain of openvz.org designates 2a00:1450:4864:31::10 as permitted sender) receiver=protection.outlook.com; client-ip=2a00:1450:4864:31::10; helo=mail-wm2-x10.google.com; pr=C Received: from mail-wm2-x10.google.com (2a00:1450:4864:31::10) by MI3PEPF00008482.mail.protection.outlook.com (2603:10a6:298:1::69) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.428.7 via Frontend Transport; Wed, 16 Sep 2026 13:34:11 +0000 Received: by mail-wm2-x10.google.com with SMTP id 5b1f17b1804b1-49b912d8239so6230235e9.0 for ; Wed, 16 Sep 2026 06:34:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=google; t=1789565650; x=1790170450; darn=virtuozzo.com; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=cKHdmMeqEr6c6grDAnvJIJYCfFFtWiQUq50MRHvcn1k=; b=NBlUn2YOIa3uH9jSf+UGJ3pQaDxtUV79E0ef53OOJz5t6J8MysDbHA0djB4Ef5InPn nO2FNAOnDTFqFe0SQ0yMoY+1H9uSnCqSu6D0aXYjQRNSI/TDcUfGTROR6MxyyJrF1uSx VTW9OAiJSkjYU2sz3nriGzkX/uw/zy+WnAmx/Ly9pq60ppwDLtWZEWqaUhrnUtxwukfh zyi3D4Wka/cSouKaSON7kS+itfEQZVWfugFhIY4luw/oacqbtJJjsfYRYPDDaerz7BGG Cm7mzjDw0nMp/2tBTRVwcrssdVd+nMMjorChvHcjmnKbrgbYeNl3pCPpdykKg/aPo9YM enDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789565650; x=1790170450; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=cKHdmMeqEr6c6grDAnvJIJYCfFFtWiQUq50MRHvcn1k=; b=1YcUtJkmC3E6ykQX0GJqRauj3J/SW+XoDZwAFd9IpC85jcUxc/lH5SfVNOh62ZbIF7 Zv+2dZDMQ+MPckHkG/ER1XvtiqXyxqw4Pd1nlGMbUD9e3qA+0gVZc2moREsBHLHrBlbj z5mZMKh6YKIL5TApjQTnwvrtzOMfe9qKRg6uJOwnJLq13AmAMCyxSp5uoy9tlTR36/RJ 5fCA4O9/tf/1j4o04W7+OIlaNRjr7C8/QnQ4pvDxcK8MHHPTvxwzIUgHsSJE86maT6EV uag98PqUnWjk2kSEEcuSAyd0GbghuEQqpQWk3PGSvqrS/qFaP/5eYC5Y06mXIVQlayg6 3XXA== X-Gm-Message-State: AFuF++k9um2tVzgD+XrVHnZDOyzgnMKZQ5Tasjs88Z/NPAZoItlnv1Ss HUKorTd2W1bwj3FuRjB4TB7PAFgX5F3GUs6L1IFOlCkSB70PiHjR0tbZr/r3gqY/XVXBiCV2xuj ldCq9OZY= X-Gm-Gg: AYBFou2Sg54Jr3UDJTzNQor8/vKa8xx8NkxqUUXsoDRYPEnSvjszTCOtuVdRhBG6HiG /pFwO0TymVhiO5YSl0lXRhd8JIkN2QprMIAvZE9FiWQ+RJeXNIja/CrOf8i2IqV1RMs8P9UFT1e IhCIz+w3xtlt/dfYN61UOPLRFzhZ2fjRYf1jvPA6UAC/h0XfcY8hpXovV1SZYRQGmYs+AlrWzEa PQ1Hjouct1aMBLtUFN6Vvg90l264FleiWriMig4gLuC1amFNLr+O+sJzAMXvATXvmpu+Saceiaq bDa3YBgRZYILqIAiLvjhKD7lAHvqy78AaopDMrWdgGtzAu0TsXzuq3+ZABNIC6uyhP++sr6bJHu UmXey73uXmRZNj3VeXekUlwZU3qnK8lvusVV33HXdivYtzyQ2YONiFNpsRYjTbiNGc6mrhZSXju +lFm9wVY7lxzdCoN1fxokhWiarUvz4g30/UvDTZXQ/L5ZhGfVfHsHlJmp/k9zrdtxqASmJ X-Received: by 2002:a05:600c:3513:b0:49c:eb17:cf3b with SMTP id 5b1f17b1804b1-49eac4678e6mr29731285e9.8.1789565650488; Wed, 16 Sep 2026 06:34:10 -0700 (PDT) Return-Path: den@openvz.org Received: from athena.sw.ru ([2a06:5b06:b600:300:f56f:c51e:c53f:b1ce]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49e83da9a7csm76763235e9.11.2026.09.16.06.34.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Sep 2026 06:34:08 -0700 (PDT) From: "Denis V. Lunev" To: svt-core@virtuozzo.com Cc: andrey.drobyshev@virtuozzo.com, den@openvz.org Subject: [PATCH hci-8.0 08/12] oslib: report each thread's program counter #VSTOR-144507 Date: Wed, 16 Sep 2026 15:33:47 +0200 Message-ID: <20260916133351.1640303-9-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260916133351.1640303-1-den@openvz.org> References: <20260916133351.1640303-1-den@openvz.org> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 1 X-EOPTenantAttributedMessage: 0bc7f26d-0264-416e-a6fc-8352af79c58f:1 X-MS-TrafficTypeDiagnostic: MI3PEPF00008482:EE_|DB9PR08MB7471:EE_|MI3PEPF00008482:EE_|AS4PR08MB8143:EE_|PAXPR08MB6942:EE_ X-MS-Office365-Filtering-Correlation-Id: e529603a-66cf-4d06-b189-08df13f73737 X-MS-Exchange-AtpMessageProperties: SA|SL X-PERCEPTION-POINT-CUSTOM: vzpp X-Microsoft-Antispam-Untrusted: BCL:0;ARA:13230040|82310400026|43022699015|6059299003|12012899012|3072899012|2092899012|5023799004|5063699009|10067099003|19002099009|18002099003|55112099003|57112099003|16102099003|22082099003; X-Microsoft-Antispam-Message-Info-Original: =?utf-8?B?Zjc4ZlZVTWRQeVk1Vy9jQUNCb25zQjFjQUlMeWFvWWh3VDRqYTFvbTY3Y2hF?= =?utf-8?B?Y0loS2t4ditLVVNmL1BaUWNEODh6WTJIcXErOFRvWFpBYUd2OE5SSkNpQk10?= =?utf-8?B?aGZDR1dvOUlIRDdkUmdvK0Z5R294MVpPRzdhTWt4NjQ0Qzg2aVNTUUJHck42?= =?utf-8?B?anVTZFpSeFJLTlFGeWt1RUxVWDhFejRPWDJxZkJuVThhbHFabUxQVjc0K3My?= =?utf-8?B?Z2swMFp6d0w3WHVyTERFalNjeEp3akh4cGZobzUvTDRWTHVxTnlZR3hUc2J3?= =?utf-8?B?WlJHRGRvU2VyWCtFb1c5OWpZN3I5c0VFZEpidEh4eUE3S0NaV3N4YmNmOWND?= =?utf-8?B?SndHMnFURktNZzRzcC9Za0N4RG11anRkVmpuZmVZSjF4ZS84a0huR2M1ZU1X?= =?utf-8?B?N3dkbzhFVkNpYk40enpnWTN5dmhudUpjaW9GdlYyZHFsME53N1RWNWFQQVFo?= =?utf-8?B?aEx0TlBaSXlSS2d3WTJLYjZ3MTVwaHByekZzY3pkUWhnUGNqbUVYbUY0eGcx?= =?utf-8?B?clB3WmQ1SzhaeHYrUzY3aHNhaExKeURsdUFRVzI4Ty9LM2xyQ2QyV2RNUmpu?= =?utf-8?B?aFJ4WGdkc05Tbk45OEpHOGx2a1VCZ21odnZieHAvWjdCNXRydC9UUjEwNnlI?= =?utf-8?B?SzcxOFVHZHdLSWdpN1NidTdSNjhSK0ExYy8yR3MySGc2M1dpbkM2bDh5dGND?= =?utf-8?B?VWk3cVlNdTVkS3VReENubGxDTXhqRC9kWmRQTkM1VEo1L2Z3dEZJbEdtVGNO?= =?utf-8?B?SWxuVnRORUtWUUhTdnN4dkVlT3k5dWo4eHhzK29mRWFQSThWc2pESkRBaXl4?= =?utf-8?B?ZjQzQ1Npdjl2aWpJeHBDQU5CN2gwNGtWV1lFMEY1WVI0aVB5ajcrSG0rb0pp?= =?utf-8?B?TS9YcC9TK1lQN2RGMlhVckNvZTM5ZUU3aWRMbnNwSm9WakpDOWFoRHZpUWxQ?= =?utf-8?B?M1BsMUJjSk1HNmRSdHNtcWt3UUpLTldQNkNzNThyeVk5WnkzeHUyVXFuekdB?= =?utf-8?B?QUJ4RmdKY3lrbUoycU8waWtzR1NkN1Zxcm5BcmY5ZEtnakxnZWRtc1NVVGZG?= =?utf-8?B?Z3FCbTVMT0JBMzNOVDJQREJGcmptSDA1SVd4MTRJZGJJbEk3b3o4azc0YXNy?= =?utf-8?B?ekZWa3JabGdFNjVYUHNORDAxY3VEWWhqb1Fzem9HNTNERTU4OVZCZ1h5MWln?= =?utf-8?B?VHFnUTJDam4rcjhNMW5lMG5Da08yRlBwYkFnY2J2cnVVSGZWQ1h3RkhXWWFu?= =?utf-8?B?RlFIeEo4c2FFS3I3M0dnemhJQXV2VDRNUTBQQjliN1I3ZDdaeS9nS2lIaENG?= =?utf-8?B?d0N2WjNmY2xxZHNSVmdnZjBjVC82S0MrQlg0ZkRhbmprWHdqdHRqRW1rVm5k?= =?utf-8?B?V1JmYUs4L2lGOEtDWUtKOXRyNWhpdnZ2RWdkZk9Gd1VseWYrcUpJd2pSOXF3?= =?utf-8?B?RE9aT25UMUJydmhQcllqMjRwb1V3b202UEtsWEpCRXVGY05Ibm12d3Z2YWp1?= =?utf-8?B?RzR4Zm0zU0Z6UTNBc0tiRXZicHF4b3oydEFkS3YydEM1MmhwclJmaEh1dURn?= =?utf-8?B?dHhyTzRPanhsME5OSU00U1hiaTZha0tnRWNuWGRtSUhNbjdrTTYvNlY2L04w?= =?utf-8?B?bnF6SjRiOFVBNGF6d0JvRFlSOSs3TW95U1A2bkRrb1lGOEFSVnh3SkV2bzlH?= =?utf-8?B?MGxHWjNuL2Ewa0RYeG8xd2NUYlk2ZTlTdm5tck1tdEdic0Y2RjNwcXUzLzVE?= =?utf-8?B?Z1FlaXJuajJFUlUwR3Vhc0dNMUdBWHBPa0k2UnRSL2RyeGhXUWppT3lPaTZO?= =?utf-8?B?NE51VG5hNVhNL1pwQmRqL0YxWGdTVHVtdzZON1JNMUhmQmpFak15LzQ4aHpN?= =?utf-8?B?ZklwT1pUV3g3aHBtUlhXUWlHd3gzaHBtbE1Ubzg4K3cwWXM5RnNJYzY1THUx?= =?utf-8?B?Z3JYMld4bmRLemNJY3U5ZzRVaWphdzcvbkFvY0U1UmRDMUpkeUxGdDN6bTRh?= =?utf-8?B?TUJFc3NjMlZReWRlazFZamVORzhuMUQrdWQ5YTFXYm1rV0pFbDhoamNPK0Fq?= =?utf-8?B?MUR4T1FXeFV1b1Uyd2UxTTFJaHhWVDlYMmhwVDZ2QkdQVkZ0bEsrRmxjalh1?= =?utf-8?B?WEdITWtTVXhWS1dpcFFRdDkrVTFHWHNYMEUwTzhVSm15aGlWRUQ1TGNaRHNK?= =?utf-8?B?VC9OTlR0SDBWdmZDOFhHbkFDM2tCbEFnbVM2S2orUGpGNy8xL21oS1NGWG0x?= =?utf-8?B?MkNBellwMGxYSkRNTmJ5eGtxTEFCbFQrY1ZYVVQ0S1RkLzQ4WFVVTVVzNUI2?= =?utf-8?B?a09tYmUwN2pXcytHQ3BUeFVDRUV5MjBLU2kyMEJBeHBMMGV3Z1NjbmJWdjBQ?= =?utf-8?B?dWdpaEI0VnVFU2lLT0JrTERrSHBJTVgzMXUyYWJwMSttVGsxck1CakNyUnIv?= =?utf-8?B?UmUwZFcvcitwZVMyUGdIZnRIRG45NDNScnJFWFFqLzJxbGNtS2dIMTdUb2hq?= =?utf-8?B?T2tqWlQvUXVXclR4c2pZaitUME91dkhLb2hxaTVvUDJ4RUxhSHUybmNPWFM4?= =?utf-8?B?c3JKVzcwQXVHKy90QlIxdTJUekhqblhUMGRMTmEzdjNjazc2UjVNWXdpQiti?= =?utf-8?B?MVoxazNvTUNhTytGRUp6anJGY1Z6ZjdHL2ticW0wOUN3MUoxTlNvd05KaG1P?= =?utf-8?B?SWVteHFYbFB6UVZzbXlVY3pUa2JGejhvN0RJWkx2UHhsTnViSXkyRERRMFJo?= =?utf-8?B?cENzY2tuY0VUdXI5WTlvalJWc0FWWklyV09FdFA3aXZPYkl1b1lEdmRJb0t1?= =?utf-8?Q?s7S5khVkhoM84AFb0nvxIgbofT3dCiU+HhGeQbm3Br?= X-Forefront-Antispam-Report-Untrusted: CIP:2a00:1450:4864:31::10;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail-wm2-x10.google.com;PTR:mail-wm2-x10.google.com;CAT:NONE;SFS:(13230040)(82310400026)(43022699015)(6059299003)(12012899012)(3072899012)(2092899012)(5023799004)(5063699009)(10067099003)(19002099009)(18002099003)(55112099003)(57112099003)(16102099003)(22082099003);DIR:INB; X-Auto-Response-Suppress: DR, OOF, AutoReply X-Exchange-RoutingPolicyChecked: s8EfC/DLu9rk1zZb59b9OKrpyBrsz74T9LBxe0vOOeqHB1UaPCW6OMM8pC2EuWSz5zXmKf2Qwga+1pbpFNrENxw/U3eX5xo3r7sfNZ0rs0aAg9IOByJ+aXVEwaWMgy23kz4wc1LsOuOjV0UP0Y4f+o8yqEDfNk+mB3qc6mLZ9u/lg4a7XJZmejWO+UDjGko2hKZGgDcUEwHKrZVxdVBxEb0fGMhQEjVog6q+da+TlyCTbHfnoTLpdE6vxz/UezPSruxXt4P0ukW4XHS7Xfn8XD5DS0MV6vqkgcpn+7ajugpze7gTUfIpMxIhyyjSfOALuCYikrSikeJRLwb6EP9E1A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR08MB7471 X-MS-Exchange-Organization-ExpirationStartTime: 16 Sep 2026 13:34:21.4146 (UTC) X-MS-Exchange-Organization-ExpirationStartTimeReason: OriginalSubmit X-MS-Exchange-Organization-ExpirationInterval: 1:00:00:00.0000000 X-MS-Exchange-Organization-ExpirationIntervalReason: OriginalSubmit X-MS-Exchange-Organization-Network-Message-Id: e529603a-66cf-4d06-b189-08df13f73737 X-MS-Exchange-Organization-MessageDirectionality: Incoming X-MS-Exchange-Transport-CrossTenantHeadersStripped: MI3PEPF00008482.eurprd02.prod.outlook.com X-MS-PublicTrafficType: Email X-MS-Exchange-Organization-AuthSource: MI3PEPF00008482.eurprd02.prod.outlook.com X-MS-Exchange-Organization-AuthAs: Anonymous X-MS-Office365-Filtering-Correlation-Id-Prvs: 228fb789-2dec-4382-089a-08df13f73128 X-MS-Exchange-Organization-SCL: -1 X-Microsoft-Antispam: BCL:0;ARA:13230040|43022699015|12012899012|3072899012|2092899012|82310400026|6059299003|35042699022|19002099009|18003699003|5133699003|10067099003|5063699009|5023799004|16102099003|22082099003|57112099003|55112099003; X-Forefront-Antispam-Report: CIP:99.81.216.78;CTRY:IE;LANG:en;SCL:-1;SRV:;IPV:CAL;SFV:SKN;H:nat.eu.perception-point.io;PTR:nat2.eu.perception-point.io;CAT:NONE;SFS:(13230040)(43022699015)(12012899012)(3072899012)(2092899012)(82310400026)(6059299003)(35042699022)(19002099009)(18003699003)(5133699003)(10067099003)(5063699009)(5023799004)(16102099003)(22082099003)(57112099003)(55112099003);DIR:INB; X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Sep 2026 13:34:20.7627 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: e529603a-66cf-4d06-b189-08df13f73737 X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-CrossTenant-AuthSource: MI3PEPF00008482.eurprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: Internet X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS4PR08MB8143 X-MS-Exchange-Transport-EndToEndLatency: 00:00:08.1238407 X-MS-Exchange-Processed-By-BccFoldering: 15.21.0451.004 X-Microsoft-Antispam-Mailbox-Delivery: ucf:0;jmr:0;auth:0;dest:I;ENG:(910005)(944506478)(944626604)(920097)(930201)(20251009189)(140003); X-Microsoft-Antispam-Message-Info: =?utf-8?B?OXdVY29BNnBJNlR1VCtpbGVUTml2VlY4U3JmWVYrTnFaOGorTFBIbmJOS3RY?= =?utf-8?B?TXVJaEZ6aTUwalhWcTJ6L3Fhazhjc3NhU1libzNRVXlpTXFLeFhpVzl6a2wv?= =?utf-8?B?L2xaaXQvRGtDbk9EeVdZbTdVN1UxU0Z5U3VzV0plclplVGlwU09vdFUwekZn?= =?utf-8?B?d0ttbStTclJXYnNxUmFhTlpZcm9LYlFUMGdOVTU5dXE3TFUzM0RMWTNWNkFZ?= =?utf-8?B?SnBPWTNHTWl3amROYlFiclJGakVPYTg2emdXQzdMUEhaZXJqc2lmM1NLSWMv?= =?utf-8?B?dVM2bFZrVGw5ZDMrQmdpTEdadUxaMnVpWEdtWjJjcmNpT1NyemdtUTV1cllL?= =?utf-8?B?WXdDTjdwYmVsSVlaeEJlRWNNT1BlVVNuZHROSnpjY3JEeEh3SEdmbnhPaU11?= =?utf-8?B?RmZzM1gxRnJ3MkhGYTR0aGVReGJ3OTgwY1ZUSEVaMFRRL3o0L2orMHMxc3ZI?= =?utf-8?B?YkFPZ3JwVUdiNVZ3N3pTbWpjbjZCa0MwNUlDUmEvazRQL3ZDNm9vNmc5aFR3?= =?utf-8?B?YWZHM2h0bVhNZjlDdXh2dHo3YVF3R1JXYlBhSzZvcWhoV2FsalllK1BMSjJM?= =?utf-8?B?V1dwUldleWlQSEorQW1HRUU3NUQyODZkWEQyUmZMdEpTMCtwZ2d1RWNHTDd3?= =?utf-8?B?MEZ1b2RxVWxzK0Q4dnF3WUIvWXVGK2FmaHBKMXZuOXJJelFZUjdycm5Xd3RU?= =?utf-8?B?Z2hvWmJTcWovVTArcVNCKzFTK1kxNE45eVAyTFNYa2h0ay96b2ZBWXBMWG1N?= =?utf-8?B?ek9YVVhKclZvdmF3aXlQSm15amFPTWluN0RUNGp5UXIrMjk0VGVEenY1Z0lZ?= =?utf-8?B?TUFLYW9sanFXNGRleExtc1pNZW9tcXdQTXd3Tzk3eUI5Rm5FYmt3WXZ4cThz?= =?utf-8?B?STB1eGNaTmtVNWtxcXNmYS9jYmdHN1JzbzFZeGxhK0lHb0NZWVY4cWtlRytT?= =?utf-8?B?THpRQlpUSTA0cGdiT0QwQWRhbnBHMGpzalZ1UlFVY0FNRGk0VnJDVldZQjZr?= =?utf-8?B?aG1tQnJBY2orQ3dGZjNJdjR0N0dmblp0bUFwaWZDRURoVVVWdG84S0MvdndX?= =?utf-8?B?cE1qRDJSdVluVmlnRUo3eTRObVNZaWZ3K0puZk1pM1BTcmEvdDlNcmR3S2g1?= =?utf-8?B?OWxBQWZvZXhObVlxSEx1MHR5aUVnZWZIOWJmc1c5b3dKUGFuRC9wZGhPVmFT?= =?utf-8?B?YXh3UDIxZmtPYTZ0NzhkZEFDU0NiYVZFUGpSZmE0WUtDcGdTMExWUzduTXJF?= =?utf-8?B?cmF4M3RjY20vTzJ3RzVTMHV6YWFCV3Bwb0tvR1BWT29DL2d0MGhFbmQwYTF4?= =?utf-8?B?SlNSYitueGYwN2puOFY5V0ZMMFE2RGM5UDVYVHI4M2oyYXNxM2NsNERhUFlt?= =?utf-8?B?MGhlYk16UEtDdGVXaGtVbDNXVEp4YmttSGltMHgxUFZTNG5tanFCWGJPb0c5?= =?utf-8?B?VVZPRzZTVEU1U094NDVyMlUra0NDNStrVUNQYmExNnFHdkd0STRicUZ1dUhw?= =?utf-8?B?M0JvTFVZZ0NHVFNlNGt0SjBMdWdYSU93b1d6S1FNdzVsK2YvdDZvSDVKSGUy?= =?utf-8?B?NmJVOHkwVTZGRzNabGJtc2pRZlF5cjZHUEZlRldnWkZRS1Z3bm44K2JsTmhi?= =?utf-8?B?aXAzQ0dEWGxEN3F0cnMrM1hVQVA3NDl0RXRFNzBwK0g2dmFRdmc1anpRaERh?= =?utf-8?B?b2RyVWxram5od3ZTZ0Zva2UvQ2RVSUhTMmtaLy9rSXVWOCtnaDNiRUhjUDdU?= =?utf-8?B?Y3NURHNhRTRQSDh3VlFseDYrZ0xLS3FHc3B6dW5ZL1VVSHNhZWNiZS9SaUpl?= =?utf-8?B?ODFBUERuYjBvSDlnUjZnMDFOVlpLcVR1ZnlvSXEya1ZrMXpMeGV2WmFwUXdl?= =?utf-8?B?TWgwRlVNeFhSVXJNc3NlRGdHTm42V3Z6SUFtbGpPMkNyS2lwMzRhdG5iNGtp?= =?utf-8?B?QjEydGlnclQzUU4vbytmRGpITGdUbjdWSmdwWjFMS0tRY29vcjFJTFp4Tytp?= =?utf-8?B?Y3JOb1c4VGdFaGtkOUJ4R3oxNEs2Tmg4WHVlWThiYnFSdHFVVXJlSkMyWnFX?= =?utf-8?B?aVg5M0swR2x4SHRTNWpQSkdBSnpHZFk2MlViNzE3VWF3cnQ1QURzenVYNld3?= =?utf-8?B?WWdzMVM1TVNMMDdSYjRKSm85Qm5OS1A5bUN2aVZuNmFEcmROSWN4QnA3blEr?= =?utf-8?B?NkEzU2MzS21YYUg5SS9waktJcURnY2NHdFpYRGQxVVpBL0tLZW8vaXhaQXp0?= =?utf-8?B?ZGNNOXJieW42dkZrN3hXY25TNTJOd0s0aTM3UWlOM1dwNjhVc2dVQ000OFZZ?= =?utf-8?B?d2lIU0t0TW0wVW01V3FUVVpZOWlMWHVjb1NQSnp6OUZHdzBKMXFYQWtPc1Ew?= =?utf-8?B?b3VHbXFHWFM2RWhRUlBGTlZOTTBybHhCOCt2YTVKREl0bTJCNGlHVGF6MlVa?= =?utf-8?B?NjRWL0dUVGw3U1BRL0RXclFFR0RkVDRtQ2NGRlRjQmIrQjFjNk10U0dyTUo0?= =?utf-8?B?d1lvYVllazdpbklTY0xwaWZSQktHN0RqRyswWGt0N3pMNCtiV25DQ3NzYm1L?= =?utf-8?B?ODh5STJ4MFpXanl5eEw2RGhOOTdSMnhTbkovRlRWOFA5WEJoZDVZa1orcytV?= =?utf-8?B?T1hkbmdhYS81L2tRTTQwSXpEcVhIUUc0Q2IxZlVxWmVMSUhOS2VPZ1NMZnR0?= =?utf-8?B?bzJxT1M3N1VRQWlFL0c5VDFMRDJwekVDYlVHZUtnOHZqejJQclhXN0ltRFZi?= =?utf-8?B?MU5hMFZ6clAwVEdHWXg3RFNybUxxeUQwb1NIY05HRUtlaXNiRFRRb0NKblBw?= =?utf-8?B?SUlIb21lMFJETzduMjVwTXJ4MVdSTnpLdzJRTC80NEhSRzVZTWNZbUVsdExu?= =?utf-8?B?ZDJsNVQ0U3Z0eXBVYWRkdGFaNkJDOFliR0gwcnprdXNoWURudVFrYWZiQWVY?= =?utf-8?B?ZlVBS3hxVnRPcXMzc0NGdnVVM0NCajlzOHBqYVc0OUlkQ2x3MkVHV3dDdHpO?= =?utf-8?B?R1hZOHdlM21TKzArSXp4VkZXZHFEZnVybVlMZUZuZWRlT3YyOGFoZDdsdW1Y?= =?utf-8?B?Y242alhDSS84Qldyb2hIU2xmRGR6NTZLQWpwZzFQeUtwUitkNEo5cGlTSTh2?= =?utf-8?B?Y2kvUS9RelBmMHQyUk9KTHVoUXRGSkxibnpiaTh3Rm1rN2tkOTBOM3hscGtW?= =?utf-8?B?R1grQWlJQVlPU2J3L24zc3IxVjR6VHM2UXVhKzFCbVgvTEJxVDRMR1FxU2I0?= =?utf-8?B?YkluKy9mY2F3enN3ekNUZTlXWkRORHFOdUppK1k2VFdxU0d1TW5sYm5rSDRu?= =?utf-8?B?UFN3VStDMmtQVHhOQ0dRS1NPTWsvOVlyVFhhOWFxUkZwMVpPRmdqRExSSW5T?= =?utf-8?B?SGJSd080ZE93VlJuT1hBSmU0SVM2ZUptTGJOcjgwVGFCbjUxVEVVYWxEYzFC?= =?utf-8?Q?3rbDxeP3CIJBmUjdoH4=3D?= MIME-Version: 1.0 List-Id: From: Denis V. Lunev A kernel stack describes a thread asleep in a syscall and says nothing about one spinning in userspace, which is the other way a thread stops making progress. Ask each thread where it is by signalling it and reading the program counter out of the signal frame. That is a register read and a store, which a handler may do, unlike unwinding: backtrace() is not async signal safe and takes the loader lock the first time it runs. Ask all of them at once, once every passive read is taken. The signal interrupts whatever a thread was blocked in, so probing earlier would make the kernel stack and the wait channel describe the interruption instead of the hang, and probing one at a time would spend the timeout again for every thread that never answers. Insert the answers from the back, so the offsets recorded during the reads still point where they did. A thread that never answers within the deadline can still run the handler later, once whatever held it lets go, and by then the slots it would write to are gone. Count handlers between entry and exit, withdraw the slots when the deadline expires and wait for the last handler out before returning to the caller that frees them. A handler that arrives after the withdrawal finds nothing to write to. Where the counter sits in the signal frame is a host property, so it is answered from host/include like the other per-host questions, with a generic fallback that reports no counter and leaves the host otherwise untouched. The Linux hosts covered are the ones whose signal frames linux-user already describes in host-signal.h. Name the address through dladdr() where there is a symbol for it. There often is not, because dladdr() sees exported symbols only and a thread parked inside a library sits in its internals, so fall back to the object and the offset within it. An offset resolves against the library afterwards; the raw address does not survive the process. Cc: Paolo Bonzini Cc: Richard Henderson Cc: Philippe Mathieu-Daudé Cc: Zhao Liu Cc: Daniel P. Berrangé Cc: Marc-André Lureau Cc: Pierrick Bouvier Signed-off-by: Denis V. Lunev --- host/include/aarch64/host/signal-pc.h | 20 +++ host/include/generic/host/signal-pc.h | 11 ++ host/include/loongarch64/host/signal-pc.h | 20 +++ host/include/ppc64/host/signal-pc.h | 22 +++ host/include/riscv/host/signal-pc.h | 20 +++ host/include/s390x/host/signal-pc.h | 20 +++ host/include/x86_64/host/signal-pc.h | 20 +++ include/qemu/osdep.h | 7 +- meson.build | 2 + util/oslib-posix.c | 181 +++++++++++++++++++++- 10 files changed, 318 insertions(+), 5 deletions(-) create mode 100644 host/include/aarch64/host/signal-pc.h create mode 100644 host/include/generic/host/signal-pc.h create mode 100644 host/include/loongarch64/host/signal-pc.h create mode 100644 host/include/ppc64/host/signal-pc.h create mode 100644 host/include/riscv/host/signal-pc.h create mode 100644 host/include/s390x/host/signal-pc.h create mode 100644 host/include/x86_64/host/signal-pc.h diff --git a/host/include/aarch64/host/signal-pc.h b/host/include/aarch64/host/signal-pc.h new file mode 100644 index 00000000000..fe60ed1c96c --- /dev/null +++ b/host/include/aarch64/host/signal-pc.h @@ -0,0 +1,20 @@ +/* + * Program counter of an interrupted aarch64 thread, from its signal frame. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef AARCH64_HOST_SIGNAL_PC_H +#define AARCH64_HOST_SIGNAL_PC_H + +#ifdef CONFIG_LINUX +#define HAVE_HOST_SIGNAL_PC 1 + +static inline uintptr_t host_signal_pc(const ucontext_t *uc) +{ + return uc->uc_mcontext.pc; +} +#else +#define HAVE_HOST_SIGNAL_PC 0 +#endif + +#endif diff --git a/host/include/generic/host/signal-pc.h b/host/include/generic/host/signal-pc.h new file mode 100644 index 00000000000..8ce3822069a --- /dev/null +++ b/host/include/generic/host/signal-pc.h @@ -0,0 +1,11 @@ +/* + * No host specific way to read the program counter from a signal frame. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HOST_SIGNAL_PC_H +#define HOST_SIGNAL_PC_H + +#define HAVE_HOST_SIGNAL_PC 0 + +#endif diff --git a/host/include/loongarch64/host/signal-pc.h b/host/include/loongarch64/host/signal-pc.h new file mode 100644 index 00000000000..ccb2ac1c56f --- /dev/null +++ b/host/include/loongarch64/host/signal-pc.h @@ -0,0 +1,20 @@ +/* + * Program counter of an interrupted loongarch64 thread, from its signal frame. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef LOONGARCH64_HOST_SIGNAL_PC_H +#define LOONGARCH64_HOST_SIGNAL_PC_H + +#ifdef CONFIG_LINUX +#define HAVE_HOST_SIGNAL_PC 1 + +static inline uintptr_t host_signal_pc(const ucontext_t *uc) +{ + return uc->uc_mcontext.__pc; +} +#else +#define HAVE_HOST_SIGNAL_PC 0 +#endif + +#endif diff --git a/host/include/ppc64/host/signal-pc.h b/host/include/ppc64/host/signal-pc.h new file mode 100644 index 00000000000..1473570a39a --- /dev/null +++ b/host/include/ppc64/host/signal-pc.h @@ -0,0 +1,22 @@ +/* + * Program counter of an interrupted ppc64 thread, from its signal frame. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef PPC64_HOST_SIGNAL_PC_H +#define PPC64_HOST_SIGNAL_PC_H + +#ifdef CONFIG_LINUX +#include + +#define HAVE_HOST_SIGNAL_PC 1 + +static inline uintptr_t host_signal_pc(const ucontext_t *uc) +{ + return uc->uc_mcontext.gp_regs[PT_NIP]; +} +#else +#define HAVE_HOST_SIGNAL_PC 0 +#endif + +#endif diff --git a/host/include/riscv/host/signal-pc.h b/host/include/riscv/host/signal-pc.h new file mode 100644 index 00000000000..8db92513465 --- /dev/null +++ b/host/include/riscv/host/signal-pc.h @@ -0,0 +1,20 @@ +/* + * Program counter of an interrupted riscv thread, from its signal frame. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef RISCV_HOST_SIGNAL_PC_H +#define RISCV_HOST_SIGNAL_PC_H + +#ifdef CONFIG_LINUX +#define HAVE_HOST_SIGNAL_PC 1 + +static inline uintptr_t host_signal_pc(const ucontext_t *uc) +{ + return uc->uc_mcontext.__gregs[REG_PC]; +} +#else +#define HAVE_HOST_SIGNAL_PC 0 +#endif + +#endif diff --git a/host/include/s390x/host/signal-pc.h b/host/include/s390x/host/signal-pc.h new file mode 100644 index 00000000000..6ad809c9116 --- /dev/null +++ b/host/include/s390x/host/signal-pc.h @@ -0,0 +1,20 @@ +/* + * Program counter of an interrupted s390x thread, from its signal frame. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef S390X_HOST_SIGNAL_PC_H +#define S390X_HOST_SIGNAL_PC_H + +#ifdef CONFIG_LINUX +#define HAVE_HOST_SIGNAL_PC 1 + +static inline uintptr_t host_signal_pc(const ucontext_t *uc) +{ + return uc->uc_mcontext.psw.addr; +} +#else +#define HAVE_HOST_SIGNAL_PC 0 +#endif + +#endif diff --git a/host/include/x86_64/host/signal-pc.h b/host/include/x86_64/host/signal-pc.h new file mode 100644 index 00000000000..c94ad2e976f --- /dev/null +++ b/host/include/x86_64/host/signal-pc.h @@ -0,0 +1,20 @@ +/* + * Program counter of an interrupted x86_64 thread, from its signal frame. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef X86_64_HOST_SIGNAL_PC_H +#define X86_64_HOST_SIGNAL_PC_H + +#ifdef CONFIG_LINUX +#define HAVE_HOST_SIGNAL_PC 1 + +static inline uintptr_t host_signal_pc(const ucontext_t *uc) +{ + return uc->uc_mcontext.gregs[REG_RIP]; +} +#else +#define HAVE_HOST_SIGNAL_PC 0 +#endif + +#endif diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 31a13926013..8aebb639e4c 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -657,9 +657,10 @@ bool qemu_debugger_attached(void); * qemu_thread_states: * * Returns a newly allocated, newline terminated description of every thread - * in this process apart from the caller: its id, name, scheduler state and - * kernel stack, or NULL on a host that cannot report any of that. Where the - * kernel stack is privileged the description falls back to a wait channel. + * in this process apart from the caller: its id, name, scheduler state, the + * program counter it stopped at and its kernel stack, or NULL on a host that + * cannot report any of that. A privileged kernel stack falls back to a wait + * channel, and a host with no way to read a program counter omits it. */ char *qemu_thread_states(void); diff --git a/meson.build b/meson.build index 21ca6d0e2a9..1e799f7346a 100644 --- a/meson.build +++ b/meson.build @@ -2749,6 +2749,8 @@ config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice) config_host_data.set('HAVE_GLIB_WITH_ALIGNED_ALLOC', glib_has_aligned_alloc) config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util)) config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul', prefix: osdep_prefix)) +config_host_data.set('CONFIG_DLADDR', cc.has_function('dladdr', + prefix: osdep_prefix + '#include ')) config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include ')) if rbd.found() config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS', diff --git a/util/oslib-posix.c b/util/oslib-posix.c index d5aa7d398f1..c960df6a313 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -58,8 +58,13 @@ #include #endif +#ifdef CONFIG_DLADDR +#include +#endif + #include "qemu/memalign.h" #include "qemu/mmap-alloc.h" +#include "host/signal-pc.h" #define MAX_MEM_PREALLOC_THREAD_COUNT 16 @@ -168,8 +173,164 @@ static bool thread_stacks_readable(void) return readable; } -static void append_thread_state(GString *out, const char *tid) +/* Where a thread was, and where its line belongs in the report */ +typedef struct { + int tid; + size_t at; + void *pc; + int done; +} ThreadPc; + +#if HAVE_HOST_SIGNAL_PC + +/* How long to wait for the answers, however many threads were asked */ +#define THREAD_PC_WAIT_MS 100 + +/* + * Published to the handler, which runs in whichever thread was interrupted + * and so may only touch this with atomics: every qemu synchronisation + * primitive is built on a mutex, and none of them may be taken here. + * pc_handlers counts handlers between entry and exit, so the slots can be + * withdrawn and the last handler waited out before the caller frees them. + */ +static ThreadPc *pc_slots; +static int pc_nslots; +static int pc_handlers; + +static void thread_pc_handler(int sig, siginfo_t *si, void *ctx) +{ + ThreadPc *slots; + int me, i, n; + + qatomic_inc(&pc_handlers); + smp_mb__after_rmw(); + slots = qatomic_load_acquire(&pc_slots); + if (slots) { + n = qatomic_read(&pc_nslots); + me = qemu_get_thread_id(); + for (i = 0; i < n; i++) { + if (qatomic_read(&slots[i].tid) == me) { + slots[i].pc = (void *)host_signal_pc(ctx); + qatomic_store_release(&slots[i].done, 1); + break; + } + } + } + qatomic_dec(&pc_handlers); +} + +static bool thread_pc_armed(void) +{ + static int armed = -1; + struct sigaction sa; + + if (armed >= 0) { + return armed; + } + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = thread_pc_handler; + sa.sa_flags = SA_SIGINFO | SA_RESTART; + sigemptyset(&sa.sa_mask); + armed = sigaction(QEMU_SIG_INTROSPECT, &sa, NULL) == 0; + return armed; +} + +/* + * Ask every thread at once. Asking one at a time would spend the timeout + * again for each thread that never answers, and the threads that never + * answer are the ones a hung qemu has most of. + */ +static void thread_pc_collect(GArray *slots) { + int64_t deadline; + guint i; + int left; + + if (!slots->len || !thread_pc_armed()) { + return; + } + qatomic_set(&pc_nslots, slots->len); + qatomic_store_release(&pc_slots, &g_array_index(slots, ThreadPc, 0)); + + for (i = 0; i < slots->len; i++) { + ThreadPc *slot = &g_array_index(slots, ThreadPc, i); + + if (qemu_kill_thread(slot->tid, QEMU_SIG_INTROSPECT) < 0) { + qatomic_store_release(&slot->done, -1); + } + } + + deadline = g_get_monotonic_time() + THREAD_PC_WAIT_MS * 1000; + do { + left = 0; + for (i = 0; i < slots->len; i++) { + if (!qatomic_load_acquire(&g_array_index(slots, ThreadPc, + i).done)) { + left++; + } + } + if (!left) { + break; + } + g_usleep(1000); + } while (g_get_monotonic_time() < deadline); + + qatomic_set(&pc_slots, NULL); + /* Pairs with the barrier in thread_pc_handler() */ + smp_mb(); + while (qatomic_read(&pc_handlers)) { + g_usleep(1000); + } +} + +static void insert_thread_pc(GString *out, const ThreadPc *slot) +{ + g_autofree char *line = NULL; + void *pc = slot->pc; +#ifdef CONFIG_DLADDR + Dl_info info = { }; +#endif + + if (qatomic_read(&slot->done) != 1 || !pc) { + return; + } +#ifdef CONFIG_DLADDR + if (dladdr(pc, &info) && info.dli_sname) { + line = g_strdup_printf(" pc %p %s+0x%tx\n", pc, info.dli_sname, + (char *)pc - (char *)info.dli_saddr); + } else if (info.dli_fname && info.dli_fbase) { + /* + * dladdr() only knows exported symbols, so an address inside a + * library's own internals has none. The object and the offset + * within it still resolve later, the raw address does not. + */ + g_autofree char *obj = g_path_get_basename(info.dli_fname); + + line = g_strdup_printf(" pc %p %s+0x%tx\n", pc, obj, + (char *)pc - (char *)info.dli_fbase); + } +#endif + if (!line) { + line = g_strdup_printf(" pc %p\n", pc); + } + g_string_insert(out, slot->at, line); +} + +#else + +static void thread_pc_collect(GArray *slots) +{ +} + +static void insert_thread_pc(GString *out, const ThreadPc *slot) +{ +} + +#endif /* HAVE_HOST_SIGNAL_PC */ + +static void append_thread_state(GString *out, GArray *slots, const char *tid) +{ + ThreadPc slot = { }; g_autofree char *comm = read_task_file(tid, "comm"); g_autofree char *stat = NULL; g_autofree char *stack = NULL; @@ -194,6 +355,10 @@ static void append_thread_state(GString *out, const char *tid) } g_string_append_printf(out, " %-7s %-16s %c\n", tid, comm, state); + slot.tid = atoi(tid); + slot.at = out->len; + g_array_append_val(slots, slot); + /* A running thread has no settled kernel stack to unwind */ if (state != 'R' && thread_stacks_readable()) { stack = read_task_file(tid, "stack"); @@ -220,8 +385,10 @@ static void append_thread_state(GString *out, const char *tid) char *qemu_thread_states(void) { g_autoptr(GDir) dir = g_dir_open("/proc/self/task", 0, NULL); + g_autoptr(GArray) slots = g_array_new(FALSE, TRUE, sizeof(ThreadPc)); const char *tid; GString *out; + guint i; if (!dir) { return NULL; @@ -232,13 +399,23 @@ char *qemu_thread_states(void) out = g_string_new(NULL); while ((tid = g_dir_read_name(dir))) { if (atoi(tid) != qemu_get_thread_id()) { - append_thread_state(out, tid); + append_thread_state(out, slots, tid); } } if (!out->len) { g_string_free(out, TRUE); return NULL; } + + /* + * Only now, with every passive read taken, disturb the threads. Insert + * from the back so the offsets recorded above stay where they were. + */ + thread_pc_collect(slots); + for (i = slots->len; i > 0; i--) { + insert_thread_pc(out, &g_array_index(slots, ThreadPc, i - 1)); + } + return g_string_free(out, FALSE); } -- 2.53.0