简体   繁体   中英

Cannot get line number of Instruction using Mono.Cecil 0.10.2

I am trying to get the line number associated with the Instruction object in the method below. SequencePoint.StartLine is supposed to give me the information I need, but in the commented out section of the method seqPoint is always null.

    /// <summary>
    /// Finds all places in code where one or more methods are called.
    /// </summary>
    /// <param name="classOfMethods">Full name of the class that contains the methods to find.</param>
    /// <param name="methodNames">Names of the methods to find in code.</param>
    public MethodCall[] FindAllMethodCalls(Type classOfMethods, params string[] methodNames)
    {
        #region Use Mono.Cecil to find all instances where methods are called
        var methodCalls = new List<MethodCall>();
        var ad = AssemblyDefinition.ReadAssembly(binaryFileToSearch, new ReaderParameters { ReadSymbols = true });
        foreach (var module in ad.Modules)
        {
            foreach (var type in module.GetTypes())
            {
                foreach (var method in type.Methods.Where(x => x.HasBody))
                {
                    var instrs = method.Body.Instructions.Where(x => x.OpCode == OpCodes.Call).ToArray();
                    foreach (var instr in instrs)
                    {
                        var mRef = instr.Operand as MethodReference;
                        if (mRef != null && mRef.DeclaringType.FullName == classOfMethods.FullName && methodNames.Contains(mRef.Name))
                        {
                            // this does not work -- always returns null
                            //var seqPoint = method.DebugInformation.GetSequencePoint(instr);
                            //if (seqPoint != null)
                            //{
                            //}

                            methodCalls.Add(new MethodCall
                            {
                                CodeFile = method.DebugInformation.SequencePoints.First().Document.Url,
                                MethodRef = mRef,
                            });
                        }
                    }
                }
            }
        }
        ...
        return methodCalls.ToArray();
    }

The binary files I am calling AssemblyDefinition.ReadAssembly() on have corresponding .pdb files, and I am using the ReadSymbols = true option. What am I doing wrong?

Your code is OK.

Cecil read PDB file when he should. In the read process, he is populating all PDB functions: ( this is not the complete real code but for demonstration, although the real code is similar )

private bool PopulateFunctions()
{
    PdbFunction[] array = PdbFile.LoadFunctions(.....);

    foreach (PdbFunction pdbFunction in array)
    {
        this.functions.Add(pdbFunction.token, pdbFunction);
    }
}

Then when he reading MethodBody, he populate the sequence points:

private void ReadSequencePoints(PdbFunction function, MethodDebugInformation info)
{
    foreach (PdbLines lines in function.lines)
    {
        this.ReadLines(lines, info);
    }
}

And,

private static void ReadLine(PdbLine line, Document document, MethodDebugInformation info)
    {
        SequencePoint sequencePoint = new SequencePoint(ine.offset, document);
        sequencePoint.StartLine = line.lineBegin;
        sequencePoint.StartColumn = line.colBegin;
        sequencePoint.EndLine = line.lineEnd;
        sequencePoint.EndColumn = line.colEnd;
        info.sequence_points.Add(sequencePoint);
    }

If you can't find a specific sequence point, it means that it does not exist in the sequence points collection of the method debug information.

Anyway, I'm in doubt that you are getting always null.

Please write this:

 method.DebugInformation.GetSequencePointMapping()

And compare it with your instrs collection.

method.DebugInformation.GetSequencePointMapping() is the sequence points that Cecil know about them, and for each of them you can see the instruction that it maps to it, so you can check which call instruction in your method has a sequence point.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM