Skip to content

Commit

Permalink
[debugger][mono] Run icordbg tests on android (#52127)
Browse files Browse the repository at this point in the history
Run icordbg debuggert tests on android
  • Loading branch information
thaystg authored May 5, 2021
1 parent 94e4e3f commit 8c88f5f
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 72 deletions.
61 changes: 57 additions & 4 deletions src/mono/dlls/dbgshim/dbgshim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,44 @@ typedef HRESULT (STDAPICALLTYPE *FPCoreCLRCreateCordbObject)(
HMODULE hmodTargetCLR,
IUnknown **ppCordb);

HRESULT RunAndroidCmd(char* c_android_adb_path, LPCWSTR w_command_to_execute)
{
PROCESS_INFORMATION processInfo;
STARTUPINFOW startupInfo;
DWORD dwCreationFlags = 0;

ZeroMemory(&processInfo, sizeof(processInfo));
ZeroMemory(&startupInfo, sizeof(startupInfo));

startupInfo.cb = sizeof(startupInfo);

LPWSTR w_android_run_adb_command = (LPWSTR)malloc(2048 * sizeof(WCHAR));
LPWSTR w_android_adb_path = (LPWSTR)malloc(2048 * sizeof(WCHAR));

MultiByteToWideChar(CP_UTF8, 0, c_android_adb_path, -1, w_android_adb_path, 2048);

swprintf_s(w_android_run_adb_command, 2048, W("%ws %ws"), w_android_adb_path, w_command_to_execute);
BOOL result = CreateProcessW(
NULL,
w_android_run_adb_command,
NULL,
NULL,
FALSE,
dwCreationFlags,
NULL,
NULL,
&startupInfo,
&processInfo);

if (!result) {
free(w_android_run_adb_command);
free(w_android_adb_path);
return HRESULT_FROM_WIN32(GetLastError());
}
free(w_android_adb_path);
free(w_android_run_adb_command);
return S_OK;
}
//-----------------------------------------------------------------------------
// Public API.
//
Expand All @@ -70,8 +108,18 @@ CreateProcessForLaunch(
ZeroMemory(&startupInfo, sizeof(startupInfo));

startupInfo.cb = sizeof(startupInfo);

putenv("MONO_ENV_OPTIONS='--debugger-agent=transport=dt_socket,address=127.0.0.1:pid_based,server=n,suspend=y,loglevel=10,timeout=100000'");
char* c_android_adb_path = getenv("ANDROID_ADB_PATH");

if (strlen(c_android_adb_path) > 0) {
HRESULT ret = RunAndroidCmd(c_android_adb_path, W("shell setprop debug.mono.extra \"debug=10.0.2.2:56000,loglevel=10,timeout=100000000000000\""));
if (ret != S_OK) {
*pProcessId = 0;
*pResumeHandle = NULL;
return ret;
}
}
else
putenv("MONO_ENV_OPTIONS='--debugger-agent=transport=dt_socket,address=127.0.0.1:pid_based,server=n,suspend=y,loglevel=10,timeout=100000'");

BOOL result = CreateProcessW(
NULL,
Expand All @@ -96,8 +144,13 @@ CreateProcessForLaunch(
CloseHandle(processInfo.hProcess);
}

*pProcessId = processInfo.dwProcessId;
*pResumeHandle = processInfo.hThread;
if (strlen(c_android_adb_path) > 0) {
*pProcessId = 1000; //TODO identify the correct processID of the process running on android or find another way to decide the port number
}
else {
*pProcessId = processInfo.dwProcessId;
*pResumeHandle = processInfo.hThread;
}

return S_OK;
}
Expand Down
60 changes: 29 additions & 31 deletions src/mono/dlls/mscordbi/cordb-assembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,24 @@ HRESULT CordbAssembly::GetName(ULONG32 cchName, ULONG32* pcchName, WCHAR szName[
MdbgProtBuffer* pReply = received_reply_packet->Buffer();

m_pAssemblyName = m_dbgprot_decode_string_with_len(pReply->p, &pReply->p, pReply->end, &m_nAssemblyNameLen);

char* c_mobile_symbols_path = getenv("MOBILE_SYMBOLS_PATH");
if (strlen(c_mobile_symbols_path) > 0) {

size_t size_path = strlen(m_pAssemblyName);
size_t pos_separator = 0;
for (pos_separator = size_path ; pos_separator > 0 ; pos_separator--) {
if (m_pAssemblyName[pos_separator] == DIR_SEPARATOR)
break;
}
m_nAssemblyNameLen = (int)(size_path + strlen(c_mobile_symbols_path));
char* symbols_full_path = (char*)malloc(m_nAssemblyNameLen);
sprintf_s(symbols_full_path, m_nAssemblyNameLen, "%s%s", c_mobile_symbols_path , m_pAssemblyName + pos_separator + 1);

free(m_pAssemblyName);
m_pAssemblyName = symbols_full_path;
m_nAssemblyNameLen = (int) strlen(m_pAssemblyName);
}
}

if (cchName < (ULONG32) m_nAssemblyNameLen + 1)
Expand Down Expand Up @@ -271,36 +289,7 @@ HRESULT CordbModule::GetBaseAddress(CORDB_ADDRESS* pAddress)

HRESULT CordbModule::GetName(ULONG32 cchName, ULONG32* pcchName, WCHAR szName[])
{
HRESULT hr = S_OK;
EX_TRY
{
if (!m_pAssemblyName) {
LOG((LF_CORDB, LL_INFO1000000, "CordbModule - GetName - IMPLEMENTED\n"));
MdbgProtBuffer localbuf;
m_dbgprot_buffer_init(&localbuf, 128);
m_dbgprot_buffer_add_id(&localbuf, GetDebuggerId());
int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_ASSEMBLY, MDBGPROT_CMD_ASSEMBLY_GET_LOCATION, &localbuf);
m_dbgprot_buffer_free(&localbuf);

ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId);
CHECK_ERROR_RETURN_FALSE(received_reply_packet);
MdbgProtBuffer* pReply = received_reply_packet->Buffer();

m_pAssemblyName = m_dbgprot_decode_string_with_len(pReply->p, &pReply->p, pReply->end, &m_nAssemblyNameLen);
}

if (cchName < (ULONG32)m_nAssemblyNameLen + 1)
{
*pcchName = (ULONG32)m_nAssemblyNameLen + 1;
}
else
{
MultiByteToWideChar(CP_UTF8, 0, m_pAssemblyName, -1, szName, cchName);
*pcchName = (ULONG32)m_nAssemblyNameLen + 1;
}
}
EX_CATCH_HRESULT(hr);
return hr;
return m_pAssembly->GetName(cchName, pcchName, szName);
}

HRESULT CordbModule::EnableJITDebugging(BOOL bTrackJITInfo, BOOL bAllowJitOpts)
Expand Down Expand Up @@ -392,9 +381,18 @@ HRESULT CordbModule::GetMetaDataInterface(REFIID riid, IUnknown** ppObj)
full_path = (WCHAR*)malloc(sizeof(WCHAR) * pcchName);
GetName(pcchName, &pcchName, full_path);

m_pStgdbRW->OpenForRead(full_path, NULL, 0, 0);
HRESULT ret = m_pStgdbRW->OpenForRead(full_path, NULL, 0, 0);
free(full_path);

if (ret != S_OK)
{
delete m_pRegMeta;
delete m_pStgdbRW;
m_pRegMeta = NULL;
m_pStgdbRW = NULL;
return CORDBG_E_MISSING_METADATA;
}

m_pRegMeta->InitWithStgdb((ICorDebugModule*)this, m_pStgdbRW);
}
m_pRegMeta->QueryInterface(riid, (void**)ppObj);
Expand Down
5 changes: 3 additions & 2 deletions src/mono/dlls/mscordbi/cordb-frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ HRESULT CordbFrameEnum::GetCount() {
int il_offset = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end);
int flags = m_dbgprot_decode_byte(pReply->p, &pReply->p, pReply->end);

