From nobody Mon Feb 9 14:15:22 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 8F87CC6FD1C for ; Mon, 20 Mar 2023 21:26:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230376AbjCTVZ6 (ORCPT ); Mon, 20 Mar 2023 17:25:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49600 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230248AbjCTVZ2 (ORCPT ); Mon, 20 Mar 2023 17:25:28 -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 50AE6302A1 for ; Mon, 20 Mar 2023 14:24:49 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id 204-20020a250fd5000000b00b6d6655dc35so2966939ybp.6 for ; Mon, 20 Mar 2023 14:24:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347480; 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=Q+n6EUqhYj+IdoEFDVvk6ANpjHNNdXvaBW3gCdTMQk9mwjnqHSMUCPhxWeIfxMAHrI NVfKSReNTU7Gbn7DBB6hBcinYmRvdy7cdvjILkdjHstnuBAr2fiTwItkAHZZVcwtRT/f wtniKmWKLCmnaJZBne28dG+uWL2aO9QUhggoSfnUyz1dOfIAIXC52kYAgX5mX0H2gWv+ xI99cVholotXfrgkFhuxjtrv/O1jfHaGRPpakU4KTGVQPYjihtLkoObTJMRuWRE+ClM8 W0enLg1WWfYqJ5JFzq8jH1SK39d2Id+IqBkK9p/FHSmIndqDl9D4P+mS8ADJMBlnCh8Z 1L+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347480; 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=4tLNvKT9BPSZVfFqF0tJnNp7DXejkJ5O7epa3TaRJ0JOLkPrerDpJyj/OFGfiUPeRo Cg0AlPUyJm+VAOB1DxtvE3yha52H19CsgxEWsf4XodgUkOWXl/95Kq5tGJ8XDM8M03NL XAef2ymuMKuIOwROIVcgU/8B77+XUNb776Eijsq7L9yBIuhYpyHT7jC0PUqCIR8J7mro SBfKTLXnF6ArRMkE9ukniKUJJz5wFcwk4X4WSTMm5LVoFI8eDCGukDEfyrdwkmPn2XwU UmlKTaMnQ6ccEd8dqKMcLaJ4W43+9bC5gxPQPRt77BSXnh9bqwiD/gPOTx7Rse5dhf0G qt8Q== X-Gm-Message-State: AAQBX9fjaIzF2ZShhaJ5MK76rkVlNJYt8FdWAiBivMzejOCwbDjkVfTc vMBKGimc4HIMiBoOkus648MfWKUlxxuT X-Google-Smtp-Source: AKy350ZbdKh1NwspQyhPDDoyG/uJa2t17sY3CpDG/BXxxDQyfVAf2+UE9i8v/XL82NqaZ+NvaLUu30w+NNg7 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a25:5b84:0:b0:b67:d295:d614 with SMTP id p126-20020a255b84000000b00b67d295d614mr403541ybb.12.1679347479801; Mon, 20 Mar 2023 14:24:39 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:44 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-14-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 13/17] 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.rc1.284.g88254d51c5-goog