Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit b356f95

Browse files
author
Mike McLaughlin
committed
Added a "setsostid" command to workaround a bug in lldb on a core dump where the system ids (TIDs) are wrong.
First find the managed thread os id is: (lldb) sos Threads Lock ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception 1 1 3787 00000000006547F8 20220 Preemptive 00007FFFCC0145D0:00007FFFCC015FD0 00000000006357F8 0 Ukn 6 2 3790 0000000000678FB8 21220 Preemptive 0000000000000000:0000000000000000 00000000006357F8 0 Ukn (Finalizer) (lldb) thread list Process 0 stopped * thread #1: tid = 0x0000, 0x00007f01fe64d267 libc.so.6`__GI_raise(sig=6) + 55 at raise.c:55, name = 'corerun', stop reason = signal SIGABRT thread #2: tid = 0x0001, 0x00007f01fe7138dd libc.so.6, stop reason = signal SIGABRT thread #3: tid = 0x0002, 0x00007f01fd27dda0 libpthread.so.0`__pthread_cond_wait + 192, stop reason = signal SIGABRT thread #4: tid = 0x0003, 0x00007f01fd27e149 libpthread.so.0`__pthread_cond_timedwait + 297, stop reason = signal SIGABRT thread #5: tid = 0x0004, 0x00007f01fe70f28d libc.so.6, stop reason = signal SIGABRT thread #6: tid = 0x0005, 0x00007f01fe70f49d libc.so.6, stop reason = signal SIGABRT Then use the new command "setsostid" to set the current thread using the "OSID" from above: (lldb) setsostid 3790 6 Set sos thread os id to 0x3790 which maps to lldb thread index 6 Now ClrStack should dump that managed thread: (lldb) sos ClrStack To undo the affect of this command: (lldb) setsostid Added setclrpath command that allows the path that sos/dac/dbi are loaded from to be changes instead of using the coreclr path. This may be needed if loading a core dump and the debugger binaries are in a different directory that what the dump has for coreclr's path.
1 parent 1961ee1 commit b356f95

File tree

9 files changed

+190
-27
lines changed

9 files changed

+190
-27
lines changed

src/ToolBox/SOS/Strike/strike.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14019,4 +14019,4 @@ Help(PDEBUG_CLIENT Client, PCSTR Args)
1401914019
return S_OK;
1402014020
}
1402114021

14022-
#endif // !FEATURE_PAL
14022+
#endif // FEATURE_PAL

src/ToolBox/SOS/lldbplugin/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ if(NOT ENABLE_LLDBPLUGIN)
2828
endif()
2929

3030
# Check for LLDB library
31-
find_library(LLDB NAMES lldb-3.6 lldb-3.5 LLDB lldb PATHS "${WITH_LLDB_LIBS}" PATH_SUFFIXES llvm)
31+
find_library(LLDB NAMES LLDB lldb lldb-3.6 lldb-3.5 PATHS "${WITH_LLDB_LIBS}" PATH_SUFFIXES llvm)
3232
if(LLDB STREQUAL LLDB-NOTFOUND)
3333
if(REQUIRE_LLDBPLUGIN)
3434
message(FATAL_ERROR "Cannot find lldb-3.5 or lldb-3.6. Try installing lldb-3.6-dev (or the appropriate package for your platform)")
@@ -70,6 +70,8 @@ include_directories(${CLR_DIR}/src/coreclr/hosts/unixcoreruncommon)
7070
set(SOURCES
7171
sosplugin.cpp
7272
soscommand.cpp
73+
setclrpathcommand.cpp
74+
setsostidcommand.cpp
7375
coreruncommand.cpp
7476
debugclient.cpp
7577
${CLR_DIR}/src/coreclr/hosts/unixcorerun/corerun.cpp

src/ToolBox/SOS/lldbplugin/debugclient.cpp

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
#include <dbgtargetcontext.h>
1111
#include <string>
1212

13-
DebugClient::DebugClient(lldb::SBDebugger &debugger, lldb::SBCommandReturnObject &returnObject, char *coreclrDirectory) :
13+
ULONG g_currentThreadIndex = -1;
14+
ULONG g_currentThreadSystemId = -1;
15+
char *g_coreclrDirectory;
16+
17+
DebugClient::DebugClient(lldb::SBDebugger &debugger, lldb::SBCommandReturnObject &returnObject) :
1418
m_debugger(debugger),
15-
m_returnObject(returnObject),
16-
m_coreclrDirectory(coreclrDirectory)
19+
m_returnObject(returnObject)
1720
{
1821
returnObject.SetStatus(lldb::eReturnStatusSuccessFinishResult);
1922
}
@@ -741,6 +744,14 @@ DebugClient::GetCurrentThreadId(
741744
return E_FAIL;
742745
}
743746

747+
// This is allow the a valid current TID to be returned to
748+
// workaround a bug in lldb on core dumps.
749+
if (g_currentThreadIndex != -1)
750+
{
751+
*id = g_currentThreadIndex;
752+
return S_OK;
753+
}
754+
744755
*id = thread.GetIndexID();
745756
return S_OK;
746757
}
@@ -774,6 +785,14 @@ DebugClient::GetCurrentThreadSystemId(
774785
return E_FAIL;
775786
}
776787