CordbNativeFrame* frame = new CordbNativeFrame(conn, frameid, methodId, il_offset, flags, m_pThread);
CordbNativeFrame* frame = new CordbNativeFrame(conn, frameid, methodId, il_offset, flags, m_pThread, i);
frame->InternalAddRef();
m_ppFrames[i] = frame;
}
Expand Down Expand Up @@ -377,12 +377,13 @@ CordbNativeFrame::~CordbNativeFrame()
}

CordbNativeFrame::CordbNativeFrame(
Connection* conn, int frameid, int methodId, int il_offset, int flags, CordbThread* thread)
Connection* conn, int frameid, int methodId, int il_offset, int flags, CordbThread* thread, int posFrame)
: CordbBaseMono(conn)
{
m_JITILFrame = new CordbJITILFrame(conn, frameid, methodId, il_offset, flags, thread);
m_JITILFrame->InternalAddRef();
this->m_pThread = thread;
this->m_nPosFrame = posFrame;
}

HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetIP(ULONG32* pnOffset)
Expand Down
3 changes: 2 additions & 1 deletion src/mono/dlls/mscordbi/cordb-frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ class CordbNativeFrame : public CordbBaseMono, public ICorDebugNativeFrame, publ
{
CordbJITILFrame* m_JITILFrame;
CordbThread* m_pThread;
int m_nPosFrame;

public:
CordbNativeFrame(Connection* conn, int frameid, int methodId, int il_offset, int flags, CordbThread* thread);
CordbNativeFrame(Connection* conn, int frameid, int methodId, int il_offset, int flags, CordbThread* thread, int posFrame);
ULONG STDMETHODCALLTYPE AddRef(void)
{
return (BaseAddRef());
Expand Down
9 changes: 4 additions & 5 deletions src/mono/dlls/mscordbi/cordb-register.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG64* pAvailable)
return E_NOTIMPL;
}

