Yesterday encountered a C # DLL dynamic loading after debugging information is missing, this morning after the resolution of the record, so that the students encounter this problem can refer to.
(note) In this article, the text in the screenshot is small, you can Ctrl + mouse wheel zoom view.
Problem description
We know that the Debug.Log () series function of Unity can not only output the user content, but also through a mechanism like stacktraceutility.extractstacktrace (), the output corresponding to the stack can be typed When the user code shows an exception that is not caught, Unity also uses the mechanism to output the exception and the associated complete stack information.
such as this function:
void Printstacktraceordinary ()
{
Debug.logformat ("StackTrace (Ordinary): \n{0}",
Environment.stacktrace);
}
Will output the following results:
Note that each function on the stacktrace in this figure has complete debug information (function, source file, line number).
However, when a part of the call chain is in an external DLL, this part of the function call that is in the external DLL is not able to display the stack as normal functions.
such as the following function in a separate DLL:
Namespace Test_stacktrace_dll
{
public class Foo
{
public static string Getstacktraceindll ()
{
return environment.stacktrace;
}
}
}
Used in Unity engineering as follows
void Printstacktraceinsideuserdll ()
{
Debug.logformat ("StackTrace (inside User DLL): \n{0}",
Test_stacktrace_dll. Foo.getstacktraceindll ());
}
Will output the following results:
Note that the second line of StackTrace in this figure is Getstacktraceindll (), which is the function within the external DLL, and the tail is not displaying file and line number information.
In this case, if the project's C # code is placed in an external DLL (generally better code organization and modularity, better VS IL code generation, convenient code thermal update, etc.), debugging will be missing a lot of ancillary information.
Problem solving
We know that every VS-compiled C # DLL comes with a PDB that stores debugging-related information that can theoretically be obtained if the Unity project can be positioned to the PDB at runtime. For a regular C # program, just copy the. pdb file of a DLL to the directory of the. exe, but I tried to copy. pdb to the directory where the project Assets is located or Unity.exe, and I'm starting to speculate that it's Unity. Compatibility issue between Mono and VS-generated PDB.
Immediately thought, since the Unity project generated by their own Assembly can successfully find debugging information, then these mono generated debugging information must exist in the project project somewhere, so began to turn over the project directory, finally in the Library under the subdirectory found these two files:
It looks like the debug file generated by Unity/mono is named. mdb, which means that you can just convert the VS-generated PDB file to an MDB. Quickly find a way:
<unity Root>\unity-5.3.6f1\editor\data\mono\lib\mono\2.0\pdb2mdb.exe <target_assembly>.dll
Use this to build the MDB and put it in the Assets directory to get additional debugging information:
Dynamic load & an exception not caught
What if this DLL is dynamically loaded?
Use the following code to dynamically load this DLL and invoke the Getstacktraceindll () function above:
String Localassmlypath = "Assets/test_stacktrace_dll.bin";
byte[] src = file.readallbytes (localassmlypath);
String Localsymbolpath = "Assets/test_stacktrace_dll.bin.mdb";
byte[] symbolbytes = file.readallbytes (Localsymbolpath);
Assembly Assembly = Assembly.Load (src, symbolbytes);
Type type = assembly. GetType ("Test_stacktrace_dll.") Foo ");
MethodInfo getstacktrace = type. GetMethod ("Getstacktraceindll",
BindingFlags.Public | BindingFlags.Static);
Debug.logformat ("StackTrace (Dynamically): \n{0}",
Getstacktrace.invoke (null, NULL));
Load the corresponding MDB file together, you can get the same result.
By the way, test for an unhandled exception and manually create one in the DLL, as you can see the complete debugging information:
To say more, there are several operations are not handled errors, the actual project to check at least Assembly whether the success of the load, processing the obtained function is valid, and other errors.