Move callstack table params to a struct.

This commit is contained in:
Bartosz Taudul
2026-07-01 01:53:08 +02:00
parent b40ef0ff29
commit f65949cc26
3 changed files with 74 additions and 53 deletions

View File

@@ -67,6 +67,25 @@ struct LockDraw;
struct PlotDraw;
struct FlameGraphContext;
struct CallstackViewWait
{
int64_t time;
const char* reason;
const char* reasonCode;
const char* state;
const char* stateCode;
};
struct CallstackTableParams
{
uint64_t thread = 0;
CallstackViewWait wait = {};
bool entryStacks = false;
bool showThread = false;
bool hasCrashed = false;
int64_t callstack = -1;
};
class View
{
@@ -261,15 +280,6 @@ private:
uint32_t count;
};
struct CallstackViewWait
{
int64_t time;
const char* reason;
const char* reasonCode;
const char* state;
const char* stateCode;
};
struct CallstackView
{
uint32_t id;
@@ -316,8 +326,8 @@ private:
void DrawAllocList();
void DrawCompare();
void DrawCallstackWindow();
void DrawCallstackTable( uint32_t callstack, uint64_t thread = 0, const CallstackViewWait& wait = {}, bool globalEntriesButton = false, bool showThread = false );
void DrawCallstackTable( const CallstackFrameId* data, size_t size, uint64_t thread = 0, const CallstackViewWait& wait = {}, bool globalEntriesButton = false, bool showThread = false, bool hasCrashed = false, int64_t callstack = -1 );
void DrawCallstackTable( uint32_t callstack, const CallstackTableParams& params = {} );
void DrawCallstackTable( const CallstackFrameId* data, size_t size, const CallstackTableParams& params = {} );
void DrawMemoryAllocWindow();
void DrawInfo();
void DrawTextEditor();

View File

@@ -24,22 +24,33 @@ void View::DrawCallstackWindow()
ImGui::Begin( "Call stack", &show, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse );
if( !ImGui::GetCurrentWindowRead()->SkipItems )
{
DrawCallstackTable( m_callstackView.id, m_callstackView.thread, m_callstackView.wait, true, true );
DrawCallstackTable( m_callstackView.id, {
.thread = m_callstackView.thread,
.wait = m_callstackView.wait,
.entryStacks = true,
.showThread = true,
} );
}
ImGui::End();
if( !show ) m_callstackView = {};
}
void View::DrawCallstackTable( uint32_t callstack, uint64_t thread, const CallstackViewWait& wait, bool globalEntriesButton, bool showThread )
void View::DrawCallstackTable( uint32_t callstack, const CallstackTableParams& params )
{
auto& crash = m_worker.GetCrashEvent();
const bool hasCrashed = crash.thread != 0 && crash.callstack == callstack;
auto& cs = m_worker.GetCallstack( callstack );
DrawCallstackTable( cs.data(), cs.size(), thread, wait, globalEntriesButton, showThread, hasCrashed, callstack );
DrawCallstackTable( cs.data(), cs.size(), {
.thread = params.thread,
.wait = params.wait,
.entryStacks = params.entryStacks,
.showThread = params.showThread,
.hasCrashed = crash.thread != 0 && crash.callstack == callstack,
.callstack = callstack,
} );
}
void View::DrawCallstackTable( const CallstackFrameId* data, size_t size, uint64_t thread, const CallstackViewWait& wait, bool globalEntriesButton, bool showThread, bool hasCrashed, int64_t callstack )
void View::DrawCallstackTable( const CallstackFrameId* data, size_t size, const CallstackTableParams& params )
{
if( ClipboardButton() )
{
@@ -113,9 +124,9 @@ void View::DrawCallstackTable( const CallstackFrameId* data, size_t size, uint64
}
if( s_config.llm )
{
auto Attach = [this, data, size, wait, hasCrashed, thread, callstack]() {
auto Attach = [this, data, size, &params]() {
auto json = GetCallstackJson( data, size );
if( hasCrashed )
if( params.hasCrashed )
{
auto& crash = m_worker.GetCrashEvent();
json["crashed"] = true;
@@ -126,18 +137,18 @@ void View::DrawCallstackTable( const CallstackFrameId* data, size_t size, uint64
}
else
{
auto threadName = m_worker.GetThreadName( thread );
auto threadName = m_worker.GetThreadName( params.thread );
if( strcmp( threadName, "???" ) != 0 ) json["thread_name"] = threadName;
json["thread_id"] = thread;
json["thread_id"] = params.thread;
}
if( callstack >= 0 ) json["id"] = callstack;
if( wait.time != 0 )
if( params.callstack >= 0 ) json["id"] = params.callstack;
if( params.wait.time != 0 )
{
json["wait_time"] = TimeToString( wait.time );
if( wait.reasonCode ) json["wait_reason"] = wait.reasonCode;
if( wait.reason ) json["wait_reason_hint"] = wait.reason;
if( wait.stateCode ) json["wait_state"] = wait.stateCode;
if( wait.state ) json["wait_state_hint"] = wait.state;
json["wait_time"] = TimeToString( params.wait.time );
if( params.wait.reasonCode ) json["wait_reason"] = params.wait.reasonCode;
if( params.wait.reason ) json["wait_reason_hint"] = params.wait.reason;
if( params.wait.stateCode ) json["wait_state"] = params.wait.stateCode;
if( params.wait.state ) json["wait_state_hint"] = params.wait.state;
}
AddLlmAttachment( json );
@@ -154,7 +165,7 @@ void View::DrawCallstackTable( const CallstackFrameId* data, size_t size, uint64
}
if( ImGui::BeginPopup( "##callstackllm" ) )
{
if( hasCrashed && ImGui::Selectable( "How to fix this crash?" ) )
if( params.hasCrashed && ImGui::Selectable( "How to fix this crash?" ) )
{
Attach();
AddLlmQuery( "How to fix this crash?" );
@@ -192,7 +203,7 @@ void View::DrawCallstackTable( const CallstackFrameId* data, size_t size, uint64
ImGui::SetNextItemWidth( ImGui::CalcTextSize( "Symbol address xxx" ).x );
ImGui::Combo( "##frameat", &m_showCallstackFrameAddress, "Source code\0Return address\0Symbol address\0Entry point\0" );
if( hasCrashed )
if( params.hasCrashed )
{
ImGui::SameLine();
ImGui::Spacing();
@@ -209,7 +220,7 @@ void View::DrawCallstackTable( const CallstackFrameId* data, size_t size, uint64
}
}
if( wait.time != 0 )
if( params.wait.time != 0 )
{
ImGui::SameLine();
ImGui::Spacing();
@@ -218,24 +229,24 @@ void View::DrawCallstackTable( const CallstackFrameId* data, size_t size, uint64
if( ImGui::IsItemHovered() )
{
ImGui::BeginTooltip();
TextFocused( "Time:", TimeToString( wait.time ) );
if( wait.reasonCode )
TextFocused( "Time:", TimeToString( params.wait.time ) );
if( params.wait.reasonCode )
{
TextFocused( "Reason:", wait.reasonCode );
TextFocused( "Reason:", params.wait.reasonCode );
ImGui::SameLine();
TextDisabledUnformatted( wait.reason );
TextDisabledUnformatted( params.wait.reason );
}
if( wait.stateCode )
if( params.wait.stateCode )
{
TextFocused( "State:", wait.stateCode );
TextFocused( "State:", params.wait.stateCode );
ImGui::SameLine();
TextDisabledUnformatted( wait.state );
TextDisabledUnformatted( params.wait.state );
}
ImGui::EndTooltip();
}
}
if( globalEntriesButton && m_worker.AreCallstackSamplesReady() )
if( params.entryStacks && m_worker.AreCallstackSamplesReady() )
{
auto frame = m_worker.GetCallstackFrame( *data );
if( frame && frame->data[0].symAddr != 0 )
@@ -257,13 +268,13 @@ void View::DrawCallstackTable( const CallstackFrameId* data, size_t size, uint64
#ifndef __EMSCRIPTEN__
bool clicked = false;
if( s_config.llm && callstack >= 0 )
if( s_config.llm && params.callstack >= 0 )
{
bool force = false;
if( s_config.llmAnnotateCallstacks )
{
std::lock_guard lock( m_callstackDescLock );
auto it = m_callstackDesc.find( callstack );
auto it = m_callstackDesc.find( params.callstack );
if( it == m_callstackDesc.end() ) force = true;
}
ImGui::SameLine();
@@ -283,7 +294,7 @@ void View::DrawCallstackTable( const CallstackFrameId* data, size_t size, uint64
}
};
m_llm.QueueFastMessageLocking( req, [this, callstack] (nlohmann::json res) {
m_llm.QueueFastMessageLocking( req, [this, callstack = params.callstack] (nlohmann::json res) {
if( res.contains( "choices" ) )
{
auto& choices = res["choices"];
@@ -346,7 +357,7 @@ void View::DrawCallstackTable( const CallstackFrameId* data, size_t size, uint64
}
#endif
if( showThread && thread != 0 )
if( params.showThread && params.thread != 0 )
{
ImGui::SameLine();
ImGui::Spacing();
@@ -358,12 +369,12 @@ void View::DrawCallstackTable( const CallstackFrameId* data, size_t size, uint64
ImGui::Spacing();
ImGui::SameLine();
SmallColorBox( GetThreadColor( thread, 0 ) );
SmallColorBox( GetThreadColor( params.thread, 0 ) );
ImGui::SameLine();
TextFocused( "Thread:", m_worker.GetThreadName( thread ) );
TextFocused( "Thread:", m_worker.GetThreadName( params.thread ) );
ImGui::SameLine();
ImGui::TextDisabled( "(%s)", RealToString( thread ) );
if( m_worker.IsThreadFiber( thread ) )
ImGui::TextDisabled( "(%s)", RealToString( params.thread ) );
if( m_worker.IsThreadFiber( params.thread ) )
{
ImGui::SameLine();
TextColoredUnformatted( ImVec4( 0.2f, 0.6f, 0.2f, 1.f ), "Fiber" );
@@ -371,10 +382,10 @@ void View::DrawCallstackTable( const CallstackFrameId* data, size_t size, uint64
}
#ifndef __EMSCRIPTEN__
if( s_config.llm && callstack >= 0 )
if( s_config.llm && params.callstack >= 0 )
{
std::lock_guard lock( m_callstackDescLock );
auto it = m_callstackDesc.find( callstack );
auto it = m_callstackDesc.find( params.callstack );
if( it != m_callstackDesc.end() )
{
TextDisabledUnformatted( ICON_FA_HAND_POINT_RIGHT );
@@ -395,7 +406,7 @@ void View::DrawCallstackTable( const CallstackFrameId* data, size_t size, uint64
}
else if( clicked )
{
m_callstackDesc.emplace( callstack, "…" );
m_callstackDesc.emplace( params.callstack, "…" );
}
}
#endif

View File

@@ -1077,7 +1077,7 @@ void View::DrawZoneInfoWindow()
{
if( ImGui::TreeNode( "Call stack" ) )
{
DrawCallstackTable( m_worker.GetZoneExtra( ev ).callstack.Val(), tid );
DrawCallstackTable( m_worker.GetZoneExtra( ev ).callstack.Val(), { .thread = tid } );
ImGui::TreePop();
}
}
@@ -1091,7 +1091,7 @@ void View::DrawZoneInfoWindow()
TextDisabledUnformatted( ICON_FA_WAND_SPARKLES );
if( expand )
{
DrawCallstackTable( cs.data(), cs.size(), tid );
DrawCallstackTable( cs.data(), cs.size(), { .thread = tid } );
ImGui::TreePop();
}
}
@@ -1568,7 +1568,7 @@ void View::DrawGpuInfoWindow()
{
if( ImGui::TreeNode( "Call stack" ) )
{
DrawCallstackTable( ev.callstack.Val(), tid );
DrawCallstackTable( ev.callstack.Val(), { .thread = tid } );
ImGui::TreePop();
}
}