CordbRegisterSet::CordbRegisterSet(Connection* conn, uint8_t* ctx, uint32_t ctx_len) : CordbBaseMono(conn)
CordbRegisterSet::CordbRegisterSet(Connection* conn, int64_t sp) : CordbBaseMono(conn)
{
this->m_pCtx = ctx;
this->m_ctxLen = ctx_len;
this->m_nSp = sp;
}

HRESULT CordbRegisterSet::QueryInterface(REFIID id, void** pInterface)
Expand Down Expand Up @@ -55,8 +54,8 @@ HRESULT STDMETHODCALLTYPE CordbRegisterSet::SetRegisters(ULONG64 mask, ULONG32 r

HRESULT STDMETHODCALLTYPE CordbRegisterSet::GetThreadContext(ULONG32 contextSize, BYTE context[])
{
if (m_ctxLen < contextSize)
memcpy(context+POS_RAX, m_pCtx, m_ctxLen);
if (POS_RSP + sizeof(int64_t) < contextSize)
memcpy(context+POS_RSP, &m_nSp, sizeof(int64_t));
LOG((LF_CORDB, LL_INFO100000, "CordbRegisterSet - GetThreadContext - NOT IMPLEMENTED\n"));
return S_OK;
}
Expand Down
6 changes: 2 additions & 4 deletions src/mono/dlls/mscordbi/cordb-register.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@

class CordbRegisterSet : public CordbBaseMono, public ICorDebugRegisterSet
{
uint8_t* m_pCtx;
uint32_t m_ctxLen;

int64_t m_nSp;
public:
CordbRegisterSet(Connection* conn, uint8_t* ctx, uint32_t ctx_len);
CordbRegisterSet(Connection* conn, int64_t sp);
ULONG STDMETHODCALLTYPE AddRef(void)
{
return (BaseAddRef());
Expand Down
15 changes: 10 additions & 5 deletions src/mono/dlls/mscordbi/cordb-stackwalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <cordb-stepper.h>
#include <cordb-thread.h>
#include <cordb-stackwalk.h>
#include <cordb-function.h>
#include <cordb.h>


Expand Down Expand Up @@ -67,10 +68,10 @@ HRESULT STDMETHODCALLTYPE CordbStackWalk::GetContext(ULONG32 contextFlags, ULONG
MdbgProtBuffer* pReply = received_reply_packet->Buffer();

int contextSizeReceived = 0;
uint8_t* contextMemoryReceived = m_dbgprot_decode_byte_array(pReply->p, &pReply->p, pReply->end, &contextSizeReceived);
int64_t stack_pointer = m_dbgprot_decode_long(pReply->p, &pReply->p, pReply->end);
*contextSize = contextSizeReceived;
memcpy(contextBuf+POS_RAX, contextMemoryReceived, contextSizeReceived);
free(contextMemoryReceived);
memcpy(contextBuf+POS_RSP, &stack_pointer, sizeof(int64_t));
LOG((LF_CORDB, LL_INFO100000, "CordbStackWalk - GetContext - IMPLEMENTED - %d - %lld\n", m_nCurrentFrame, stack_pointer));
}
EX_CATCH_HRESULT(hr);
return hr;
Expand All @@ -84,7 +85,11 @@ HRESULT STDMETHODCALLTYPE CordbStackWalk::SetContext(CorDebugSetContextFlag flag
MdbgProtBuffer localbuf;
m_dbgprot_buffer_init(&localbuf, 128);
m_dbgprot_buffer_add_id(&localbuf, m_pThread->GetThreadId());
m_dbgprot_buffer_add_byte_array(&localbuf, context, contextSize);
int64_t stack_pointer;
memcpy(&stack_pointer, context+POS_RSP, sizeof(int64_t));
m_dbgprot_buffer_add_long(&localbuf, stack_pointer);

LOG((LF_CORDB, LL_INFO100000, "CordbStackWalk - SetContext - IMPLEMENTED - %d - %lld\n", m_nCurrentFrame, stack_pointer));

int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_THREAD, MDBGPROT_CMD_THREAD_SET_CONTEXT, &localbuf);
m_dbgprot_buffer_free(&localbuf);
Expand Down Expand Up @@ -137,7 +142,7 @@ HRESULT CordbStackWalk::PopulateStackWalk() {
int il_offset = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end);
int flags = m_dbgprot_decode_byte(pReply->p, &pReply->p, pReply->end);

CordbNativeFrame* frame = new CordbNativeFrame(conn, frameid, methodId, il_offset, flags, m_pThread);
CordbNativeFrame* frame = new CordbNativeFrame(conn, frameid, methodId, il_offset, flags, m_pThread, i);
frame->InternalAddRef();
m_ppFrames[i] = frame;
}
Expand Down
9 changes: 5 additions & 4 deletions src/mono/dlls/mscordbi/cordb-thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,11 @@ HRESULT STDMETHODCALLTYPE CordbThread::GetActiveFrame(ICorDebugFrame** ppFrame)
int flags = m_dbgprot_decode_byte(pReply->p, &pReply->p, pReply->end);
if (m_pCurrentFrame)
m_pCurrentFrame->InternalRelease();
m_pCurrentFrame = new CordbNativeFrame(conn, frameid, methodId, il_offset, flags, this);
m_pCurrentFrame = new CordbNativeFrame(conn, frameid, methodId, il_offset, flags, this, 0);
m_pCurrentFrame->InternalAddRef();
m_pCurrentFrame->QueryInterface(IID_ICorDebugFrame, (void**)ppFrame);
}
SetRegisterSet(new CordbRegisterSet(conn, 0, 0));
SetRegisterSet(new CordbRegisterSet(conn, 0));
}
EX_CATCH_HRESULT(hr);
return hr;
Expand All @@ -280,9 +280,10 @@ HRESULT STDMETHODCALLTYPE CordbThread::GetRegisterSet(ICorDebugRegisterSet** ppR
MdbgProtBuffer* pReply = received_reply_packet->Buffer();

int contextSizeReceived = 0;
uint8_t* contextMemoryReceived = m_dbgprot_decode_byte_array(pReply->p, &pReply->p, pReply->end, &contextSizeReceived);
m_pRegisterSet = new CordbRegisterSet(conn, contextMemoryReceived, contextSizeReceived);
int64_t stack_pointer = m_dbgprot_decode_long(pReply->p, &pReply->p, pReply->end);
m_pRegisterSet = new CordbRegisterSet(conn, stack_pointer);
m_pRegisterSet->InternalAddRef();
LOG((LF_CORDB, LL_INFO100000, "CordbThread - GetRegisterSet - IMPLEMENTED - %ld\n", stack_pointer));
}
EX_CATCH_HRESULT(hr);

