| --- |
| title: BE Thread Stack Trace |
| language: en |
| description: Collect live thread stack traces from an Apache Doris BE process through the BE HTTP API. |
| keywords: |
| - Apache Doris |
| - BE stack trace |
| - thread stack |
| - troubleshooting |
| - debug |
| --- |
| |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| --> |
| |
| # BE Thread Stack Trace |
| |
| <!-- Knowledge type: Tool usage --> |
| <!-- Applicable scenarios: Troubleshooting --> |
| |
| ## Purpose |
| |
| The BE thread stack trace API collects live thread stacks from a running Apache Doris BE process through HTTP. Use it when a BE is slow, blocked, or consuming unexpected CPU. The response is plain text and only reflects the target BE. |
| |
| This API is supported on Linux BE processes. |
| |
| ## Quick Start |
| |
| 1. Find the target BE HTTP endpoint: |
| |
| ```sql |
| SHOW BACKENDS; |
| ``` |
| |
| Use the `Host` and `HttpPort` fields of the target BE. |
| |
| 2. Collect stacks from all BE threads: |
| |
| ```bash |
| curl -s "http://{be_host}:{be_webport}/api/stack_trace" -o be_stack_trace.txt |
| ``` |
| |
| 3. Collect stacks from specific thread IDs: |
| |
| Thread IDs can be obtained from a previous full-stack response or from OS tools such as `top -H -p <be_pid>`. |
| |
| ```bash |
| curl -s "http://{be_host}:{be_webport}/api/stack_trace?thread_id=12345,12346&mode=FAST&timeout_ms=3000" -o be_stack_trace_tid.txt |
| ``` |
| |
| 4. Use conservative mode when you want to avoid signaling threads that are blocked in interrupt-sensitive syscalls: |
| |
| ```bash |
| curl -s "http://{be_host}:{be_webport}/api/stack_trace?skip_blocking_syscalls=true" -o be_stack_trace_safe.txt |
| ``` |
| |
| ## Parameters |
| |
| All parameters are optional query parameters of `GET /api/stack_trace`. |
| |
| | Parameter | Default | Description | |
| |-----------|---------|-------------| |
| | `thread_id` | None | Comma-separated Linux thread IDs. If omitted, all BE threads are sampled. | |
| | `tid` | None | Legacy alias of `thread_id`. Do not use it together with `thread_id`. | |
| | `mode` | `FAST` | Alias of `dwarf_location_info_mode`. Values: `DISABLED`, `FAST`, `FULL`, `FULL_WITH_INLINE`. | |
| | `dwarf_location_info_mode` | `FAST` | Controls DWARF symbolization detail. If both `mode` and this parameter are set, this parameter is used. | |
| | `timeout_ms` | `100` | Timeout in milliseconds for each thread. Valid range: `1` to `10000`. | |
| | `skip_blocking_syscalls` | `false` | Whether to skip threads blocked in syscalls such as `read`, `poll`, `select`, `epoll_wait`, `futex`, and `nanosleep`. Values: `true`, `false`, `1`, `0`. | |
| |
| Recommended symbolization modes: |
| |
| | Mode | Usage | |
| |------|-------| |
| | `DISABLED` | Fastest mode. Use it when you only need thread names, statuses, and raw frames. | |
| | `FAST` | Default mode. Suitable for most troubleshooting. | |
| | `FULL` | More complete file and line information. Use only when `FAST` is not enough. | |
| | `FULL_WITH_INLINE` | Includes inline frame information. This is the most expensive mode. | |
| |
| ## Output |
| |
| The response starts with collection metadata, followed by one section per thread and a final summary line. |
| |
| Example: |
| |
| ```text |
| BE thread stack traces |
| pid: 96543 |
| service_signal: 40 |
| thread_count: 1168 |
| timeout_ms_per_thread: 100 |
| dwarf_location_info_mode: fast |
| skip_blocking_syscalls: false |
| signal_handler_unwinder: frame_pointer_with_coordinator_signal_context_libunwind_fallback |
| |
| ----- thread ... (p_normal_simple) status=ok capture_method=frame_pointer frames=29 fp_status=end_of_chain ... ----- |
| 0# doris::md5_hex_batch(...) |
| 1# doris::FunctionStringDigestMulti<doris::MD5Sum>::vector_execute_single_md5(...) |
| ... |
| 20# doris::AggSinkLocalState::_execute_without_key(doris::Block*) |
| 21# doris::AggSinkLocalState::Executor<true, false>::execute(...) |
| 22# doris::AggSinkOperatorX::sink_impl(...) |
| 23# doris::DataSinkOperatorXBase::sink(...) |
| 24# doris::PipelineTask::execute(bool*) |
| 25# doris::TaskScheduler::_do_work(int) |
| |
| summary: captured=1160 skipped=4 timed_out=0 remote_signal_attempts=1164 |
| ``` |
| |
| Common thread statuses: |
| |
| | Status | Meaning | |
| |--------|---------| |
| | `ok` | Stack was captured successfully. | |
| | `ok_current_thread` | Stack was captured from the HTTP handler thread itself. | |
| | `skipped_blocking_syscall` | The thread was skipped because `skip_blocking_syscalls=true` and the thread was in an interrupt-sensitive syscall. | |
| | `signal_blocked` | The target thread blocks the diagnostic signal. | |
| | `thread_exited` | The specified thread exited before it was sampled. | |
| | `signal_error` | Sending the diagnostic signal failed. | |
| | `timeout` | Stack capture did not finish within `timeout_ms`. | |
| |
| ## Notes |
| |
| - The default full-process request samples all BE threads and does not skip blocking syscalls. This preserves blocked worker stacks, which are often useful during incidents. |
| - This is not a stop-the-world snapshot. Threads are sampled one by one, so their stacks are close in time but not from exactly the same instant. |
| - Only one stack trace request can run in a BE process at a time. Concurrent requests return HTTP `409`. |
| - Invalid parameters return HTTP `400`. Non-Linux BE processes return HTTP `501`. |
| - Prefer `thread_id` filtering and `mode=FAST` for routine diagnosis. Use `FULL` or `FULL_WITH_INLINE` only when more detailed symbolization is needed. |