From nobody Tue Feb 10 15:43:47 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 70EBCC6FD1D for ; Mon, 20 Mar 2023 03:43:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230024AbjCTDnK (ORCPT ); Sun, 19 Mar 2023 23:43:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36750 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229848AbjCTDmY (ORCPT ); Sun, 19 Mar 2023 23:42:24 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2729D227B9 for ; Sun, 19 Mar 2023 20:40:58 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-5419fb7d6c7so108802217b3.11 for ; Sun, 19 Mar 2023 20:40:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679283656; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Dx+Czfooqx4+y3PtKz3VngTOr7flvK3/ZnOwhjyajRw=; b=MnCFeZ3XYBxTeakZd+zOXa4Ab3HZffcdRzC8KKmGbbG9Fn9k1DFYzjlrNzkXYGXnxd 923XA9T3DkAR0cJ6qMDKJ9rhD3B6K8UXQ7POn0CCRqQcNXXrQxg5X0BE0b1a18KdG70D ul5rcjH1TSDixbX/5aMLw+P/mJ2v2v6aS45fo+mDzXKNT1tqCuO1ISTU5MXWf6YAVpTO 3nCtelHziS8hnvRvMZXud4/jWzVF9s8FLsd96uVwPGuS6/rBup1H+o/TDMxalS7iDz0Y SAUjZQ9vSBzD6XhPKS4ZAWFEt4Dxe2TohNmrm2CaXeTkKRG2T+JO6e8WEntCXe14Ejyh X20Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679283656; 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=Dx+Czfooqx4+y3PtKz3VngTOr7flvK3/ZnOwhjyajRw=; b=MiwLZBegECDVVZ18ng2pLMjnVky6QF4D6kneE3qNBHQaaW+F9hh6mg68I42LnUubWt XboYcUsu/W27SBF8eHQXLGtjkb/5MJi3DE2+menO2s2r/2o6N2WEyEf9k9/U12+E4xey AkLoHQj0HebW0nspawKa88+Zr512ZyduFQHSvM0VRaK9GcsNOMJna0/hR3gTOijiWcgD RN4n7HY4gK3cVMyaCzNH8UoKMtkvywbrxac3nAGGPd+pKYVm5mcXWaGqkjPEGQxyJbJ1 bogjMxjkAOE/QWtPZnn1CaGu7UUKS3nDtHtofxWFNSbBYcIkyUwBVi13V6IStmN39leX YpPg== X-Gm-Message-State: AO0yUKUiaexyPYFzEX3qW5lhDYcI/qTp828gbeVDWTgAFYPCQ7Kc+krm npTzaMrwy8p159qFJ3MfEL23w0gAHZ/a X-Google-Smtp-Source: AK7set8Tdbub04SSF+TbbYlkVgHxpVLE5t37DZ88uqqR1sEcI7ns7735e5AVy4IaYP0kJ8d3N8QRGJexgh2j X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:1895:9fa0:27f5:cb71]) (user=irogers job=sendgmr) by 2002:a05:6902:72b:b0:b6b:e967:920d with SMTP id l11-20020a056902072b00b00b6be967920dmr1240639ybt.13.1679283656703; Sun, 19 Mar 2023 20:40:56 -0700 (PDT) Date: Sun, 19 Mar 2023 20:38:06 -0700 In-Reply-To: <20230320033810.980165-1-irogers@google.com> Message-Id: <20230320033810.980165-19-irogers@google.com> Mime-Version: 1.0 References: <20230320033810.980165-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v4 18/22] 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 , "=?UTF-8?q?Andr=C3=A9=20Almeida?=" , 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.rc1.284.g88254d51c5-goog