Expand Down
10 changes: 10 additions & 0 deletions src/mono/dlls/mscordbi/cordb.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#ifdef HOST_WIN32
#include <windows.h>
#include <ws2tcpip.h>
#define DIR_SEPARATOR '\\'
#else
#define DIR_SEPARATOR '/'
#endif

#define return_if_nok(error) \
Expand All @@ -41,6 +44,13 @@ static UTSemReadWrite* m_pSemReadWrite;
#define LOGGING
#endif

#ifdef TARGET_AMD64
#define POS_RSP 0x98
#else
#define POS_RSP 0 //TODO fix for other platforms
#endif


#define CreateProcess CreateProcessW

class Socket;
Expand Down
16 changes: 7 additions & 9 deletions src/mono/mono/mini/debugger-agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -8745,8 +8745,7 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
if (suspend_count)
wait_for_suspend();
}
int context_size = 0;
uint8_t * contextMemoryReceived = m_dbgprot_decode_byte_array(p, &p, end, &context_size);
int64_t sp_received = m_dbgprot_decode_long(p, &p, end);

mono_loader_lock();
tls = (DebuggerTlsData*)mono_g_hash_table_lookup(thread_to_tls, thread);
Expand All @@ -8756,17 +8755,14 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf)

compute_frame_info(thread, tls, TRUE); //the last parameter is TRUE to force that the frame info that will be send is synchronised with the debugged thread

