tikv / pprof-rs

A Rust CPU profiler implemented with the help of backtrace-rs
Apache License 2.0
1.3k stars 99 forks source link

fix `TempFdArrayIterator` next panic #251

Open b41sh opened 1 month ago

b41sh commented 1 month ago

fix TempFdArrayIterator panic when the length is zero.

panicked at library/core/src/[panicking.rs:221](http://panicking.rs:221/):5:
unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                              ⋮ 12 frames hidden ⋮
13: core::panicking::panic_nounwind_fmt::runtime::h4a82511582835fa3
    at /rustc/cf2df68d1f5e56803c97d91e2b1a9f1c9923c533/library/core/src/[panicking.rs:112](http://panicking.rs:112/)
14: core::panicking::panic_nounwind_fmt::hd550827d91055e4d
    at /rustc/cf2df68d1f5e56803c97d91e2b1a9f1c9923c533/library/core/src/[panicking.rs:122](http://panicking.rs:122/)
15: core::panicking::panic_nounwind::h92523daa262eea20
    at /rustc/cf2df68d1f5e56803c97d91e2b1a9f1c9923c533/library/core/src/[panicking.rs:221](http://panicking.rs:221/)
16: core::slice::raw::from_raw_parts::precondition_check::h6eadaf90e62a8ea1
    at /rustc/cf2df68d1f5e56803c97d91e2b1a9f1c9923c533/library/core/src/[ub_checks.rs:68](http://ub_checks.rs:68/)
17: core::slice::raw::from_raw_parts::hfc529f5241f0d8c5
    at /rustc/cf2df68d1f5e56803c97d91e2b1a9f1c9923c533/library/core/src/[ub_checks.rs:75](http://ub_checks.rs:75/)
18: <pprof::collector::TempFdArrayIterator<T> as core::iter::traits::iterator::Iterator>::next::he3d83b556b58d647
    at /home/b41sh/.cargo/registry/src/[rsproxy.cn](http://rsproxy.cn/)-0dccff568467c15b/pprof-0.11.1/src/[collector.rs:225](http://collector.rs:225/)
     223 │             let length = self.file_vec.len() / std::mem::size_of::<T>();
     224 │             let ts =
     225 >                 unsafe { std::slice::from_raw_parts(self.file_vec.as_ptr() as *const T, length) };
     226 │             if self.index - self.buffer.len() < ts.len() {
     227 │                 self.index += 1;
19: core::iter::traits::iterator::Iterator::fold::h3c5652dde1f22ed0
    at /rustc/cf2df68d1f5e56803c97d91e2b1a9f1c9923c533/library/core/src/iter/traits/[iterator.rs:2587](http://iterator.rs:2587/)
20: <core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold::h5aaea918f58281b0
    at /rustc/cf2df68d1f5e56803c97d91e2b1a9f1c9923c533/library/core/src/iter/adapters/[chain.rs:126](http://chain.rs:126/)
21: core::iter::traits::iterator::Iterator::for_each::h0498e792e1a08a28
    at /rustc/cf2df68d1f5e56803c97d91e2b1a9f1c9923c533/library/core/src/iter/traits/[iterator.rs:818](http://iterator.rs:818/)
22: pprof::report::ReportBuilder::build::hf874f9100609e917
    at /home/b41sh/.cargo/registry/src/[rsproxy.cn](http://rsproxy.cn/)-0dccff568467c15b/pprof-0.11.1/src/[report.rs:110](http://report.rs:110/)
     108 │             }
     109 │             Ok(profiler) => {
     110 >                 profiler.data.try_iter()?.for_each(|entry| {
     111 │                     let count = entry.count;
     112 │                     if count > 0 {
23: databend_common_base::base::profiling::Profiling::report::{{closure}}::haf1fd0aee5e45417
    at /data2/b41sh/databend/src/common/base/src/base/[profiling.rs:38](http://profiling.rs:38/)
      36 │             .map_err(|e| ErrorCode::UnknownException(e.to_string()))?;
      37 │         tokio::time::sleep(self.duration).await;
      38 >         guard
      39 │             .report()
      40 │             .build()
24: databend_common_base::base::profiling::Profiling::dump_proto::{{closure}}::h83dbfaa475b57646
    at /data2/b41sh/databend/src/common/base/src/base/[profiling.rs:58](http://profiling.rs:58/)
      56 │         let mut body: Vec<u8> = Vec::new();
      57 │
      58 >         let report = self.report().await?;
      59 │         let profile = report
      60 │             .pprof()
25: <databend_common_http::debug::pprof::debug_pprof_handler as poem::endpoint::endpoint::Endpoint>::call::{{closure}}::debug_pprof_handler::{{closure}}::h411b26091a1f0807
    at /data2/b41sh/databend/src/common/http/src/debug/[pprof.rs:50](http://pprof.rs:50/)
      48 │         }
      49 │     };
      50 >     let body = profile.dump_proto().await.map_err(InternalServerError)?;
      51 │
      52 │     debug!("finished pprof request");
26: <databend_common_http::debug::pprof::debug_pprof_handler as poem::endpoint::endpoint::Endpoint>::call::{{closure}}::hbcbb7579291621b3
    at /data2/b41sh/databend/src/common/http/src/debug/[pprof.rs:27](http://pprof.rs:27/)
      25 │ // example: /debug/pprof/profile?seconds=5&frequency=99
      26 │ // req query contains pprofrequest information
      27 > #[poem::handler]
      28 │ pub async fn debug_pprof_handler(
      29 │     req: Option<Query<PProfRequest>>,
27: <poem::endpoint::map_to_response::MapToResponse<E> as poem::endpoint::endpoint::Endpoint>::call::{{closure}}::h45a755d700b45934
    at /home/b41sh/.cargo/registry/src/[rsproxy.cn](http://rsproxy.cn/)-0dccff568467c15b/poem-3.0.0/src/endpoint/[map_to_response.rs:20](http://map_to_response.rs:20/)
      18 │
      19 │     async fn call(&self, req: Request) -> Result<Self::Output> {
      20 >         self.inner.call(req).await.map(IntoResponse::into_response)
      21 │     }
      22 │ }
28: <core::pin::Pin<P> as core::future::future::Future>::poll::h10a050eaf476cf1d
    at /rustc/cf2df68d1f5e56803c97d91e2b1a9f1c9923c533/library/core/src/future/[future.rs:123](http://future.rs:123/)
29: <dyn poem::endpoint::endpoint::DynEndpoint+Output = T as poem::endpoint::endpoint::Endpoint>::call::{{closure}}::hecd4229b6865be27
    at /home/b41sh/.cargo/registry/src/[rsproxy.cn](http://rsproxy.cn/)-0dccff568467c15b/poem-3.0.0/src/endpoint/[endpoint.rs:234](http://endpoint.rs:234/)
     232 │     #[inline]
     233 │     async fn call(&self, req: Request) -> Result<Self::Output> {
     234 >         DynEndpoint::call(self, req).await
     235 │     }
     236 │ }
30: <alloc::boxed::Box<T> as poem::endpoint::endpoint::Endpoint>::call::{{closure}}::hb714b1fbb7ab5b5a
    at /home/b41sh/.cargo/registry/src/[rsproxy.cn](http://rsproxy.cn/)-0dccff568467c15b/poem-3.0.0/src/endpoint/[endpoint.rs:190](http://endpoint.rs:190/)
     188 │
     189 │     async fn call(&self, req: Request) -> Result<Self::Output> {
     190 >         self.as_ref().call(req).await
     191 │     }
     192 │ }