• FFI Navigtor在Windows环境下的"No Such File or Directory"Bug解决过程


    一年未更,沉淀积累。

    今日立春,万象更新!

    这两天花了大概10个小时尝试在Windows环境下使用TVM工程的FFI Navigator插件,最终成功,在此记录。

    传送门:只想看方法不想看过程的直接跳至分支B处阅读。

    背景:

    1. FFI 是多语言交互接口,在TVM工程中大量使用它来实现后端C++与前端Python之类的语言交互。

    2. FFI的使用导致Python程序调用C++函数的相关代码无法跟踪函数定义。

    3. 于是TVM大佬陈天奇自己写了一个FFI Navigator(https://github.com/tqchen/ffi-navigator)用来实现Python与C++之间的代码跟踪。

    解决过程:

    1. 我的传统开发方式是本地Windows PC准备一套代码,通过WinSCP与Linux服务器端同步,编译与debug过程都通过SSH使用命令行实现,本地代码仅用于通过VSCode检视与编写。由于FFI Navigator现在仅支持VSCode与emacs,所以选择使用VSCode版本。

    2. 在VSCode上安装了FFI Navigator的Extension,发现还需要pip安装FFI Navigator,pip安装报错Retrying after connection broken by,参考文章https://blog.csdn.net/weixin_40995629/article/details/80180609解决。解决方法:pip install -i https://pypi.mirrors.ustc.edu.cn/simple gensim。

    3. pip安装FFI Navigator之后还提示未安装,阅读Github的Readme,发现还需要Build from Source步骤 ( https://github.com/tqchen/ffi-navigator/tree/main/vscode-extension )。

    4. 尝试步骤Run npm install && npm run compile on the vscode-extension folder,报错cb() never called,未能成功。搜索到有两种解决方法,一是使用cnpm,二是删除代理(忘了是哪篇文章),使用指定代理(https://www.cnblogs.com/wenbinjiang/p/11062959.html)。

    5. 方法二不管用,使用方法一成功。成功执行cnpm install与npm run compile,但仍然提示未安装FFI Navigator。

    6. 在VSCode的Extension界面Disable,Enable,Uninstall,Install,然后重启VSCode ( 后来发现VSCode不加载某插件,可能是卡在某其他插件的下载更新步骤上,比如C/C++ Extension,国内网络状况大家都明白,这时候可以把这个卡住的插件disable来解决尴尬 ) 。

    7. VSCode下方出现了FFI Navigator的打印信息,也不报未安装FFI Navigator的错误了,感觉离成功很近了。但是每当在FFI函数接口使用Ctrl+鼠标点击跟踪定义时,会出现一段报错:

     8. 思考了半天,发现这个路径是按照Linux系统的路径在找文件,所以找不到。

    时间线在这里分叉,我当时的探索,与我现在的探索,是两个思路,记为分支A与分支B:

    分支A:

      1. 在服务器端安装使用VSCode,由于我的TVM是在Docker中的。还要研究SSH -X在Docker镜像中的转发问题,作罢。

      2. 在服务器端直接安装使用VSCode,这台服务器yum出问题,会直接卡住,提示yum lock。使用另一终端kill掉进程后可退出,但yum还是无法使用。

      3. 搜索发现yum clean all,不管用,yum makecache方法,卡住,可能需要替换yum源头,其他方法参考:https://www.cnblogs.com/wpjamer/articles/10317821.html,怕弄得更糟没敢用。

      4. 使用VSCode Remote SSH插件,查阅方法:https://code.visualstudio.com/docs/remote/ssh#_getting-started。

      1.   Install an OpenSSH compatible SSH client if one is not already present.

      2.   Install Visual Studio Code or Visual Studio Code Insiders.

      3.   Install the Remote Development extension pack

      5. 在Docker镜像里面安装OpenSSH,但同样还要解决SSH直接链接Docker镜像的问题,参考文档:https://www.cnblogs.com/jesse131/p/13543308.html。觉得麻烦没弄。

      6. 本地Remote WSL方式,WSL太难装没弄。

    分支B:

      1. 修改报错路径输出脚本langserver.py第62行的内容。

      2. 直接修改后并不会立即生效,要重启VSCode,应该是本模块仅在启动时import一次。

      3. 用Print函数并不会打印输出,仿照报错中的其他打印信息使用本地方法:self.logger.info。其实self.logger是logging,有些没有self的域直接用logging就可以打印。

      4. 打印发现langserver.py中第62行的路径确实是错误的,Windows路径中的“d:”变成了“d%3A”。网上搜到有人提到URL路径中的%的问题,受到文章:https://www.cnblogs.com/zhangcheng1/p/11174736.html与https://bbs.csdn.net/topics/200020651的启发,发现是URL特殊字符处理的问题。参考方法:https://www.runoob.com/python/att-string-replace.html。扩展阅读:http://www.360doc.com/content/11/1223/16/2150778_174499703.shtml。思路在这里又一次分叉:

        分支B1:

          直接修改langserver.py第62行m_text_document__definition(self, **kwargs)报错处之前的path内容,path = path..replace("%3A",":")。虽然不报错,但是m_text_document__definition函数返回空路径,应该有其他问题。

        分支B2:

          1. 修改langserver.py第16行uri2path()函数中的语句,将str(pathlib.Path(raw_path[1:]))修改为str(pathlib.Path(raw_path[1:])).replace("%3A",":")。发现还是会报错,报错提示FFI Navigator启动时遍历某个.cc文件时打不开。(其实我首先尝试的是分支B2,到这一步我觉得我可能弄错了,又回去尝试分支B1,B1失败后我在食堂吃中午饭的时候觉得有可能B2是对的,但是正确的路径反而暴露了文件打开的另一个问题,于是进行下一步B2.2)

          2. 文件打开报错定位至workspace.py的第79行,报错UnicodeDecodeError: 'gbk' codec can't decode byte 0x9d。查阅文章:https://blog.csdn.net/u012369535/article/details/97927853。

          3. 将workspace.py69-79行所有的open方法加上编码限定,即由open(path)改为open(path, encoding='UTF-8')。

          4. 问题基本解决,FFI Navigator成功跨语言由Python至C++跟踪函数。

          5. 由C++至Python跨语言Reference跟踪报错,修改langserver.py第63行与第87行的open函数,修改方法同步骤B2.3。

          6. 问题完全解决。

    VSCode插件调试心得: 

    1. VSCode插件本身不复杂。

    2. 可能由于PC配置差或者网络差,VSCode插件启动有问题,有时候我想用的这个插件启动不起来,这样也就没法打印调试。解决方法是将这个插件Uninstall再Install然后再关闭并打开VSCode,猜测是首先启动新加载的插件。

    3. 重启VSCode,插件python源码的修改才能生效,应该是插件仅在启动时import一次。

    总结:

    1. 基本解决思路是靠搜索引擎搜索技术博客(这也是我为啥要写这篇,当然也是为了总结解决问题的思路)+积累的技术基础知识+现有问题的分析。

    2. 很多时候改源码可能并不是最难的解决方案,Github上很多代码都需要先调试再用。

    3. 尽早采用最简单直接的解决方案。

    4. 使用Github的时候先仔细阅读ReadMe。

    5. 不用对技术细节问题过于执着,不能解决马上找替代方案。人的精力有限,Debug过程就像游戏中血槽不断减少的Player一样,一定要把高精力时刻用在最直接最可行的方案上,不要过于执着!

    Feel free to contact me on professional issue. liveinspring@hotmail.com
  • 相关阅读:
    详述Xgboost原理
    Uncaught Error: Script error for "popper.js", needed by: bootstrap
    JS 正则表达式从地址中提取省市县
    OneThink实现多图片批量上传功能
    移动端图片上传解决方案localResizeIMG先压缩后ajax无刷新上传
    PHPCMS V9添加模板自定义全局变量
    CentOS 7:如何安装防火墙?
    HTML5的fieldset标签
    PHP使用CURL详解
    asp.net+swfupload 多图片批量上传(附源码下载)
  • 原文地址:https://www.cnblogs.com/blue-box/p/14365367.html
Copyright © 2020-2023  润新知