Howdy.
I'm working on an OpenGL capture / playback tool that we're planning on
open sourcing at some point in the near future. It's incredibly useful to
display callstacks for the various GL entry points to help track down what
part of the engine is drawing that fancy sword, etc.
I did quite a bit of investigative work and found libunwind to be the best
at unwinding stacks _by far_. We only capture addresses during the running
of the games and we do the symbol resolving during shutdown or even in a
post step after the app has exited.
The below is the function that we're currently using to walk our stacks.
It's working very well on our i386 and x86_64 Linux platforms.
The problem I'm just starting to investigate right now is performance on
i386 - it's brutally slow. I've stepped through the various routines below
and I believe there is quite a bit of extra work going on that we don't
need since the only thing we care about are the instruction pointers.
Before I start going deeper and ripping code out and breaking things, I
thought I should ask folks familiar with the code for suggestions. If this
seems useful to anyone else I'd be more than happy to work at sending in an
official patch as well, of course.
Thanks much.
-Mike
( If it matters, we're building with these options: CFLAGS="-g -fPIC"
./configure --enable-debug-frame --enable-shared=no --enable-static=yes )
int btrace_get(uintptr_t *pcs, size_t count_pcs, uint32_t pcs_to_skip)
{
size_t count = 0;
unw_cursor_t cursor;
unw_context_t context;
unw_getcontext(&context);
unw_init_local(&cursor, &context);
while (count < count_pcs)
{
unw_word_t pc;
if (unw_step(&cursor) <= 0)
break;
unw_get_reg(&cursor, UNW_REG_IP, &pc);
if (pcs_to_skip)
{
pcs_to_skip--;
continue;
}
pcs[count++] = (uintptr_t)pc;
}
return (int)count;
}
This is an example of our data set:
"pcs" : [
"0xF4CAB533", "0xF0772E35", "0xF0752785", "0xF075EFCB", "0xE91B9D81",
"0xE91A4553", "0xEAF5DF73", "0xEAF5EA81", "0xEAF5EC28", "0xEAF5EC92",
"0xEAF71711", "0xEAF72B0A",
"0xEAF6B86D", "0xE7AB5A6D", "0xE7A91B06", "0xE7A87ABA", "0xE7AB4ED1",
"0xEAF6BDB8", "0xEAF16A66", "0xEAF15875", "0xE94E5714", "0xE94E5DBA",
"0xE941D77D", "0xE927168C",
"0xE92719BA", "0xE928098D", "0xD60A9D35", "0xD60D1A83", "0xD60CD01E",
"0xD60A9CB6", "0xD60F1ABE", "0xD5F39641", "0xD5F3CF44", "0xD5F3DA10",
"0xD5F3D5B0", "0xD5DF1622",
"0xD5F17F87", "0xD5C5EB09", "0xD5C5F536", "0xEB7A55C0", "0xEB8A40A0",
"0xEB998C9C", "0xEB99DC98", "0xEB99A8C8", "0xEBA0B640", "0xEB99C14F",
"0xF0EACB80", "0xF0EACB80",
"0xF0E9427D", "0x80484E4", "0xF48C9905", "0x804860D" ],
"syms" : [
"gli_glBindTexture(unsigned int, unsigned int) (libglitrace32.so+0x153) at
/home/mikesart/dev/voglproj/vogl/src/gliinc/gl_glx_func_defs.inc:11016",
"GLMContext::BindTexToTMU(CGLMTex*, int) (libtogl.so+0x145) at
./src/togl/../togl/linuxwin/glmgr.cpp:2936",
"CGLMTex::Unlock(GLMTexLockParams*) (libtogl.so+0x145) at
./src/togl/../togl/linuxwin/cglmtex.cpp:1708",
"IDirect3DSurface9::UnlockRect(void) (libtogl.so+0x3b) at
./src/togl/../togl/linuxwin/dxabstract.cpp:1032",
"BlitTextureBits (shaderapidx9.so+0x221) at
./src/materialsystem/shaderapidx9/texturedx8.cpp:1010",
"CShaderAPIDx8::TexImage2D(int, int, ImageFormat, int, int, int,
CShaderAPIDx8::TexImage2D, bool, void*) (shaderapidx9.so+0x93) at
./src/materialsystem/shaderapidx9/shaderapidx8.cpp:9452",
"CTexture::WriteDataToShaderAPITexture(int, int, int, int, IVTFTexture*,
ImageFormat) (materialsystem.so+0x133) at
./src/materialsystem/ctexture.cpp:3651",
"CTexture::ReconstructTexture(void) (materialsystem.so+0x261) at
./src/materialsystem/ctexture.cpp:3900",
"CTexture::DownloadTexture(Rect_t*) (materialsystem.so+0x78) at
./src/materialsystem/ctexture.cpp:2130",
"CTexture::Download(Rect_t*, int) (materialsystem.so+0x62) at
./src/materialsystem/ctexture.cpp:2154",
"CTextureManager::LoadTexture(char const*, char const, int)
(materialsystem.so+0x61) at ./src/materialsystem/texturemanager.cpp:1152",
"CTextureManager::FindOrLoadTexture(char const*, char const, int)
(materialsystem.so+0x5a) at ./src/materialsystem/texturemanager.cpp:1376",
"CShaderSystem::LoadTexture(IMaterialVar*, char const*, int)
(materialsystem.so+0xcd) at ./src/materialsystem/shadersystem.cpp:1800",
"CBaseShader::LoadTexture(int, int) (stdshader_dx9.so+0x4d) at
./src/materialsystem/shaderlib/baseshader.cpp:487",
"InitVertexLitGeneric_DX9(CBaseVSShader*, IMaterialVar**, bool,
VertexLitGeneric_DX9_Vars_t&) (stdshader_dx9.so+0x96) at
./src/materialsystem/stdshaders/vertexlitgeneric_dx9_helper.cpp:312",
"UnlitGeneric::CShader::OnInitShaderInstance(IMaterialVar**, IShaderInit*,
char const*) (stdshader_dx9.so+0x24a) at
./src/materialsystem/stdshaders/unlitgeneric_dx9.cpp:162",
"CBaseShader::InitShaderInstance(IMaterialVar**, IShaderInit*, char const*,
char const) (stdshader_dx9.so+0x41) at
./src/materialsystem/shaderlib/baseshader.cpp:142",
"CShaderSystem::InitShaderInstance(IShader*, IMaterialVar**, char const*,
char const) (materialsystem.so+0x68) at
./src/materialsystem/shadersystem.cpp:973",
"CMaterial::Precache(void) (materialsystem.so+0xb6) at
./src/materialsystem/cmaterial.cpp:2283", "CMaterial::GetMappingWidth(void)
(materialsystem.so+0x15) at ./src/materialsystem/cmaterial.cpp:2429",
"CMatSystemTexture::SetMaterial(IMaterial*) (vguimatsurface.so+0x34) at
./src/vgui2/vgui_surfacelib/texturedictionary.cpp:586",
"CTextureDictionary::BindTextureToFile(int, char const*)
(vguimatsurface.so+0x7a) at
./src/vgui2/vgui_surfacelib/texturedictionary.cpp:826",
"CMatSystemSurface::DrawSetTextureFile(int, char const*, int, bool)
(vguimatsurface.so+0x2d) at ./src/vguimatsurface/matsystemsurface.cpp:1632",
"vgui::Bitmap::ForceUpload(void) (vgui2.so+0x9c) at
./src/vgui2/src/bitmap.cpp:209", "Bitmap (vgui2.so+0xba) at
./src/vgui2/src/bitmap.cpp:55",
"CSchemeManager::GetImage(char const*, bool) (vgui2.so+0xcd) at
./src/vgui2/src/scheme.cpp:1314",
"vgui::ImagePanel::ApplySchemeSettings(vgui::IScheme*) (client.so+0x65) at
./src/vgui2/vgui_controls/imagepanel.cpp:318",
"vgui::Panel::PerformApplySchemeSettings(void) (client.so+0x113) at
./src/vgui2/vgui_controls/panel.cpp:4290",
"vgui::Panel::InvalidateLayout(bool, bool) (client.so+0x7e) at
./src/vgui2/vgui_controls/panel.cpp:4035",
"vgui::ImagePanel::SetImage(char const*) (client.so+0x96) at
./src/vgui2/vgui_controls/imagepanel.cpp:94",
"vgui::ScrollBar::UseImages(char const*, char const, char const, char
const) (client.so+0x11e) at ./src/vgui2/vgui_controls/scrollbar.cpp:679",
"CTerrorRichText (client.so+0xc1) at
./src/game/client/terror/vgui/terrorcontrols.cpp:350", "CTerrorTextWindow
(client.so+0xa4) at ./src/game/client/terror/vgui/terrortextwindow.cpp:24",
"TerrorViewport::CreatePanelByName(char const*) (client.so+0x150) at
./src/game/client/terror/vgui/terrorviewport.cpp:238",
"FullscreenTerrorViewport::CreateDefaultPanels(void) (client.so+0x120) at
./src/game/client/terror/vgui/terrorviewport.cpp:372",
"CBaseViewport::Start(IGameUIFuncs*, IGameEventManager2*) (client.so+0x142)
at ./src/game/client/game_controls/baseviewport.cpp:583",
"FullscreenTerrorClientMode::InitViewport(void) (client.so+0xd7) at
./src/game/client/terror/terrorclientmode.cpp:3505",
"InitGameSystems(void*(*)(char const*int*)) (client.so+0x199) at
./src/game/client/cdll_client_int.cpp:1328",
"CHLClient::Init(void*(*)(char const*int*), CGlobalVarsBase*)
(client.so+0x6a6) at ./src/game/client/cdll_client_int.cpp:1617",
"ClientDLL_Init(void) (engine.so+0x50) at
./src/engine/./cdll_engine_int.cpp:2356", "Host_Init(bool)
(engine.so+0x570) at ./src/engine/./host.cpp:4513",
"Sys_InitGame(void*(*)(char const*int*), char const*, void*, int)
(engine.so+0x16c) at ./src/engine/./sys_dll.cpp:1116",
"CEngine::Load(bool, char const*) (engine.so+0x48) at
./src/engine/./sys_engine.cpp:164", "CModAppSystemGroup::Main(void)
(engine.so+0x78) at ./src/engine/./sys_dll2.cpp:2180",
"CAppSystemGroup::Run(void) (engine.so+0x30) at
./src/appframework/appsystemgroup.cpp:383",
"CEngineAPI::RunListenServer(void) (engine.so+0x7f) at
./src/engine/./sys_dll2.cpp:1237",
"CAppSystemGroup::Run(void) (launcher.so+0x30) at
./src/appframework/appsystemgroup.cpp:383", "CAppSystemGroup::Run(void)
(launcher.so+0x30) at ./src/appframework/appsystemgroup.cpp:383",
"LauncherMain (launcher.so+0x38d) at ./src/launcher/launcher.cpp:1665",
"main (hl2_linux+0x44) at ./src/launcher_main/main.cpp:153",
"__libc_start_main (libc.so.6+0xf5)", "(hl2_linux+0x60d)" ]
_______________________________________________
Libunwind-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/libunwind-devel