From nobody Sun Jun 14 04:08:52 2026 Received: from mail-dy1-f202.google.com (mail-dy1-f202.google.com [74.125.82.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 52EF3372EFB for ; Sun, 3 May 2026 17:10:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777828247; cv=none; b=UWSoOv6xvMTKrlqpjkj8RUU3SJKDzvol29t/7J+e6QgrryKhIvnX8W7+3PNce+h6LZK1mwEJjsZ/wgKz0sMSirtuk8JG5GDA46y+e3sBKb+/cHa1rnHY2c11PXkbuV7T+CrTnRkuzyADsSvxV0oAzXaS0USyw/45JZcYpdAjQkQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777828247; c=relaxed/simple; bh=zbHYAlo7dJ6R+XPlY9Xu4bAywdb1MOjhflrOAQn4RfE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=KZH17WBTn0NkxSOO5L/tDy0adL6nZ5VFmb8jR/1nQGJnbt+l3FeoYbPY2209rw/xn514MPY/oKb7Qjj5M+ymZftLkJQPMgLAd25jEmXpiRXG9G5Q5Nv9EP+Zc/zLuLTvJpNumVHfuYYQdfQN4Ee2hdTPqKN1zDWe4QR4sqOPtzo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=rdTCbWwr; arc=none smtp.client-ip=74.125.82.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="rdTCbWwr" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-2ba8013a9e3so5493734eec.0 for ; Sun, 03 May 2026 10:10:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1777828245; x=1778433045; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=unHJ4YhQvNl3r+8GWeRKMAqsKkQhrEiTWJRAvguRxRM=; b=rdTCbWwrAjavKDBmauD3N0cNuZ8nYZ1LDD2N0T7b0+CCk3xH5kj05HP/ihvOUNDF8Z 55Ac6hcKUZLKFxUmocHjMQEu1K01xUQVVQkcB2gLOChAWTxbpobyiWVJ7pVp26vWhDUv 0pGFrERSMlclqzJ5uj+ljMDcBlLM78YEiCIAmTzJ5Ot56jaypfFZHOKnHTLEzWpAGK6E z9Mi3/lbXtnEXMjK2Pn7/UC90GGBgmcJsKKEku93zZxKf/cJ+q0MmBe9fJCyrmgH77vq ell9DBXUm3XHHk1ToDySvkE9Eo6+p+HtaswmLl2vFZ+DsDi1o8UtAhZR6bJTCLpTgxsN PObg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777828245; x=1778433045; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=unHJ4YhQvNl3r+8GWeRKMAqsKkQhrEiTWJRAvguRxRM=; b=BMfDK0KkgxIojgOMc5p8CkSJhd/mA4YqFlT6O0QpXnm2VtzSRI03VMGDc95/IIUnzR +Vhd+Yx8Tem/mcjeyX4zssTF/JT5UBhXyLjMuB0PXTPiGujyXjE9UbVObsiSrhpW5Q6A GgBS7sHTm2ipQINtmfTbiWpcY0CV3CsN+uOJ03pJZOEtuQeIYW/vqh/IYmOqUqPf0dYr 46Scb8/tsGWeU2b/LMT94TGu70grrwr9r/gcK9XrgneLqoigPmQx0WimQRkeW68pMiOf hBNjthBcI+b/qiMa3TrJpZn3OqLQl2h50xAzIOdW7F6dxpLWAx1xfTW746h6a/hYd4Q7 wt+g== X-Forwarded-Encrypted: i=1; AFNElJ+LHE7Wa9dtnbW4JdxjrDpRSU6uTvbLDUCSJMG9JWKttKB4f0vWcCH5Mc7Lo3IxK3IXHO/0GRhFvNdJaZY=@vger.kernel.org X-Gm-Message-State: AOJu0Yz2kMq8pPTXm53C9gCAnW1GARvLr3n8YkPHiMuZKGHuTTe3orH4 lxmUps4Je9RewDfiMrr9r2Lk1pTy1uhCz6lg2CjA+41Pigs/ezBaCZ50mA1DxGLfvPby9FdcahX Ll68HFxuuAA== X-Received: from dlbuy8.prod.google.com ([2002:a05:7022:1e08:b0:12d:cb64:e75d]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:4590:b0:122:2f4:b285 with SMTP id a92af1059eb24-12dfd81a3a7mr3135963c88.25.1777828245223; Sun, 03 May 2026 10:10:45 -0700 (PDT) Date: Sun, 3 May 2026 10:10:27 -0700 In-Reply-To: <20260503171032.1559338-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260503003552.1063540-1-irogers@google.com> <20260503171032.1559338-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.545.g6539524ca2-goog Message-ID: <20260503171032.1559338-2-irogers@google.com> Subject: [PATCH v4 1/6] perf dwarf-aux: Fix libdw segmentation fault in cu_walk_functions_at From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Adrian Hunter , James Clark , Zecheng Li , Masami Hiramatsu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ian Rogers Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A segmentation fault was observed in `libdw` when running `perf kmem` with `--page stat` on some workloads. The crash occurred deep inside `libdw` (specifically in `dwarf_child` and `dwarf_diename`) when processing DWARF information. The root cause was improper error handling of `dwarf_getfuncs` in `die_find_realfunc` and `die_find_tailfunc`. `dwarf_getfuncs` returns: - `0` on success (when all functions have been processed). - A positive offset if the callback aborts early (e.g., via `DWARF_CB_ABORT` when a match is found). - `-1` on error. The original code used `if (!dwarf_getfuncs(...)) return NULL;`. On error (`-1`), `!-1` evaluates to `0` (false), bypassing the error check. Execution then proceeded as if a match was found, returning uninitialized stack memory (`die_mem`) to the caller (`cu_walk_functions_at`). When `cu_walk_functions_at` passed this uninitialized memory to `libdw` via `dwarf_diename`, it caused a segmentation fault. Fix this by correcting the error check to `if (dwarf_getfuncs(...) <=3D 0)`. Fixes: e0d153c69040 ("perf-probe: Move dwarf library routines to dwarf-aux.= {c, h}") Fixes: d4c537e6bf86 ("perf probe: Ignore tail calls to probed functions") Assisted-by: Gemini-CLI:Google Gemini 3 Signed-off-by: Ian Rogers Acked-by: Namhyung Kim --- tools/perf/util/dwarf-aux.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 92db2fccc788..109a166a6d19 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -171,7 +171,6 @@ int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr = addr, } =20 return ret; - } =20 /** @@ -620,7 +619,7 @@ Dwarf_Die *die_find_tailfunc(Dwarf_Die *cu_die, Dwarf_A= ddr addr, ad.addr =3D addr; ad.die_mem =3D die_mem; /* dwarf_getscopes can't find subprogram. */ - if (!dwarf_getfuncs(cu_die, __die_search_func_tail_cb, &ad, 0)) + if (dwarf_getfuncs(cu_die, __die_search_func_tail_cb, &ad, 0) <=3D 0) return NULL; else return die_mem; @@ -659,7 +658,7 @@ Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_A= ddr addr, ad.addr =3D addr; ad.die_mem =3D die_mem; /* dwarf_getscopes can't find subprogram. */ - if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0)) + if (dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0) <=3D 0) return NULL; else return die_mem; --=20 2.54.0.545.g6539524ca2-goog From nobody Sun Jun 14 04:08:52 2026 Received: from mail-dy1-f202.google.com (mail-dy1-f202.google.com [74.125.82.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5464D3CF68D for ; Sun, 3 May 2026 17:10:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777828249; cv=none; b=nkAdkxMUygfw3XBIMGrhJFfOxcuAKpIFZQS69vCtc7XbHBct4OnZpkP7tcJoGVE2+ZUlKDKVXtsiFn9G1S/shdw11F1vQF9GJj543JdqcU9AvoHzDP8IFvKAv3zRtrwNO8rdgV4ZjxszFd3JeHWDg3r9a/Swnx1hmxiooCCWawA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777828249; c=relaxed/simple; bh=yjcs1D6pGw7KPynb26FlbUjS/OAEHH4cdgoxuoNVwLM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=SW86Y6pmlrxyY4MIgENXc98c8gdUag0f1Q6ink2wGb0z0Cxh2CNAoaF8pudLl7WwEOI0eCnPHY9QCSEZquV7ZSkV+LPPrUxCiUIc66e+lY418Ypqk5/m+fQMThgRGG9lFPkgJ4F5AIz5czrEKW5KaLgFi89DZIaE1CfbmziSg8A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=cgKka/Iz; arc=none smtp.client-ip=74.125.82.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="cgKka/Iz" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-2ef37c3f773so1559498eec.1 for ; Sun, 03 May 2026 10:10:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1777828247; x=1778433047; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=n7qKK0k5c4yxl6VaFAc+LrAt0pI1jotb392xlOeZ7Wo=; b=cgKka/IzZQS6nNYL9/vSrn0Q4VdE901nUshVtR8mCJOUDZUJOj9iWq55oioU9rBjcL o21muNUCydCoxuZOGplz9gxaElVEaco3srTxPeNBpENWfRU/v2s3mOf/+EMP+XwAM2u/ qYddpQ8n8qSmTPwD6JEhIZQDzpzkAmkR6k+ISwh2lkeUWDDQ+fCCD19bt20+DoAQ9YTg pXVlyJlJM0NWv+fqoKW2+JQ96GqFv0mfg9fgFxizIILoRhSyhu4EFk/ThgzP2qLeWa5P Rztk8IRfcm1fIP1SyCCKriKcchtffMOSXorxvNT73E3PQhxw9zQ2QagDdyfddadxKmUl e45Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777828247; x=1778433047; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=n7qKK0k5c4yxl6VaFAc+LrAt0pI1jotb392xlOeZ7Wo=; b=D7wrJWchryFGPR7b0te6ABLCIoMTCXTQNNkeQSIb+D8hduNwZb6lIqigTaTH6IKRwj HHdqwTUFpK9+16Ep5ibIQBgJTycLArUCnGwBZI891ggg0Rzp1I3r+BdHovcb60esKRXo Wjko7YMzoYZnJ0R5by7LSZX81j19kdyfuKGeRyHgQodE8Urq48aqZnKoml4C1eaioPGK oRV0W1LsRp1bODyf3CRwEGau5bkjprRTVYuY/+30101/o5s7IFDzLxZj3O17wFyfUQK0 xz4hUqm1akEf/1+mG6sg9hFP6evTKc2Vu8cKSRjpiK2rHJfRHO3KFbB+FIs3GxZL1uNt 4Dpg== X-Forwarded-Encrypted: i=1; AFNElJ/S2ws9HSza6slKiRS+eDD/DXycM1knC/cedRwKT+DHmxJeN2KUmjXJHnOs2uEB1PrzeCVWCdYk31jh58c=@vger.kernel.org X-Gm-Message-State: AOJu0Yxam74oS+LiNkUShDdoaZVjIRxdvvKOQqVXujoXUK4RbN8iKajw S5DTVCs0ie7jW0e5Valu4Zysp/mbZDUcCpnWp9Mj+U3WsAyTKcnctUxvKbej6AirBxXJTifkL2e Vip93ijYSIg== X-Received: from dybmk34.prod.google.com ([2002:a05:7301:ea2:b0:2ed:a84e:18d3]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7300:e68b:b0:2ea:4228:ab11 with SMTP id 5a478bee46e88-2efb7ad867amr3108657eec.3.1777828247156; Sun, 03 May 2026 10:10:47 -0700 (PDT) Date: Sun, 3 May 2026 10:10:28 -0700 In-Reply-To: <20260503171032.1559338-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260503003552.1063540-1-irogers@google.com> <20260503171032.1559338-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.545.g6539524ca2-goog Message-ID: <20260503171032.1559338-3-irogers@google.com> Subject: [PATCH v4 2/6] perf dwarf-aux: Fix libdw API contract violations From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Adrian Hunter , James Clark , Zecheng Li , Masami Hiramatsu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ian Rogers Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Check return values of `dwarf_decl_line` (where non-optional), `dwarf_getfuncs`, and `dwarf_lineaddr` to prevent using uninitialized stack variables or incorrectly reporting success on failure. For the root DIE in `die_walk_lines()`, `dwarf_decl_line` and `die_get_decl_file` are optional and their failures are handled gracefully to avoid breaking line walking on valid functions. Additionally: - Add NULL pointer protection for `strcmp()` in `die_walk_lines()` when `inf` or `decf` are NULL to prevent crashes on generated code. - Use `dwarf_attr_integrate` in `die_get_data_member_location` to correctly resolve inherited member locations (e.g. via abstract origin or specification). Fixes: 57f95bf5f882 ("perf probe: Show correct statement line number by per= f probe -l") Fixes: 3f4460a28fb2 ("perf probe: Filter out redundant inline-instances") Fixes: 75186a9b09e4 ("perf probe: Fix to show lines of sys_ functions corre= ctly") Fixes: e0d153c69040 ("perf-probe: Move dwarf library routines to dwarf-aux.= {c, h}") Fixes: 6243b9dc4c99 ("perf probe: Move dwarf specific functions to dwarf-au= x.c") Assisted-by: Gemini-CLI:Google Gemini 3 Signed-off-by: Ian Rogers --- v4: - Fix strcmp(NULL) risk and inherited member location fallbacks in dwarf-a= ux.c. --- tools/perf/util/dwarf-aux.c | 34 ++++++++++++++++------------------ tools/perf/util/dwarf-aux.h | 5 +++++ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 109a166a6d19..a8ab1c30d0ac 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -125,7 +125,8 @@ int cu_find_lineinfo(Dwarf_Die *cu_die, Dwarf_Addr addr, && die_entrypc(&die_mem, &faddr) =3D=3D 0 && faddr =3D=3D addr) { *fname =3D die_get_decl_file(&die_mem); - dwarf_decl_line(&die_mem, lineno); + if (dwarf_decl_line(&die_mem, lineno) !=3D 0) + return -ENOENT; goto out; } =20 @@ -459,7 +460,7 @@ int die_get_data_member_location(Dwarf_Die *mb_die, Dwa= rf_Word *offs) size_t nexpr; int ret; =20 - if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) =3D=3D NULL) + if (dwarf_attr_integrate(mb_die, DW_AT_data_member_location, &attr) =3D= =3D NULL) return -ENOENT; =20 if (dwarf_formudata(&attr, offs) !=3D 0) { @@ -795,8 +796,7 @@ static int __die_walk_instances_cb(Dwarf_Die *inst, voi= d *data) =20 /* Ignore redundant instances */ if (dwarf_tag(inst) =3D=3D DW_TAG_inlined_subroutine) { - dwarf_decl_line(origin, &tmp); - if (die_get_call_lineno(inst) =3D=3D tmp) { + if (dwarf_decl_line(origin, &tmp) =3D=3D 0 && die_get_call_lineno(inst) = =3D=3D tmp) { tmp =3D die_get_decl_fileno(origin); if (die_get_call_fileno(inst) =3D=3D tmp) return DIE_FIND_CB_CONTINUE; @@ -950,11 +950,6 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callba= ck_t callback, void *data) cu_die =3D dwarf_diecu(rt_die, &die_mem, NULL, NULL); dwarf_decl_line(rt_die, &decl); decf =3D die_get_decl_file(rt_die); - if (!decf) { - pr_debug2("Failed to get the declared file name of %s\n", - dwarf_diename(rt_die)); - return -EINVAL; - } } else cu_die =3D rt_die; if (!cu_die) { @@ -998,12 +993,11 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callb= ack_t callback, void *data) if (die_find_inlinefunc(rt_die, addr, &die_mem)) { /* Call-site check */ inf =3D die_get_call_file(&die_mem); - if ((inf && !strcmp(inf, decf)) && + if ((inf =3D=3D decf || (inf && decf && !strcmp(inf, decf))) && die_get_call_lineno(&die_mem) =3D=3D lineno) goto found; =20 - dwarf_decl_line(&die_mem, &inl); - if (inl !=3D decl || + if (dwarf_decl_line(&die_mem, &inl) !=3D 0 || inl !=3D decl || decf !=3D die_get_decl_file(&die_mem)) continue; } @@ -1034,8 +1028,10 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_call= back_t callback, void *data) .data =3D data, .retval =3D 0, }; - dwarf_getfuncs(cu_die, __die_walk_culines_cb, ¶m, 0); - ret =3D param.retval; + if (dwarf_getfuncs(cu_die, __die_walk_culines_cb, ¶m, 0) < 0) + ret =3D -EINVAL; + else + ret =3D param.retval; } =20 return ret; @@ -1939,10 +1935,12 @@ static bool die_get_postprologue_addr(unsigned long= entrypc_idx, break; } =20 - dwarf_lineaddr(line, postprologue_addr); - if (*postprologue_addr >=3D highpc) - dwarf_lineaddr(dwarf_onesrcline(lines, i - 1), - postprologue_addr); + if (dwarf_lineaddr(line, postprologue_addr) !=3D 0) + return false; + if (*postprologue_addr >=3D highpc) { + if (dwarf_lineaddr(dwarf_onesrcline(lines, i - 1), postprologue_addr) != =3D 0) + return false; + } =20 return true; } diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index a79968a2e573..161f0bf980b6 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h @@ -10,6 +10,11 @@ #include #include =20 +static inline const char *die_name(Dwarf_Die *die) +{ + return dwarf_diename(die) ?: ""; +} + struct strbuf; =20 /* Find the realpath of the target file */ --=20 2.54.0.545.g6539524ca2-goog From nobody Sun Jun 14 04:08:52 2026 Received: from mail-dl1-f74.google.com (mail-dl1-f74.google.com [74.125.82.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 32AA4370D5D for ; Sun, 3 May 2026 17:10:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777828251; cv=none; b=YudDIzAiPHAbrC2+rFNVMPCEbdy8i7jUE7g/IzpxzeKRzFxonEaCZd7BH3VqoLCUzi96tq+13TcshrkqO+20iImtjtMiTWNo58R8R2SG/Cp6UnQ0kQ99cALunjP4duZlgFmzZXAKh1j5qiJtt3qjxr1pXcWpR9ErzKEFYC+jZM8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777828251; c=relaxed/simple; bh=twLN1Z1yGMGWkKYCQ23p7Txv1I+kqyjqk5QXs5o7OfA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=BeJB0CzQIzjxaNyJIcL7vU75Cdkt2yz6Z3herx1IsTU2CtKBmo0L3zFs5NGDwytLnfhMai6bYQH4rVERMOMFwnsmLz0C7YUhbUugoPyNhDNuhyQQ5p2dCikhYw/Scjo/u+rx/DDfOQSq66xq4ljFSblql3+0OsDaipYXwhU6Gh0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=SksZGP3N; arc=none smtp.client-ip=74.125.82.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="SksZGP3N" Received: by mail-dl1-f74.google.com with SMTP id a92af1059eb24-12dfe06b670so6678913c88.0 for ; Sun, 03 May 2026 10:10:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1777828249; x=1778433049; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Ve6SWXuI0g3UIJWrk0QyWnJcnIHFUm99czrE0ptbwhQ=; b=SksZGP3NignalvcOCP7DegrTg6zdRAaxoZCPAOU2Av6E6kAKG0WwLH5USLQv7x609L JjrxX3PiW7EXoDhWPzN+UCDvPTJPSW4/sFF75/QxPZ7SjGKYkcw/oNbnIgNLsMjBy6uw VxIUzdMsg9h2zwtcuCqnR8yplQ3a4CfF317S/GAe0Iyrr43U5nYV4/aqf1ISDmxOaKwK x0L1whnKgK6bJ3NhFsKeSshdjAXOJu77DMPBG50lDsZdUERdpA2w1THuIrRKBnAYRpaW syKuhkm7FEM4+QfOAaA5jMIW4yQbC7EWFtetr7zRuAm+cXhIizuruuflbqk8GcwW71Zy BwFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777828249; x=1778433049; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Ve6SWXuI0g3UIJWrk0QyWnJcnIHFUm99czrE0ptbwhQ=; b=lboWUphqgbkoK3SGBVr5J/r6vA8/Y9o/CAkN/7y8RclzLKv+skJKqXxiVwG+YzxQ8C 4oRlRynG5ggiu0fhPJf/JF3ajFCdFrFeQzejuMLQnQO5LLh5lx/ApmYbhVKk0avaawtZ te9GYEOYlWB4RZlqVS8kQh6bbsIsik5jSt/NNitqtERQtRdxh3PuQA/ZFjolfQXqtW1t dBrAJvxsE2Awp2kkaSrdNeU207fhiWaeozPhrv8be57su1RTcaP5hKg92WW73EzcVIFk TqD9YXeqnnFUvjEwEH886+5TbcMtjNKhvvRO52ZDbaMTgLnSlnWpxQv/PJT5BqHDiLIC 3g7g== X-Forwarded-Encrypted: i=1; AFNElJ+kV43wTraGyuWGj6dz6nR4Lb51n9XTW1kLdX4cdlMgtEk5fwjOJ8iqts9VSWPfQrNaEuSBCyi8GyIbsPY=@vger.kernel.org X-Gm-Message-State: AOJu0YwjA+Pn8kq0aL83I53fhA5EMqd41c8s93MxWj6Sugt33ewlSyul Gjoq7C57sPhqy3mEuS/dpHTJ1r0J668P/XAk4PBC3fhzRkRzN95naflAdIgQFAdmELCblTFDCF0 glmZFbv0WCg== X-Received: from dlea6-n1.prod.google.com ([2002:a05:701b:4206:10b0:12d:e33d:70da]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:701b:271a:b0:130:68a1:a235 with SMTP id a92af1059eb24-13068a1a485mr294901c88.27.1777828249197; Sun, 03 May 2026 10:10:49 -0700 (PDT) Date: Sun, 3 May 2026 10:10:29 -0700 In-Reply-To: <20260503171032.1559338-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260503003552.1063540-1-irogers@google.com> <20260503171032.1559338-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.545.g6539524ca2-goog Message-ID: <20260503171032.1559338-4-irogers@google.com> Subject: [PATCH v4 3/6] perf libdw: Fix libdw API contract violations From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Adrian Hunter , James Clark , Zecheng Li , Masami Hiramatsu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ian Rogers Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Check return values of `dwfl_report_end` and `dwfl_module_addrdie`. Check `die_get_call_lineno` for errors. Additionally: - Introduce `inline_node__clear_frames()` to clean up partial allocations. - Ensure `*file` is freed and inline frames are cleared on error in `libdw__addr2line()` to prevent memory leaks and duplicated callchains when falling back to other unwinders. - Allow DWARF line 0 in `libdw_a2l_cb()`, as it is a valid reference for compiler-generated code. - Fix the parent srcline lookup in `libdw_a2l_cb()` to target the correct parent node depending on the callchain order (ORDER_CALLER/ORDER_CALLEE). Fixes: b7a2b011e962 ("perf powerpc: Unify the skip-callchain-idx libdw with= that for addr2line") Fixes: 88c51002d06f ("perf addr2line: Add a libdw implementation") Assisted-by: Gemini-CLI:Google Gemini 3 Signed-off-by: Ian Rogers --- v4: - Fix memory leaks and duplicated callchains on unwinding errors. - Support DWARF line 0 in inline list. - Fix callchain parent update in ORDER_CALLER mode. --- tools/perf/util/libdw.c | 84 +++++++++++++++++++++++++++++++-------- tools/perf/util/srcline.c | 9 ++++- tools/perf/util/srcline.h | 1 + 3 files changed, 77 insertions(+), 17 deletions(-) diff --git a/tools/perf/util/libdw.c b/tools/perf/util/libdw.c index 216977884103..e69ff4cea856 100644 --- a/tools/perf/util/libdw.c +++ b/tools/perf/util/libdw.c @@ -4,6 +4,7 @@ #include "srcline.h" #include "symbol.h" #include "dwarf-aux.h" +#include "callchain.h" #include #include #include @@ -60,7 +61,11 @@ struct Dwfl *dso__libdw_dwfl(struct dso *dso) return NULL; } =20 - dwfl_report_end(dwfl, /*removed=3D*/NULL, /*arg=3D*/NULL); + if (dwfl_report_end(dwfl, NULL, NULL) !=3D 0) { + dwfl_end(dwfl); + return NULL; + } + dso__set_libdw(dso, dwfl); =20 return dwfl; @@ -72,41 +77,70 @@ struct libdw_a2l_cb_args { struct inline_node *node; char *leaf_srcline; bool leaf_srcline_used; + int err; }; =20 static int libdw_a2l_cb(Dwarf_Die *die, void *_args) { struct libdw_a2l_cb_args *args =3D _args; - struct symbol *inline_sym =3D new_inline_sym(args->dso, args->sym, dwarf_= diename(die)); + const char *name =3D dwarf_diename(die); + struct symbol *inline_sym =3D new_inline_sym(args->dso, args->sym, name ?= : "unknown"); const char *call_fname =3D die_get_call_file(die); + int call_lineno =3D die_get_call_lineno(die); char *call_srcline =3D srcline__unknown; - struct inline_list *ilist; =20 - if (!inline_sym) - return -ENOMEM; + if (!inline_sym) { + args->err =3D -ENOMEM; + return DWARF_CB_ABORT; + } =20 /* Assign caller information to the parent. */ - if (call_fname) - call_srcline =3D srcline_from_fileline(call_fname, die_get_call_lineno(d= ie)); + if (call_fname && call_lineno >=3D 0) + call_srcline =3D srcline_from_fileline(call_fname, call_lineno); =20 - list_for_each_entry(ilist, &args->node->val, list) { - if (args->leaf_srcline =3D=3D ilist->srcline) + if (!list_empty(&args->node->val)) { + struct inline_list *parent; + + if (callchain_param.order =3D=3D ORDER_CALLEE) + parent =3D list_first_entry(&args->node->val, struct inline_list, list); + else + parent =3D list_last_entry(&args->node->val, struct inline_list, list); + + if (args->leaf_srcline =3D=3D parent->srcline) args->leaf_srcline_used =3D false; - else if (ilist->srcline !=3D srcline__unknown) - free(ilist->srcline); - ilist->srcline =3D call_srcline; + else if (parent->srcline !=3D srcline__unknown) + free(parent->srcline); + parent->srcline =3D call_srcline; call_srcline =3D NULL; - break; } if (call_srcline && call_srcline !=3D srcline__unknown) free(call_srcline); =20 /* Add this symbol to the chain as the leaf. */ if (!args->leaf_srcline_used) { - inline_list__append_tail(inline_sym, args->leaf_srcline, args->node); + if (inline_list__append_tail(inline_sym, args->leaf_srcline, args->node)= !=3D 0) { + args->err =3D -ENOMEM; + if (inline_sym->inlined) + symbol__delete(inline_sym); + return DWARF_CB_ABORT; + } args->leaf_srcline_used =3D true; } else { - inline_list__append_tail(inline_sym, strdup(args->leaf_srcline), args->n= ode); + char *srcline =3D strdup(args->leaf_srcline); + + if (!srcline) { + args->err =3D -ENOMEM; + if (inline_sym->inlined) + symbol__delete(inline_sym); + return DWARF_CB_ABORT; + } + if (inline_list__append_tail(inline_sym, srcline, args->node) !=3D 0) { + free(srcline); + args->err =3D -ENOMEM; + if (inline_sym->inlined) + symbol__delete(inline_sym); + return DWARF_CB_ABORT; + } } return 0; } @@ -162,11 +196,29 @@ int libdw__addr2line(u64 addr, char **file, unsigned = int *line_nr, .leaf_srcline =3D srcline_from_fileline(src ?: "", lineno), }; =20 + if (!args.leaf_srcline) { + if (file && *file) { + free(*file); + *file =3D NULL; + } + return 0; + } + /* Walk from the parent down to the leaf. */ - cu_walk_functions_at(cudie, addr, libdw_a2l_cb, &args); + if (cudie) + cu_walk_functions_at(cudie, addr, libdw_a2l_cb, &args); =20 if (!args.leaf_srcline_used) free(args.leaf_srcline); + + if (args.err) { + if (file && *file) { + free(*file); + *file =3D NULL; + } + inline_node__clear_frames(node); + return 0; + } } return 1; } diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index db164d258163..62884428fb5a 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -429,10 +429,13 @@ struct inline_node *dso__parse_addr_inlines(struct ds= o *dso, u64 addr, return addr2inlines(dso_name, addr, dso, sym); } =20 -void inline_node__delete(struct inline_node *node) +void inline_node__clear_frames(struct inline_node *node) { struct inline_list *ilist, *tmp; =20 + if (node =3D=3D NULL) + return; + list_for_each_entry_safe(ilist, tmp, &node->val, list) { list_del_init(&ilist->list); zfree_srcline(&ilist->srcline); @@ -441,7 +444,11 @@ void inline_node__delete(struct inline_node *node) symbol__delete(ilist->symbol); free(ilist); } +} =20 +void inline_node__delete(struct inline_node *node) +{ + inline_node__clear_frames(node); free(node); } =20 diff --git a/tools/perf/util/srcline.h b/tools/perf/util/srcline.h index 7c37b3bf9ce7..1018cbc886d6 100644 --- a/tools/perf/util/srcline.h +++ b/tools/perf/util/srcline.h @@ -47,6 +47,7 @@ struct inline_node *dso__parse_addr_inlines(struct dso *d= so, u64 addr, struct symbol *sym); /* free resources associated to the inline node list */ void inline_node__delete(struct inline_node *node); +void inline_node__clear_frames(struct inline_node *node); =20 /* insert the inline node list into the DSO, which will take ownership */ void inlines__tree_insert(struct rb_root_cached *tree, --=20 2.54.0.545.g6539524ca2-goog From nobody Sun Jun 14 04:08:52 2026 Received: from mail-dl1-f74.google.com (mail-dl1-f74.google.com [74.125.82.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 435E9372EF5 for ; Sun, 3 May 2026 17:10:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777828253; cv=none; b=K230JixmF39tdB9M7vhvyWvfi+xtf+AhKyTupvlNvosEMUBXzQ2C5InPMgRFBhk0gvIT+e5iST8Tmpqmsju+FX/64lgIexC1j3Ec+Hzl9YwOnAfxZsHkr0Y3AGLH4+KJ32Ia5batdskb4KXoQixPapxfBjzxU3AyRD4lpPzOsQg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777828253; c=relaxed/simple; bh=C2GxdJe9js5+0goHulNKSoB3Rt7Y/I6oioRhqshPbYU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=rLkcdX9qYDN+wSw3Qsqr9sCRvDNuNI7670Wkrfy3BjnU7cvI214SjyVVp5UTAUY0IVeqAvnQk3qqpKsp94Xv7OP6KKHvA2YPALeAbHc/ajKeeysObUjkATBxpJc4VKUDxv5fU60xYFhDjcD8MY6qqkOBodw94AOW6whlrhP3Yog= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=dGyFBYoq; arc=none smtp.client-ip=74.125.82.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dGyFBYoq" Received: by mail-dl1-f74.google.com with SMTP id a92af1059eb24-1275c6fc58aso6835782c88.0 for ; Sun, 03 May 2026 10:10:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1777828251; x=1778433051; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=6qnQeN+SdTQyhoZZJbPOiU1F4AhjFmLHplSWwVk2IH8=; b=dGyFBYoqNTlJHePeaGDhzAyAvizo1ddCH4RhevJWZAsFk53aHNtgKje2NSfavs/rj1 Vl/QT8co9FpM9Pt54RLsSX+6wyLueBnFKM5Wa6Gy2F/ZXydE2rmcJvG3mJ3oE9T9JhBX UQvVsU5FrVNxNAlSU3vuSDtIU8ZafvY6YxkNlus76XArVIjTfnsQd1zdrAmMmUHJ5uYF rlwG+Au87+eJeMIH5uu3A3rX6xH4AnIhBiZPyCnoE4T4nEsk6zTxO3QTOQqhv+9wyYc0 2qDhv/SGdShpvCAeBjBj2K8qpwvQkdC/lil22CqlkO2OIT+tPWzadoWlUYNxI5NUz9sr URCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777828251; x=1778433051; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=6qnQeN+SdTQyhoZZJbPOiU1F4AhjFmLHplSWwVk2IH8=; b=Eq+9RhwfwgMvSR9XQpl12trCpfokwSXn+V/h7JAEUqyS+GvajdsWPrmkxDJNAs74L0 sC2dR50E1/F5F9T0zz+fjMR3MbqzxTj70c5joDNoJU+mKVN1tVj6SToKhlwyJkGWQIZj SIgZguELEom+JA8iuOuByooJcwr3MgKrtcuGk3g0Ugb9Fced+wXyiBQvWHRq6gSM4Wg7 nz4IVqjF7eqkpopZwUgD/fdziIo5m6uHzZYKX9ONC+3Bsq6ihgpjYzrwOqoapZuCdFQm NitzecV642T/dtQRwHqXDclaKiPsYrHcX0YYOrNz8Xr2BepugW37rBCJ+TObSbS+L/Ma tpzg== X-Forwarded-Encrypted: i=1; AFNElJ8lOOlEiy7KI3AltCP+2OtI5mv1qFdCzMzLAVkR8Z33+yOLx101/Wjn9D1YlyyUe8hY/Su23yl27dRwqpQ=@vger.kernel.org X-Gm-Message-State: AOJu0YyyRxpjtFnJr76VXxD/Hz4HJ7pvtX7Hz00qq7n/GJZ+NEctSz7Y bkE+BXNeP64l1mNpmORvewcjYXwaQKMo1SGnhiiFacT5khhlwwsEhQEmKCkqQdNGA/nCiFlBcxb LcL4eUzALEg== X-Received: from dlb14.prod.google.com ([2002:a05:7022:60e:b0:12c:8bfc:84e3]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:43a3:b0:12b:ed30:5a32 with SMTP id a92af1059eb24-12dfd79e5aamr3132691c88.5.1777828250944; Sun, 03 May 2026 10:10:50 -0700 (PDT) Date: Sun, 3 May 2026 10:10:30 -0700 In-Reply-To: <20260503171032.1559338-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260503003552.1063540-1-irogers@google.com> <20260503171032.1559338-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.545.g6539524ca2-goog Message-ID: <20260503171032.1559338-5-irogers@google.com> Subject: [PATCH v4 4/6] perf probe-finder: Fix libdw API contract violations From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Adrian Hunter , James Clark , Zecheng Li , Masami Hiramatsu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ian Rogers Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Check return values of `dwarf_formsdata`, `dwarf_entrypc`, `dwarf_highpc`, `dwarf_bytesize`, `dwarf_attr`, `dwarf_decl_line`, `dwarf_getfuncs`, and `dwarf_formref_die`. Validate `dwarf_diename` and `dwarf_diecu` results to prevent potential crashes. Fix C90 mixed declarations. Additionally: - Avoid vfprintf undefined behavior with NULL strings by using the `die_name()` helper for `dwarf_diename()` in `pr_*` calls, including when warning about tail calls. - Prevent NULL pointer dereference in `convert_variable_fields()` when processing array elements for variables in registers. - Fallback to offset 0 in `line_range_search_cb()` instead of skipping functions without `DW_AT_decl_line`. - Relax `dwarf_getfuncs` error checking in `find_probe_point_by_func()` and `find_line_range_by_func()` to prevent premature CU search aborts, ensuring robustness against corrupted CUs. Fixes: 66f69b219716 ("perf probe: Support DW_AT_const_value constant value") Fixes: 3d918a12a1b3 ("perf probe: Find fentry mcount fuzzed parameter locat= ion") Fixes: bcfc082150c6 ("perf probe: Remove redundant dwarf functions") Fixes: 221d061182b8 ("perf probe: Fix to search local variables in appropri= ate scope") Fixes: b55a87ade383 ("perf probe: Remove die() from probe-finder code") Fixes: 4c859351226c ("perf probe: Support glob wildcards for function name") Assisted-by: Gemini-CLI:Google Gemini 3 Signed-off-by: Ian Rogers --- v4: - Safe DWARF name printing with die_name() to avoid NULL formatting crashe= s. - Fix NULL dereference in register variable array lookups. - Fix robust CU search loops by continuing on getfuncs errors. --- tools/perf/util/probe-finder.c | 105 +++++++++++++++++++++------------ 1 file changed, 68 insertions(+), 37 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 64328abeef8b..7f9761a29c08 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -79,7 +79,7 @@ static int convert_variable_location(Dwarf_Die *vr_die, D= warf_Addr addr, unsigned int regn; Dwarf_Word offs =3D 0; bool ref =3D false; - const char *regs; + const char *regs, *name; int ret, ret2 =3D 0; =20 if (dwarf_attr(vr_die, DW_AT_external, &attr) !=3D NULL) @@ -93,7 +93,8 @@ static int convert_variable_location(Dwarf_Die *vr_die, D= warf_Addr addr, if (!tvar) return 0; =20 - dwarf_formsdata(&attr, &snum); + if (dwarf_formsdata(&attr, &snum) !=3D 0) + return -ENOENT; ret =3D asprintf(&tvar->value, "\\%ld", (long)snum); =20 return ret < 0 ? -ENOMEM : 0; @@ -103,8 +104,7 @@ static int convert_variable_location(Dwarf_Die *vr_die,= Dwarf_Addr addr, if (dwarf_attr(vr_die, DW_AT_location, &attr) =3D=3D NULL) return -EINVAL; /* Broken DIE ? */ if (dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <=3D 0) { - ret =3D dwarf_entrypc(sp_die, &tmp); - if (ret) + if (dwarf_entrypc(sp_die, &tmp) !=3D 0) return -ENOENT; =20 if (probe_conf.show_location_range && @@ -115,8 +115,7 @@ static int convert_variable_location(Dwarf_Die *vr_die,= Dwarf_Addr addr, return -ENOENT; } =20 - ret =3D dwarf_highpc(sp_die, &tmp); - if (ret) + if (dwarf_highpc(sp_die, &tmp) !=3D 0) return -ENOENT; /* * This is fuzzed by fentry mcount. We try to find the @@ -138,12 +137,16 @@ static int convert_variable_location(Dwarf_Die *vr_di= e, Dwarf_Addr addr, static_var: if (!tvar) return ret2; + /* Static variables on memory (not stack), make @varname */ - ret =3D strlen(dwarf_diename(vr_die)); + name =3D dwarf_diename(vr_die); + if (!name) + return -ENOENT; + ret =3D strlen(name); tvar->value =3D zalloc(ret + 2); if (tvar->value =3D=3D NULL) return -ENOMEM; - snprintf(tvar->value, ret + 2, "@%s", dwarf_diename(vr_die)); + snprintf(tvar->value, ret + 2, "@%s", name); tvar->ref =3D alloc_trace_arg_ref((long)offs); if (tvar->ref =3D=3D NULL) return -ENOMEM; @@ -234,13 +237,14 @@ static int convert_variable_type(Dwarf_Die *vr_die, } =20 if (die_get_real_type(vr_die, &type) =3D=3D NULL) { - pr_warning("Failed to get a type information of %s.\n", - dwarf_diename(vr_die)); + const char *name =3D dwarf_diename(vr_die); + + pr_warning("Failed to get a type information of %s.\n", name ?: ""); return -ENOENT; } =20 pr_debug("%s type is %s.\n", - dwarf_diename(vr_die), dwarf_diename(&type)); + die_name(vr_die), die_name(&type)); =20 if (cast && (!strcmp(cast, "string") || !strcmp(cast, "ustring"))) { /* String type */ @@ -249,7 +253,7 @@ static int convert_variable_type(Dwarf_Die *vr_die, ret !=3D DW_TAG_array_type) { pr_warning("Failed to cast into string: " "%s(%s) is not a pointer nor array.\n", - dwarf_diename(vr_die), dwarf_diename(&type)); + die_name(vr_die), die_name(&type)); return -EINVAL; } if (die_get_real_type(&type, &type) =3D=3D NULL) { @@ -272,7 +276,7 @@ static int convert_variable_type(Dwarf_Die *vr_die, !die_compare_name(&type, "unsigned char")) { pr_warning("Failed to cast into string: " "%s is not (unsigned) char *.\n", - dwarf_diename(vr_die)); + die_name(vr_die)); return -EINVAL; } tvar->type =3D strdup(cast); @@ -299,7 +303,7 @@ static int convert_variable_type(Dwarf_Die *vr_die, /* Check the bitwidth */ if (ret > MAX_BASIC_TYPE_BITS) { pr_info("%s exceeds max-bitwidth. Cut down to %d bits.\n", - dwarf_diename(&type), MAX_BASIC_TYPE_BITS); + die_name(&type), MAX_BASIC_TYPE_BITS); ret =3D MAX_BASIC_TYPE_BITS; } ret =3D snprintf(buf, 16, "%c%d", prefix, ret); @@ -333,12 +337,14 @@ static int convert_variable_fields(Dwarf_Die *vr_die,= const char *varname, pr_warning("Failed to get the type of %s.\n", varname); return -ENOENT; } - pr_debug2("Var real type: %s (%x)\n", dwarf_diename(&type), + pr_debug2("Var real type: %s (%x)\n", die_name(&type), (unsigned)dwarf_dieoffset(&type)); tag =3D dwarf_tag(&type); =20 if (field->name[0] =3D=3D '[' && (tag =3D=3D DW_TAG_array_type || tag =3D=3D DW_TAG_pointer_type)) { + int bsize; + /* Save original type for next field or type */ memcpy(die_mem, &type, sizeof(*die_mem)); /* Get the type of this array */ @@ -346,7 +352,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, c= onst char *varname, pr_warning("Failed to get the type of %s.\n", varname); return -ENOENT; } - pr_debug2("Array real type: %s (%x)\n", dwarf_diename(&type), + pr_debug2("Array real type: %s (%x)\n", die_name(&type), (unsigned)dwarf_dieoffset(&type)); if (tag =3D=3D DW_TAG_pointer_type) { ref =3D zalloc(sizeof(struct probe_trace_arg_ref)); @@ -357,7 +363,15 @@ static int convert_variable_fields(Dwarf_Die *vr_die, = const char *varname, else *ref_ptr =3D ref; } - ref->offset +=3D dwarf_bytesize(&type) * field->index; + bsize =3D dwarf_bytesize(&type); + + if (bsize < 0) + return -EINVAL; + if (!ref) { + pr_warning("Array indexing not supported for variables in registers.\n"= ); + return -ENOTSUP; + } + ref->offset +=3D bsize * field->index; ref->user_access =3D user_access; goto next; } else if (tag =3D=3D DW_TAG_pointer_type) { @@ -414,7 +428,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, c= onst char *varname, =20 if (die_find_member(&type, field->name, die_mem) =3D=3D NULL) { pr_warning("%s(type:%s) has no member %s.\n", varname, - dwarf_diename(&type), field->name); + die_name(&type), field->name); return -EINVAL; } =20 @@ -461,7 +475,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct p= robe_finder *pf) int ret; =20 pr_debug("Converting variable %s into trace event.\n", - dwarf_diename(vr_die)); + die_name(vr_die)); =20 ret =3D convert_variable_location(vr_die, pf->addr, pf->fb_ops, &pf->sp_die, pf, pf->tvar); @@ -542,7 +556,7 @@ static int convert_to_trace_point(Dwarf_Die *sp_die, Dw= fl_Module *mod, /* Verify the address is correct */ if (!dwarf_haspc(sp_die, paddr)) { pr_warning("Specified offset is out of %s\n", - dwarf_diename(sp_die)); + die_name(sp_die)); return -EINVAL; } =20 @@ -599,7 +613,7 @@ static int call_probe_finder(Dwarf_Die *sc_die, struct = probe_finder *pf) if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) { if (die_find_tailfunc(&pf->cu_die, pf->addr, &pf->sp_die)) { pr_warning("Ignoring tail call from %s\n", - dwarf_diename(&pf->sp_die)); + die_name(&pf->sp_die)); return 0; } else { pr_warning("Failed to find probe point in any " @@ -611,10 +625,16 @@ static int call_probe_finder(Dwarf_Die *sc_die, struc= t probe_finder *pf) memcpy(&pf->sp_die, sc_die, sizeof(Dwarf_Die)); =20 /* Get the frame base attribute/ops from subprogram */ - dwarf_attr(&pf->sp_die, DW_AT_frame_base, &fb_attr); - ret =3D dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1); - if (ret <=3D 0 || nops =3D=3D 0) { + if (dwarf_attr(&pf->sp_die, DW_AT_frame_base, &fb_attr) =3D=3D NULL) { pf->fb_ops =3D NULL; + } else { + ret =3D dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1= ); + if (ret <=3D 0 || nops =3D=3D 0) + pf->fb_ops =3D NULL; + } + + if (pf->fb_ops =3D=3D NULL) { + /* Not supported */ } else if (nops =3D=3D 1 && pf->fb_ops[0].atom =3D=3D DW_OP_call_frame_cf= a && (pf->cfi_eh !=3D NULL || pf->cfi_dbg !=3D NULL)) { if ((dwarf_cfi_addrframe(pf->cfi_eh, pf->addr, &frame) !=3D 0 && @@ -667,8 +687,8 @@ static int find_best_scope_cb(Dwarf_Die *fn_die, void *= data) } } else { /* With the line number, find the nearest declared DIE */ - dwarf_decl_line(fn_die, &lno); - if (lno < fsp->line && fsp->diff > fsp->line - lno) { + if (dwarf_decl_line(fn_die, &lno) =3D=3D 0 && lno < fsp->line && + fsp->diff > fsp->line - lno) { /* Keep a candidate and continue */ fsp->diff =3D fsp->line - lno; memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die)); @@ -924,12 +944,12 @@ static int probe_point_inline_cb(Dwarf_Die *in_die, v= oid *data) /* Get probe address */ if (die_entrypc(in_die, &addr) !=3D 0) { pr_warning("Failed to get entry address of %s.\n", - dwarf_diename(in_die)); + die_name(in_die)); return -ENOENT; } if (addr =3D=3D 0) { pr_debug("%s has no valid entry address. skipped.\n", - dwarf_diename(in_die)); + die_name(in_die)); return -ENOENT; } pf->addr =3D addr; @@ -971,12 +991,13 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, v= oid *data) if (pp->file && fname && strtailcmp(pp->file, fname)) return DWARF_CB_OK; =20 - pr_debug("Matched function: %s [%lx]\n", dwarf_diename(sp_die), + pr_debug("Matched function: %s [%lx]\n", die_name(sp_die), (unsigned long)dwarf_dieoffset(sp_die)); pf->fname =3D fname; pf->abstrace_dieoffset =3D dwarf_dieoffset(sp_die); if (pp->line) { /* Function relative line */ - dwarf_decl_line(sp_die, &pf->lno); + if (dwarf_decl_line(sp_die, &pf->lno) !=3D 0) + return DWARF_CB_OK; pf->lno +=3D pp->line; param->retval =3D find_probe_point_by_line(pf); } else if (die_is_func_instance(sp_die)) { @@ -985,7 +1006,7 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, vo= id *data) /* But in some case the entry address is 0 */ if (pf->addr =3D=3D 0) { pr_debug("%s has no entry PC. Skipped\n", - dwarf_diename(sp_die)); + die_name(sp_die)); param->retval =3D 0; /* Real function */ } else if (pp->lazy_line) @@ -1018,7 +1039,8 @@ static int find_probe_point_by_func(struct probe_find= er *pf) { struct dwarf_callback_param _param =3D {.data =3D (void *)pf, .retval =3D 0}; - dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0); + if (dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0) < 0) + pr_debug("Failed to get functions from CU\n"); return _param.retval; } =20 @@ -1207,7 +1229,8 @@ static int copy_variables_cb(Dwarf_Die *die_mem, void= *data) * points to correct die. */ if (dwarf_attr(die_mem, DW_AT_abstract_origin, &attr)) { - dwarf_formref_die(&attr, &var_die); + if (dwarf_formref_die(&attr, &var_die) =3D=3D NULL) + goto out; if (pf->abstrace_dieoffset !=3D dwarf_dieoffset(&var_die)) goto out; } @@ -1270,6 +1293,8 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, s= truct probe_finder *pf) struct probe_trace_event *tev; struct perf_probe_arg *args =3D NULL; int ret, i; + const char *realname; + Dwarf_Die cu_die_mem; =20 /* * For some reason (e.g. different column assigned to same address) @@ -1293,13 +1318,17 @@ static int add_probe_trace_event(Dwarf_Die *sc_die,= struct probe_finder *pf) if (ret < 0) goto end; =20 - tev->point.realname =3D strdup(dwarf_diename(sc_die)); + realname =3D dwarf_diename(sc_die); + tev->point.realname =3D strdup(realname ?: "unknown"); if (!tev->point.realname) { ret =3D -ENOMEM; goto end; } =20 - tev->lang =3D dwarf_srclang(dwarf_diecu(sc_die, &pf->cu_die, NULL, NULL)); + if (dwarf_diecu(sc_die, &cu_die_mem, NULL, NULL) !=3D NULL) + tev->lang =3D dwarf_srclang(&cu_die_mem); + else + tev->lang =3D DW_LANG_C; // Fallback =20 pr_debug("Probe point found: %s+%lu\n", tev->point.symbol, tev->point.offset); @@ -1794,7 +1823,8 @@ static int line_range_search_cb(Dwarf_Die *sp_die, vo= id *data) =20 if (die_match_name(sp_die, lr->function) && die_is_func_def(sp_die)) { lf->fname =3D die_get_decl_file(sp_die); - dwarf_decl_line(sp_die, &lr->offset); + if (dwarf_decl_line(sp_die, &lr->offset) !=3D 0) + lr->offset =3D 0; // Fallback if no line info pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset); lf->lno_s =3D lr->offset + lr->start; if (lf->lno_s < 0) /* Overflow */ @@ -1818,7 +1848,8 @@ static int line_range_search_cb(Dwarf_Die *sp_die, vo= id *data) static int find_line_range_by_func(struct line_finder *lf) { struct dwarf_callback_param param =3D {.data =3D (void *)lf, .retval =3D = 0}; - dwarf_getfuncs(&lf->cu_die, line_range_search_cb, ¶m, 0); + if (dwarf_getfuncs(&lf->cu_die, line_range_search_cb, ¶m, 0) < 0) + pr_debug("Failed to get functions from CU\n"); return param.retval; } =20 --=20 2.54.0.545.g6539524ca2-goog From nobody Sun Jun 14 04:08:52 2026 Received: from mail-dy1-f201.google.com (mail-dy1-f201.google.com [74.125.82.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DBC7D3CCFCA for ; Sun, 3 May 2026 17:10:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777828255; cv=none; b=s0kSo4SvU1hulkNI0LSk3o1hOr2ezXESqi9AJJr2ZKLApD0kZXdGz7X19SI1dZn2mQW62bttTwFKjphFAK3SRN/1r3Kf6J+/1VkXLIeoRAsl0CLi2sVJvciV37uHyb8T9wfxHw4K4OEcYf40Oq7QdfzGO2FKHzHugVv4ScZwF88= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777828255; c=relaxed/simple; bh=5ANgtqZcdHupGEjzhsCuRbNnzfgu2X6dZdqc5Q0ebrI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=lpZqakICLNFaZpZHH1LvsBtvTCWBMIgNpMiWXb//63nfJ/BEglEM4WoIc7CwSyi3YcvcBM2C/5xLjNhBcCxUzJcumedU4B3b1ShFKnmsBf/g54GuiZCu438MFyOr5lH+Lw5pXqb+/OepYmfaLdBwmsa8ewA6qsV6K17pY3a7A0Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=FZvcuPAQ; arc=none smtp.client-ip=74.125.82.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="FZvcuPAQ" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2ee1da7a13fso3039905eec.1 for ; Sun, 03 May 2026 10:10:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1777828253; x=1778433053; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=5/EJWbfv09KofvOl4dto1edm7VYIyTldbr310LMAAT0=; b=FZvcuPAQzD7yCxR2DLHiOFnYny5ezWsy48ZAsyS5kaL4UD9Tno4JzJ7ajen+s/7y0n vEmvuDaWx3bZEwvnbK9B7DrBwoghka9XO1LKaTEwHbxLYKHWYH3k6SDk+AgUaWp3oTMP nWGrIkKsnI5VrXMSNJo+roVidBA/H4AR7NE4/U/2fsQFMG4daolPiO54cf2t9MfGMV0W WQNS8bG9AlfXk13DHQYahOIx4+LBgHwX1i94eZcF7VQEb98SVm/BrEqxvHZMy//AOHvb mYdF+EgIad1Idbe29FQaERjucUMd8CmiWuGS41LS/oCAYvdsrafsuioQLLYRrOe0yRgx jRmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777828253; x=1778433053; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=5/EJWbfv09KofvOl4dto1edm7VYIyTldbr310LMAAT0=; b=M1PYAP3OehZkY7NjTbL+TS98Yi94xpVmkvBKdCUjNrrfgrfY8iMzLybp4Oi/yyG8HH 7QVn5WAKjJb2fusSYU+ertlpao48w2Dn3sYQut70eqGH8/2FJzWodxMbx6UaBgWVZN/g RdAEtI/R3QNp12aRFZgg3ILdkqPl6kvlCew6WUyEEWCDnIZDSsvlKmLb/V+twgw6glWG 3Jm01Z2ccYgpyohmgy/8z3a9/HeSfA2f285ZiWnOpOH27CAXyVsWNJLVdT3jr/oT9FGc kGBl+4Ybycd4s0iV/ZgGMwV9eWNC3b5nxcv3tDeuJJs9M7Dga3+gU0SvbpAAAJnq7ypt RWuQ== X-Forwarded-Encrypted: i=1; AFNElJ9hJc9XVWgq+0fMoHIwXIZJjAadxtuwTJibprWVK6UKJKIRoP9Xc9WskNPkN8QS3CAPdoGGLJklogZbyaM=@vger.kernel.org X-Gm-Message-State: AOJu0YzX8Bga/9cxC9rMS7o6TN865/VPDrEKT5YiwtP/AeYvuiQnxpO+ q5lI5PhBE2IicxqhAdAFiV4C55h2fRc2sIDRHt85bh+hEt60Gjw8N95/MKTea19HHBmlRgAS/qp IBgUL8hPacg== X-Received: from dlec12-n2.prod.google.com ([2002:a05:701b:428c:20b0:12b:fba9:5eb0]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:6628:b0:122:33e:6d41 with SMTP id a92af1059eb24-12dfd84327fmr3007412c88.23.1777828252768; Sun, 03 May 2026 10:10:52 -0700 (PDT) Date: Sun, 3 May 2026 10:10:31 -0700 In-Reply-To: <20260503171032.1559338-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260503003552.1063540-1-irogers@google.com> <20260503171032.1559338-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.545.g6539524ca2-goog Message-ID: <20260503171032.1559338-6-irogers@google.com> Subject: [PATCH v4 5/6] perf annotate-data: Fix libdw API contract violations From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Adrian Hunter , James Clark , Zecheng Li , Masami Hiramatsu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ian Rogers Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Check return values of `dwarf_aggregate_size` and `dwarf_formudata`. Additionally: - Avoid `vfprintf` undefined behavior with `NULL` strings by using the `die_name()` helper for `dwarf_diename()` in `pr_*` calls. - Use `die_get_data_member_location()` (updated to use `dwarf_attr_integrate`) to correctly parse location expressions for inherited member locations in the fallback path when `dwarf_formudata()` fails. Fixes: 2bc3cf575a16 ("perf annotate-data: Improve debug message with locati= on info") Fixes: 4a111cadac85 ("perf annotate-data: Add member field in the data type= ") Fixes: 8b1042c425f6 ("perf annotate-data: Set bitfield member offset and si= ze properly") Fixes: fc044c53b99f ("perf annotate-data: Add dso->data_types tree") Assisted-by: Gemini-CLI:Google Gemini 3 Signed-off-by: Ian Rogers --- v4: - Safe DWARF name printing in annotate-data. - Fix fallback location expression parsing for inherited data members. --- tools/perf/util/annotate-data.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 1eff0a27237d..2eacbba51f32 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -74,7 +74,8 @@ void pr_debug_type_name(Dwarf_Die *die, enum type_state_k= ind kind) break; } =20 - dwarf_aggregate_size(die, &size); + if (dwarf_aggregate_size(die, &size) !=3D 0) + size =3D 0; =20 strbuf_init(&sb, 32); die_get_typename_from_type(die, &sb); @@ -146,9 +147,9 @@ static void pr_debug_scope(Dwarf_Die *scope_die) =20 tag =3D dwarf_tag(scope_die); if (tag =3D=3D DW_TAG_subprogram) - pr_info("[function] %s\n", dwarf_diename(scope_die)); + pr_info("[function] %s\n", die_name(scope_die)); else if (tag =3D=3D DW_TAG_inlined_subroutine) - pr_info("[inlined] %s\n", dwarf_diename(scope_die)); + pr_info("[inlined] %s\n", die_name(scope_die)); else if (tag =3D=3D DW_TAG_lexical_block) pr_info("[block]\n"); else @@ -250,9 +251,12 @@ static int __add_member_cb(Dwarf_Die *die, void *arg) if (dwarf_aggregate_size(&die_mem, &size) < 0) size =3D 0; =20 - if (dwarf_attr_integrate(die, DW_AT_data_member_location, &attr)) - dwarf_formudata(&attr, &loc); - else { + if (dwarf_attr_integrate(die, DW_AT_data_member_location, &attr)) { + if (dwarf_formudata(&attr, &loc) !=3D 0) { + if (die_get_data_member_location(die, &loc) !=3D 0) + loc =3D 0; + } + } else { /* bitfield member */ if (dwarf_attr_integrate(die, DW_AT_data_bit_offset, &attr) && dwarf_formudata(&attr, &loc) =3D=3D 0) @@ -273,7 +277,9 @@ static int __add_member_cb(Dwarf_Die *die, void *arg) dwarf_diename(die), (long)bit_size) < 0) member->var_name =3D NULL; } else { - member->var_name =3D strdup(dwarf_diename(die)); + const char *name =3D dwarf_diename(die); + + member->var_name =3D strdup(name); } =20 if (member->var_name =3D=3D NULL) { @@ -370,7 +376,8 @@ static struct annotated_data_type *dso__findnew_data_ty= pe(struct dso *dso, if (dwarf_tag(type_die) =3D=3D DW_TAG_typedef) die_get_real_type(type_die, type_die); =20 - dwarf_aggregate_size(type_die, &size); + if (dwarf_aggregate_size(type_die, &size) !=3D 0) + size =3D 0; =20 /* Check existing nodes in dso->data_types tree */ key.self.type_name =3D type_name; @@ -1569,7 +1576,7 @@ static int find_data_type_die(struct data_loc_info *d= loc, Dwarf_Die *type_die) offset =3D loc->offset; =20 pr_debug_dtp("CU for %s (die:%#lx)\n", - dwarf_diename(&cu_die), (long)dwarf_dieoffset(&cu_die)); + die_name(&cu_die), (long)dwarf_dieoffset(&cu_die)); =20 if (reg =3D=3D DWARF_REG_PC) { if (get_global_var_type(&cu_die, dloc, dloc->ip, dloc->var_addr, @@ -1636,7 +1643,7 @@ static int find_data_type_die(struct data_loc_info *d= loc, Dwarf_Die *type_die) } =20 pr_debug_dtp("found \"%s\" (die: %#lx) in scope=3D%d/%d (die: %#lx) ", - dwarf_diename(&var_die), (long)dwarf_dieoffset(&var_die), + die_name(&var_die), (long)dwarf_dieoffset(&var_die), i+1, nr_scopes, (long)dwarf_dieoffset(&scopes[i])); =20 if (reg =3D=3D DWARF_REG_PC) { --=20 2.54.0.545.g6539524ca2-goog From nobody Sun Jun 14 04:08:52 2026 Received: from mail-dy1-f202.google.com (mail-dy1-f202.google.com [74.125.82.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 15AB03D330C for ; Sun, 3 May 2026 17:10:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777828257; cv=none; b=nu6wUJ/mlBDgJXs/VxxE7sB2DdflacNTTBsSqxwJbYAM9qVc3w0puijW/fNLLcQqRPLhtVTRaMb6CxQRtrCMVdEqTorBXQUeE/0B0Jqa2gFJe6+GBH0TKcohPQ5DeOFi8irNhFZRDfpb/SLZdVZjCcymnSX8YaIw94/vzq9+RG0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777828257; c=relaxed/simple; bh=TVHo9dnFcw/tGdRrYrVbasoITISy+2trrO5Bo/2ExRE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=co/bztEQO42MUIW+rEnLpmGUA6QHWamvByXRVtfjW13zOeKix/K5Pftm4/qmXHXfDMW4haVzxdUJZlUZKx1hAueYiuElislegi6/YV/WPly8mqejyOfDy4ww/XKPWr+T9j8ohFSdYge6D7w+Gm+PJWnnfuw5nZ2Y5yTMVuSnNOI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=P9dKItcx; arc=none smtp.client-ip=74.125.82.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="P9dKItcx" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-2bdf75bc88fso5349148eec.0 for ; Sun, 03 May 2026 10:10:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1777828255; x=1778433055; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=N0tW0FxSBXoHGLy8UAyiIK3CDK7lkkw9WSavrtAU+9E=; b=P9dKItcxpVCMY5cMFHC0kQllnKMtIcU+8XCizQQjjJbcNKoIZRuCFU8KDlh/Vkt1Lm ZxBQh+s92fQVa3vS+8Ky1d2aaqcgAG2CLbcw8YHkh0+84FdtVQLklV7WPAmbKRX58leS W71cht323Y3W+2EiA//UTcCnSoRUX/ChSC2CBMA0rLKTC2GTdF0bGNMXCfHUA5xIFYXi do2UkOhyp6I8pNsugq4vfexkEMkKRv04wwhgW9JZ6tHWfODdXOheKa2WSLI562QJ/dEs qpWK1TETgv023IdxeOf+yVegl7Sfetps9EpbaNFWu7+R2SfehOTt4VgVb93IXkCIlQ8b JwzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777828255; x=1778433055; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=N0tW0FxSBXoHGLy8UAyiIK3CDK7lkkw9WSavrtAU+9E=; b=rszh2Ne6T1m4TyqSTm6yk22n+xzFWWzPbjy8F1MPOfEtySHGngXeHorydkj3FOrwEs 7RCZpguF2h8VZrQ6aL77soLJGTbPxi3hIVBIadT/S9WxAzE+s6Folj4bRc6C0ZPHq90i QQRugzPJe7dSJePOpDJ/UksP8ZqDSviryUmOoLQUny+H+Bmf2nYp2lhm3J0G1Ej1R4BR 2IlgIbCGE9kDygOjM8zWSViPrhcAEixHskWn+DnIQZzgQsRgPoX5rX9/j5ClOctGeikS JeJSoYsXLEqL3BsIbh9xlW1kB4lbO7sfX4rduy6aIOP4LplFJYAtTNcxO4BICjQbcEQD zdqQ== X-Forwarded-Encrypted: i=1; AFNElJ8V5mit/7nHzq7c74KMD7SLlpw1hHs3Z7TzoUBG+mODu7oDxlExdKHBnNFhIgOLTLN9+xEQtHrdxKAXLQk=@vger.kernel.org X-Gm-Message-State: AOJu0YxgbmURG2jZBGeI3GuDVfnxA7mfJf6d0giPXRUUm27WM16zb6uu kaaDi0A8DuLG73vyZ86UwjrMN8m0jnvskZDf19wCvVhXIsOY0cOUG8+Q2AtFAj/bilTSwv9840B /TM82XXcNJA== X-Received: from dlbuu10.prod.google.com ([2002:a05:7022:7e8a:b0:12c:87ba:191d]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:1a85:b0:127:380e:ff5a with SMTP id a92af1059eb24-12dfd7f994bmr3060618c88.17.1777828255093; Sun, 03 May 2026 10:10:55 -0700 (PDT) Date: Sun, 3 May 2026 10:10:32 -0700 In-Reply-To: <20260503171032.1559338-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260503003552.1063540-1-irogers@google.com> <20260503171032.1559338-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.545.g6539524ca2-goog Message-ID: <20260503171032.1559338-7-irogers@google.com> Subject: [PATCH v4 6/6] perf debuginfo: Fix libdw API contract violations From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Adrian Hunter , James Clark , Zecheng Li , Masami Hiramatsu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ian Rogers Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Check return value of `dwfl_report_end` during offline initialization. Validate `dwfl_module_relocation_info` result before passing to `strcmp` to avoid potential segmentation faults. Additionally: - Fix a file descriptor leak in `debuginfo__init_offline_dwarf()` when `dwfl_report_offline()` or subsequent setup calls fail. Fixes: 6f1b6291cf73 ("perf tools: Add util/debuginfo.[ch] files") Assisted-by: Gemini-CLI:Google Gemini 3 Signed-off-by: Ian Rogers Acked-by: Namhyung Kim --- v4: - Fix file descriptor leaks in debuginfo init paths. --- tools/perf/util/debuginfo.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/debuginfo.c b/tools/perf/util/debuginfo.c index 0e35c13abd04..84a78b30ceac 100644 --- a/tools/perf/util/debuginfo.c +++ b/tools/perf/util/debuginfo.c @@ -42,6 +42,7 @@ static int debuginfo__init_offline_dwarf(struct debuginfo= *dbg, { GElf_Addr dummy; int fd; + bool fd_consumed =3D false; =20 fd =3D open(path, O_RDONLY); if (fd < 0) @@ -55,6 +56,7 @@ static int debuginfo__init_offline_dwarf(struct debuginfo= *dbg, dbg->mod =3D dwfl_report_offline(dbg->dwfl, "", "", fd); if (!dbg->mod) goto error; + fd_consumed =3D true; =20 dbg->dbg =3D dwfl_module_getdwarf(dbg->mod, &dbg->bias); if (!dbg->dbg) @@ -62,13 +64,14 @@ static int debuginfo__init_offline_dwarf(struct debugin= fo *dbg, =20 dwfl_module_build_id(dbg->mod, &dbg->build_id, &dummy); =20 - dwfl_report_end(dbg->dwfl, NULL, NULL); + if (dwfl_report_end(dbg->dwfl, NULL, NULL) !=3D 0) + goto error; =20 return 0; error: if (dbg->dwfl) dwfl_end(dbg->dwfl); - else + if (!fd_consumed) close(fd); memset(dbg, 0, sizeof(*dbg)); =20 @@ -167,7 +170,7 @@ int debuginfo__get_text_offset(struct debuginfo *dbg, D= warf_Addr *offs, /* Search the relocation related .text section */ for (i =3D 0; i < n; i++) { p =3D dwfl_module_relocation_info(dbg->mod, i, &shndx); - if (strcmp(p, ".text") =3D=3D 0) { + if (p && strcmp(p, ".text") =3D=3D 0) { /* OK, get the section header */ scn =3D elf_getscn(elf, shndx); if (!scn) --=20 2.54.0.545.g6539524ca2-goog