新的pdb2mdb.exe

发布时间 2023-04-12 21:42:42作者: bodong

    之前做Unity3d脚本分离的时候遇到的问题,当pdb文件特别大或者其它一些未知情况时,会导致pdb无法正确转成mdb,这会导致mono脚本无法调试,报错为:

Microsoft.Cci.Pdb.PdbDebugException: Invalid signature. (sig=1919117645) in Microsoft.Cci.Pdb.PdbFile.LoadFuncsFromDbiModule(BitAccess bits, DbiModuleInfo info, IntHashTable names, ArrayList funcList, Boolean readStrings, MsfDirectory dir, Dictionary`2 nameIndex, PdbReader reader) in Microsoft.Cci.Pdb.PdbFile.LoadFunctions(Stream read, BitAccess bits, Boolean readAllStrings) in Pdb2Mdb.Driver.Convert(AssemblyDefinition assembly, Stream pdb, MonoSymbolWriter mdb)

    经过一些调试,发现本身可能是由于mono自带的和unity自带的pdb2mdb都太老了,很多新东西都不支持了。所以我自己建了个github项目,然后尝试找到pdb2mdb的源代码,接着尝试将其所有的依赖项都升级到最新,然后再将不兼容的代码都改了。这样就有了一个新的pdb2mdb,使用这个新的pdb2mdb就可以转之前不能转的pdb了。

github地址:https://github.com/bodong1987/pdb2mdb

   出于安全考虑,建议使用脚本来包装一下,先尝试使用旧的pdb2mdb转一下,如果转成功了就继续;没转成功就用我的新的pdb2mdb来转,这样应该就最安全稳当了:

def _process_mdb_new(script_directory, output_path, project_name, dll_name) :
    pdb2mdb_path = os.path.join(script_directory, "pdb2mdb.exe")            
    subprocess.call([pdb2mdb_path, output_path])
    print("[new]convert " + dll_name +".dll.pdb to " + dll_name + ".dll.mdb ...")


# other codes
 if(sys.platform == "win32") :
        # convert pdb to mdb
        script_directory = os.path.dirname(os.path.realpath(__file__))

        Enable_Traditional_Converter = True

        if(Enable_Traditional_Converter) :
            pdb2mdb_path = os.path.join(script_directory, "pdb2mdb_traditional.exe")

            output_mdb_path = output_path + ".mdb"
            if(os.path.exists(output_mdb_path)) :
                os.remove(output_mdb_path)

            try :            
                exit_code = subprocess.call([pdb2mdb_path, output_path])
                if(exit_code == 0 and os.path.exists(output_mdb_path)) :
                    print("[traditional]convert " + project_name +".dll.pdb to " + project_name + ".dll.mdb ...")
                else :
                    # print("@warning: do you see an error report? don't warry, I will convert pdb to mdb by a new pdb2mdb.exe, this exe is created by me. please ignore this error now.")
                    _process_mdb_new(script_directory, output_path, project_name, dll_name)
            except :            
                _process_mdb_new(script_directory, output_path, project_name, dll_name)
        else :
            _process_mdb_new(script_directory, output_path, project_name, dll_name)

    不过需要注意的是旧版的pdb2mdb需要魔改一下,否则会有一些问题,比如说当其抛出异常的时候,会自行消化掉,进程并不会返回非0值,所以外部的python可能无法发现它失败了。所以这种情况下,要么魔改一下pdb2mdb,或者检查一下目标mdb是否正常产生即可。