From nobody Wed Feb 11 08:12:15 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 A134DC6FD1D for ; Tue, 4 Apr 2023 21:02:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236460AbjDDVCU (ORCPT ); Tue, 4 Apr 2023 17:02:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236433AbjDDVB7 (ORCPT ); Tue, 4 Apr 2023 17:01:59 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82E945BA3 for ; Tue, 4 Apr 2023 14:01:25 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id b124-20020a253482000000b00b72947f6a54so33428207yba.14 for ; Tue, 04 Apr 2023 14:01:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680642084; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=i5xLBjFXhcm9sYgimeLOoR7dRp+TOGDHizUYLczDSFs=; b=MR40FXnRWvM0PtNwbowixq5oiEk6TvBwN6ON4Eb72CUn7s3L2jydJtAU3Aef+oA/UY 61zED9hKdyXinbgivdq2ur/4/c/TEYdLU7p64Ze+BKPI3s1r11RoksYwLAsa9GU9THnp l67Ynb8L2gCE02Z/B/ERWP3xD4WYX5TikLoatemNqhCbHnInLnhIW7bR3NPDu9vU2VxX fRlElraht1JjTHhNSMwoTXw+BXRK1Bo+t8fdaKBFMb85uaPfsW1tGeSPbF2SghglNEj5 ZUPM4mmt23vNpmQbopvFOYHdv7ljhWs4NRbPwES4+rDxRnhKV7gxpwc+eIUmBJeNR4ou Yczg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680642084; 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=i5xLBjFXhcm9sYgimeLOoR7dRp+TOGDHizUYLczDSFs=; b=Ua4o1IMQwFUh9A6Fp9+ILKZPzxzRETyWO14rHAgHueLgUhPZp50wc67hTXy2Rn5FjT BGI6VqvHPR/1Z86pufaBofqIYCtNtiv6SGfZevQyGnDjM9GNM4qPduufInFvaoLUGEAY zDgHdJB4PVzcVngjdvjY5iP0sRsabQnyculx+bxnR9lnDc6rUdJKHtdo1TqFXUTzd0XY INTWG+BDGJTjtrOqw4grwNd/ZJsKS2fSfFv7dhAIZquxihXATLyQa2JF23yBrxNDJzQB j577wVT1H3wlGXJHzMT/w+xbbmmIq+65VYgi24xNTQjhM5OCto67n48d/Iw0AbI1iFr/ IMYA== X-Gm-Message-State: AAQBX9eULVmg27En//DumTXaYxjVriiFvbd4ClAV0xObcmel3ZYnk9OC iHKWErYZQ3YeWDLRhOYDdqXy/Jr1RsaY X-Google-Smtp-Source: AKy350b2Qp9xtHHizu722cnYV+snfN2OE0sUVZq5lE5vAnQsNBwrkZZStZmG1KNsXuhm4qMoVrlCIB27YRxP X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a051:e074:d6f:dc29]) (user=irogers job=sendgmr) by 2002:a81:c642:0:b0:546:63a:6e23 with SMTP id q2-20020a81c642000000b00546063a6e23mr2324766ywj.0.1680642084270; Tue, 04 Apr 2023 14:01:24 -0700 (PDT) Date: Tue, 4 Apr 2023 13:59:50 -0700 In-Reply-To: <20230404205954.2245628-1-irogers@google.com> Message-Id: <20230404205954.2245628-9-irogers@google.com> Mime-Version: 1.0 References: <20230404205954.2245628-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Subject: [PATCH v6 08/12] 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.348.gf938b09366-goog