MonoContext ctx;
memcpy(&ctx, contextMemoryReceived+POS_RAX, sizeof(MonoContext));
for (int i = 0; i < tls->frame_count; i++)
{
PRINT_DEBUG_MSG(1, "[dbg] Searching Context [%d] - [%p] - [%p]\n", i, MONO_CONTEXT_GET_SP(&tls->frames[i]->ctx), MONO_CONTEXT_GET_SP(&ctx));
if (MONO_CONTEXT_GET_SP(&ctx) == MONO_CONTEXT_GET_SP(&tls->frames[i]->ctx)) {
PRINT_DEBUG_MSG(1, "[dbg] Searching Context [%d] - [%lld] - [%lld]\n", i, (uint64_t) MONO_CONTEXT_GET_SP (&tls->frames [i]->ctx), sp_received);
if (sp_received == (uint64_t)MONO_CONTEXT_GET_SP (&tls->frames [i]->ctx)) {
buffer_add_int(buf, i);
break;
}
}
g_free (contextMemoryReceived);
break;
}
case MDBGPROT_CMD_THREAD_GET_CONTEXT: {
Expand All @@ -8788,7 +8784,7 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf)

if (start_frame < tls->frame_count)
{
buffer_add_byte_array (buf, (uint8_t *)&tls->frames [start_frame]->ctx, sizeof(MonoContext));
buffer_add_long(buf, (uint64_t)MONO_CONTEXT_GET_SP (&tls->frames [start_frame]->ctx));
}
break;
}
Expand Down Expand Up @@ -9654,7 +9650,9 @@ static const char* vm_cmds_str [] = {
"GET_TYPES",
"INVOKE_METHODS",
"START_BUFFERING",
"STOP_BUFFERING"
"STOP_BUFFERING",
"READ_MEMORY",
"WRITE_MEMORY"
};

static const char* thread_cmds_str[] = {
Expand Down
7 changes: 0 additions & 7 deletions src/mono/mono/mini/debugger-protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@
#define HEADER_LENGTH 11
#define REPLY_PACKET 0x80

#ifdef TARGET_AMD64
#define POS_RAX 0x78
#else
#define POS_RAX 0 //TODO fix for other platforms
#endif


/*
* Wire Protocol definitions
*/
Expand Down

0 comments on commit 8c88f5f

Please sign in to comment.