788+
// This is allow the a valid current TID to be returned to
789+
// workaround a bug in lldb on core dumps.
790+
if (g_currentThreadSystemId != -1)
791+
{
792+
*sysId = g_currentThreadSystemId;
793+
return S_OK;
794+
}
795+
777796
*sysId = thread.GetThreadID();
778797
return S_OK;
779798
}
@@ -795,13 +814,22 @@ DebugClient::GetThreadIdBySystemId(
795814
goto exit;
796815
}
797816

798-
thread = process.GetThreadByID(sysId);
799-
if (!thread.IsValid())
817+
// If we have a "fake" thread OS (system) id and a fake thread index,
818+
// we need to return fake thread index.
819+
if (g_currentThreadSystemId == sysId && g_currentThreadIndex != -1)
800820
{
801-
goto exit;
821+
id = g_currentThreadIndex;
802822
}
823+
else
824+
{
825+
thread = process.GetThreadByID(sysId);
826+
if (!thread.IsValid())
827+
{
828+
goto exit;
829+
}
803830

804-
id = thread.GetIndexID();
831+
id = thread.GetIndexID();
832+
}
805833
hr = S_OK;
806834

807835
exit:
@@ -834,7 +862,17 @@ DebugClient::GetThreadContextById(
834862
goto exit;
835863
}
836864

