From nobody Tue Feb 10 02:59:46 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 85FB5C77B6C for ; Fri, 7 Apr 2023 23:04:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229535AbjDGXEl (ORCPT ); Fri, 7 Apr 2023 19:04:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57242 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229455AbjDGXEj (ORCPT ); Fri, 7 Apr 2023 19:04:39 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 38190E059 for ; Fri, 7 Apr 2023 16:04:38 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id z4-20020a25bb04000000b00b392ae70300so43700803ybg.21 for ; Fri, 07 Apr 2023 16:04:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680908678; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=59paec+IWSQBz2L9CjqeP22mRhkSxyuTil9toZzz+2E=; b=jlZb9danWvv+ixJf3PU7oMdPaoWTKji9N1XTbeOIi2Q4zCMVso1x0EQEF0GmrJFyqw /eBDqunf5xCemE7/Ccz8arnTjRSY6aqbJBDdXMN4PpMDNgMzY+dlKb7HClsohYGHS6y9 O8h5Q+X52uCBkRUwtyv0V80QU+dKa9YX+3Ot6UIS5oqzHZwJaYIsX76zjlRhRlr/QqzN WIivivWJL0jCQVgm9BV+51EMoC0akd0CxnxSdP86HYvW/brazjK+M1zDraRKi0G2RKpq PWcOiNPXSywqsFJVZHpFdyKJBTo4kEV0ykNE10v7Z13dDJxEqjFu7KBJt7nwTSxO2GWs lUsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680908678; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=59paec+IWSQBz2L9CjqeP22mRhkSxyuTil9toZzz+2E=; b=nlN9+eckEOBEIbiC+J1CMbGYOAYKEJN20EZNa4qLGx20lGk3ghjQqbMBby/YixBdbM Qs/ythoe9goFMs+q0L359l/VAoxIRDRsrzm+l4MFeyfbBPqctn/kOsaUKmwXQN2sFhKh Njykgn++wU5/2BOGmVEP7Rbmmx+P5qnUN2fbzk1TXrxtXnbEbtfbQBXsdR/dT/mwixUy Hs7p5eUSrJjPOD+RW7BTEsl49WWQUyomKdAkdRXy1fOsSn22TLsUcOuzAR/rb16ZryeF GM+lBvnv26u+64HzEEwuln6jiu2WlOOY8FfmtM8BEydzWYb4uxrCiEwxFfx4cDQkoGdN Y35Q== X-Gm-Message-State: AAQBX9dYKqv9Innxyx35/kh3NLxCnr/fMHve/YKbwRFSBXswqg7KKrdQ rTleGYU9TuKE9GnX4god0gdFzEorp57f X-Google-Smtp-Source: AKy350bKg/Da1VLiNEVJ2OJM6u7YBHcM9+S2I35CQPhyi/mADelAipjwwpcBKwDi+gl/5RcsJ4RaXJ0uPV/4 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:b240:9cdf:7861:b23e]) (user=irogers job=sendgmr) by 2002:a25:cbd6:0:b0:b6e:361a:c86 with SMTP id b205-20020a25cbd6000000b00b6e361a0c86mr314698ybg.3.1680908677793; Fri, 07 Apr 2023 16:04:37 -0700 (PDT) Date: Fri, 7 Apr 2023 16:04:01 -0700 In-Reply-To: <20230407230405.2931830-1-irogers@google.com> Message-Id: <20230407230405.2931830-2-irogers@google.com> Mime-Version: 1.0 References: <20230407230405.2931830-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.577.gac1e443424-goog Subject: [PATCH v7 1/5] libperf: Add reference count checking macros. From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov , Hao Luo Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The macros serve as a way to debug use of a reference counted struct. The macros add a memory allocated pointer that is interposed between the reference counted original struct at a get and freed by a put. The pointer replaces the original struct, so use of the struct name via APIs remains unchanged. Signed-off-by: Ian Rogers --- tools/lib/perf/include/internal/rc_check.h | 94 ++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 tools/lib/perf/include/internal/rc_check.h diff --git a/tools/lib/perf/include/internal/rc_check.h b/tools/lib/perf/in= clude/internal/rc_check.h new file mode 100644 index 000000000000..c0626d8beb59 --- /dev/null +++ b/tools/lib/perf/include/internal/rc_check.h @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ +#ifndef __LIBPERF_INTERNAL_RC_CHECK_H +#define __LIBPERF_INTERNAL_RC_CHECK_H + +#include +#include + +/* + * Shared reference count checking macros. + * + * Reference count checking is an approach to sanitizing the use of refere= nce + * counted structs. It leverages address and leak sanitizers to make sure = gets + * are paired with a put. Reference count checking adds a malloc-ed layer = of + * indirection on a get, and frees it on a put. A missed put will be repor= ted as + * a memory leak. A double put will be reported as a double free. Accessing + * after a put will cause a use-after-free and/or a segfault. + */ + +#ifndef REFCNT_CHECKING +/* Replaces "struct foo" so that the pointer may be interposed. */ +#define DECLARE_RC_STRUCT(struct_name) \ + struct struct_name + +/* Declare a reference counted struct variable. */ +#define RC_STRUCT(struct_name) struct struct_name + +/* + * Interpose the indirection. Result will hold the indirection and object = is the + * reference counted struct. + */ +#define ADD_RC_CHK(result, object) (result =3D object, object) + +/* Strip the indirection layer. */ +#define RC_CHK_ACCESS(object) object + +/* Frees the object and the indirection layer. */ +#define RC_CHK_FREE(object) free(object) + +/* A get operation adding the indirection layer. */ +#define RC_CHK_GET(result, object) ADD_RC_CHK(result, object) + +/* A put operation removing the indirection layer. */ +#define RC_CHK_PUT(object) {} + +#else + +/* Replaces "struct foo" so that the pointer may be interposed. */ +#define DECLARE_RC_STRUCT(struct_name) \ + struct original_##struct_name; \ + struct struct_name { \ + struct original_##struct_name *orig; \ + }; \ + struct original_##struct_name + +/* Declare a reference counted struct variable. */ +#define RC_STRUCT(struct_name) struct original_##struct_name + +/* + * Interpose the indirection. Result will hold the indirection and object = is the + * reference counted struct. + */ +#define ADD_RC_CHK(result, object) \ + ( \ + object ? (result =3D malloc(sizeof(*result)), \ + result ? (result->orig =3D object, result) \ + : (result =3D NULL, NULL)) \ + : (result =3D NULL, NULL) \ + ) + +/* Strip the indirection layer. */ +#define RC_CHK_ACCESS(object) object->orig + +/* Frees the object and the indirection layer. */ +#define RC_CHK_FREE(object) \ + do { \ + zfree(&object->orig); \ + free(object); \ + } while(0) + +/* A get operation adding the indirection layer. */ +#define RC_CHK_GET(result, object) ADD_RC_CHK(result, (object ? object->or= ig : NULL)) + +/* A put operation removing the indirection layer. */ +#define RC_CHK_PUT(object) \ + do { \ + if (object) { \ + object->orig =3D NULL; \ + free(object); \ + } \ + } while(0) + +#endif + +#endif /* __LIBPERF_INTERNAL_RC_CHECK_H */ --=20 2.40.0.577.gac1e443424-goog