예제 #1
0
        async Task <MethodInfo> LoadSymbolsOnDemand(AssemblyInfo asm, uint method_token, SessionId sessionId, CancellationToken token)
        {
            var context = GetContext(sessionId);

            if (asm.TriedToLoadSymbolsOnDemand)
            {
                return(null);
            }
            asm.TriedToLoadSymbolsOnDemand = true;
            ImageDebugHeader header = asm.Image.GetDebugHeader();

            for (var i = 0; i < header.Entries.Length; i++)
            {
                var entry = header.Entries[i];
                if (entry.Directory.Type != ImageDebugType.CodeView)
                {
                    continue;
                }

                var data = entry.Data;

                if (data.Length < 24)
                {
                    return(null);
                }

                var pdbSignature = (data[0]
                                    | (data[1] << 8)
                                    | (data[2] << 16)
                                    | (data[3] << 24));

                if (pdbSignature != 0x53445352) // "SDSR" mono/metadata/debug-mono-ppdb.c#L101
                {
                    return(null);
                }

                var buffer = new byte[16];
                Buffer.BlockCopy(data, 4, buffer, 0, 16);

                var pdbAge = (data[20]
                              | (data[21] << 8)
                              | (data[22] << 16)
                              | (data[23] << 24));

                var pdbGuid = new Guid(buffer);
                var buffer2 = new byte[(data.Length - 24) - 1];
                Buffer.BlockCopy(data, 24, buffer2, 0, (data.Length - 24) - 1);
                var pdbName = System.Text.Encoding.UTF8.GetString(buffer2, 0, buffer2.Length);
                pdbName = Path.GetFileName(pdbName);

                foreach (var urlSymbolServer in urlSymbolServerList)
                {
                    var downloadURL = $"{urlSymbolServer}/{pdbName}/{pdbGuid.ToString("N").ToUpper() + pdbAge}/{pdbName}";

                    try
                    {
                        using HttpResponseMessage response = await client.GetAsync(downloadURL);

                        using Stream streamToReadFrom = await response.Content.ReadAsStreamAsync();

                        var portablePdbReaderProvider = new PdbReaderProvider();
                        var symbolReader = portablePdbReaderProvider.GetSymbolReader(asm.Image, streamToReadFrom);
                        asm.ClearDebugInfo(); //workaround while cecil PR #686 is not merged
                        asm.Image.ReadSymbols(symbolReader);
                        asm.Populate();
                        foreach (var source in asm.Sources)
                        {
                            var scriptSource = JObject.FromObject(source.ToScriptSource(context.Id, context.AuxData));
                            SendEvent(sessionId, "Debugger.scriptParsed", scriptSource, token);
                        }
                        return(asm.GetMethodByToken(method_token));
                    }
                    catch (Exception e)
                    {
                        Log("info", $"Unable to load symbols on demand exception: {e.ToString()} url:{downloadURL} assembly: {asm.Name}");
                    }
                }
                break;
            }

            Log("info", "Unable to load symbols on demand assembly: {asm.Name}");
            return(null);
        }