837-
thread = process.GetThreadByID(threadID);
865+
// If we have a "fake" thread OS (system) id and a fake thread index,
866+
// use the fake thread index to get the context.
867+
if (g_currentThreadSystemId == threadID && g_currentThreadIndex != -1)
868+
{
869+
thread = process.GetThreadByIndexID(g_currentThreadIndex);
870+
}
871+
else
872+
{
873+
thread = process.GetThreadByID(threadID);
874+
}
875+
838876
if (!thread.IsValid())
839877
{
840878
goto exit;
@@ -1001,7 +1039,7 @@ DebugClient::GetFrameOffset(
10011039
PCSTR
10021040
DebugClient::GetCoreClrDirectory()
10031041
{
1004-
return m_coreclrDirectory;
1042+
return g_coreclrDirectory;
10051043
}
10061044

10071045
DWORD_PTR

src/ToolBox/SOS/lldbplugin/debugclient.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ class DebugClient : public IDebugClient
88
private:
99
lldb::SBDebugger &m_debugger;
1010
lldb::SBCommandReturnObject &m_returnObject;
11-
char *m_coreclrDirectory;
1211

1312
void OutputString(ULONG mask, PCSTR str);
1413
lldb::SBProcess GetCurrentProcess();
@@ -19,7 +18,7 @@ class DebugClient : public IDebugClient
1918
DWORD_PTR GetRegister(lldb::SBFrame frame, const char *name);
2019

2120
public:
22-
DebugClient(lldb::SBDebugger &debugger, lldb::SBCommandReturnObject &returnObject, char *coreclrDirectory);
21+
DebugClient(lldb::SBDebugger &debugger, lldb::SBCommandReturnObject &returnObject);
2322
~DebugClient();
2423

2524
//----------------------------------------------------------------------------
@@ -139,6 +138,9 @@ class DebugClient : public IDebugClient
139138
ULONG loadedImageNameBufferSize,
140139
PULONG loadedImageNameSize);
141140

141+
PCSTR GetModuleDirectory(
142+
PCSTR name);
143+
142144
//----------------------------------------------------------------------------
143145
// IDebugSystemObjects
144146
//----------------------------------------------------------------------------
@@ -187,7 +189,4 @@ class DebugClient : public IDebugClient
187189

188190
DWORD_PTR GetExpression(
189191
PCSTR exp);
190-
191-
PCSTR GetModuleDirectory(
192-
PCSTR name);
193192
};
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
//
5+
6+
#include "sosplugin.h"
7+
#include <dlfcn.h>
8+
#include <string.h>
9+
#include <string>
10+
11+
class setclrpathCommand : public lldb::SBCommandPluginInterface
12+
{
13+
public:
14+
setclrpathCommand()
15+
{
16+
}
17+
18+
virtual bool
19+
DoExecute (lldb::SBDebugger debugger,
20+
char** arguments,
21+
lldb::SBCommandReturnObject &result)
22+
{
23+
if (arguments[0] == NULL)
24+
{
25+
result.Printf("setclrpath error - no path\n");
26+
return false;
27+
}
28+
29+
if (g_coreclrDirectory != NULL)
30+
{
31+
free(g_coreclrDirectory);
32+
}
33+
34+
std::string path(arguments[0]);
35+
if (path[path.length() - 1] != '/')
36+
{
37+
path.append("/");
38+
}
39+
40+
g_coreclrDirectory = strdup(path.c_str());
41+
result.Printf("Set load path for sos/dac/dbi to %s\n", g_coreclrDirectory);
42+
return result.Succeeded();
43+
}
44+
};
45+
46+
bool
47+
setclrpathCommandInitialize(lldb::SBDebugger debugger)
48+
{
49+
lldb::SBCommandInterpreter interpreter = debugger.GetCommandInterpreter();
50+
lldb::SBCommand command = interpreter.AddCommand("setclrpath", new setclrpathCommand(), "Set the path to load coreclr sos/dac/dbi files. setclrpath <path>");
51+
return true;
52+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
//
5+
6+
#include "sosplugin.h"
7+
#include <dlfcn.h>
8+
#include <string.h>
9+
#include <string>
10+
11+
class setsostidCommand : public lldb::SBCommandPluginInterface
12+
{
13+
public:
14+
setsostidCommand()
15+
{
16+
}
17+
18+
virtual bool
19+
DoExecute(lldb::SBDebugger debugger,
20+
char** arguments,
21+
lldb::SBCommandReturnObject &result)
22+
{
23+
if (arguments[0] == NULL)
24+
{
25+
result.Printf("Clearing sos thread os id/index\n");
26+
g_currentThreadIndex = -1;
27+
g_currentThreadSystemId = -1;
28+
}
29+
else if (arguments[1] == NULL)
30+
{
31+
result.Printf("Need thread index parameter that maps to the os id\n");
32+
}
33+
else
34+
{
35+
ULONG tid = strtoul(arguments[0], NULL, 16);
36+
g_currentThreadSystemId = tid;
37+
38+
ULONG index = strtoul(arguments[1], NULL, 16);
39+
g_currentThreadIndex = index;
40+
41+
result.Printf("Set sos thread os id to 0x%x which maps to lldb thread index %d\n", tid, index);
42+
}
43+
return result.Succeeded();
44+
}
45+
};
46+
47+
bool
48+
setsostidCommandInitialize(lldb::SBDebugger debugger)
49+
{
50+
lldb::SBCommandInterpreter interpreter = debugger.GetCommandInterpreter();
51+
lldb::SBCommand command = interpreter.AddCommand("setsostid", new setsostidCommand(), "Set the current os tid/thread index instead of using the one lldb provides. setsostid <tid> <index>");
52+
return true;
53+
}

src/ToolBox/SOS/lldbplugin/soscommand.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
class sosCommand : public lldb::SBCommandPluginInterface
1212
{
1313
void *m_sosHandle;
14-
char m_coreclrDirectory[MAX_PATH];
1514

1615
public:
1716
sosCommand()
@@ -24,7 +23,7 @@ class sosCommand : public lldb::SBCommandPluginInterface
2423
char** arguments,
2524
lldb::SBCommandReturnObject &result)
2625
{
27-
DebugClient* client = new DebugClient(debugger, result, m_coreclrDirectory);
26+
DebugClient* client = new DebugClient(debugger, result);
2827
if (arguments)
2928
{
3029
LoadSos(client);
@@ -65,16 +64,24 @@ class sosCommand : public lldb::SBCommandPluginInterface
6564
{
6665
if (m_sosHandle == NULL)
6766
{
68-
const char *coreclrModule = MAKEDLLNAME_A("coreclr");
69-
const char *directory = client->GetModuleDirectory(coreclrModule);
70-
if (directory == NULL)
67+
if (g_coreclrDirectory == NULL)
7168
{
72-
client->Output(DEBUG_OUTPUT_WARNING, "The %s module is not loaded yet in the target process\n", coreclrModule);
69+
const char *coreclrModule = MAKEDLLNAME_A("coreclr");
70+
const char *directory = client->GetModuleDirectory(coreclrModule);
71+
if (directory != NULL)
72+
{
73+
std::string path(directory);
74+
path.append("/");
75+
g_coreclrDirectory = strdup(path.c_str());
76+
}
77+
else
78+
{
79+
client->Output(DEBUG_OUTPUT_WARNING, "The %s module is not loaded yet in the target process\n", coreclrModule);
80+
}
7381
}
74-
else
82+
83+
if (g_coreclrDirectory != NULL)
7584
{
76-
strcpy(m_coreclrDirectory, directory);
77-
strcat(m_coreclrDirectory, "/");
7885

7986
// Load the DAC module first explicitly because SOS and DBI
8087
// have implicit references to the DAC's PAL.
@@ -88,7 +95,7 @@ class sosCommand : public lldb::SBCommandPluginInterface
8895
void *
8996
LoadModule(DebugClient *client, const char *moduleName)
9097
{
91-
std::string modulePath(m_coreclrDirectory);
98+
std::string modulePath(g_coreclrDirectory);
9299
modulePath.append(moduleName);
93100

94101
void *moduleHandle = dlopen(modulePath.c_str(), RTLD_NOW);

src/ToolBox/SOS/lldbplugin/sosplugin.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,7 @@ lldb::PluginInitialize (lldb::SBDebugger debugger)
1414
{
1515
corerunCommandInitialize(debugger);
1616
sosCommandInitialize(debugger);
17+
setclrpathCommandInitialize(debugger);
18+
setsostidCommandInitialize(debugger);
1719
return true;
1820
}

src/ToolBox/SOS/lldbplugin/sosplugin.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,18 @@
1111

1212
typedef HRESULT (*CommandFunc)(PDEBUG_CLIENT client, const char *args);
1313

14+
extern char *g_coreclrDirectory;
15+
extern ULONG g_currentThreadIndex;
16+
extern ULONG g_currentThreadSystemId;
17+
1418
bool
1519
sosCommandInitialize(lldb::SBDebugger debugger);
1620

1721
bool
18-
corerunCommandInitialize(lldb::SBDebugger debugger);
22+
setsostidCommandInitialize(lldb::SBDebugger debugger);
23+
24+
bool
25+
setclrpathCommandInitialize(lldb::SBDebugger debugger);
26+
27+
bool
28+
corerunCommandInitialize(lldb::SBDebugger debugger);

0 commit comments

Comments
 (0)