也许是一个边界线问题,更多与调试有关。严格意义上编码的系统管理员
我正在努力(在Debian / Sid / x86-64上)准备下一个GCC MELT版本,它是GCC提供的复杂元插件(通过免费软件GPLv3)插件)GCC的领域特定语言翻译为C ++。
(如果您想要当前快照,请下载http://gcc-melt.org/melt-plugin-snapshot-r213101-2014july27.tar.bz2它有3.8M字节)
MELT的建造程序是神秘的,需要15分钟(在i7 3770K上)。它涉及几个运行时生成的C ++代码和生成的shell脚本以及复杂的makefile。所以这是一场噩梦。
我的一些代码中有一个错误。 dlopen
失败了。 dlopen
由一些系统 GCC编译器完成(实际上它当然是cc1plus
...)。这种情况发生在深层嵌套的脚本中(例如make
调用autogen
代shell脚本,然后生成的shell脚本调用另一个make
,调用该GCC命令;某些shell或者使变量不正确......)。
当然,系统cc1plus
在dlsym
失败时正确地给出致命错误。
我的错误(某个地方,现在还没有)在某些shell或环境或make
变量被错误传输,而不是调用/usr/bin/g++-4.8
编译器,一些中间脚本是在我的Debian上调用/usr/bin/g++
,默认g++
是g++-4.9
当然,我不想重新编译我的系统/usr/bin/g++-4.8
或/usr/bin/g++-4.9
是否可能(可能通过 oprofile 或LD_PRELOAD
可爱的技巧?)运行一系列复杂的流程(某些他们是g++
或g++-4.8
)以及停止或断点,任何cc1plus
或cc1
(在/usr/lib/gcc/x86_64-linux-gnu/4.8.3/
或在/usr/lib/gcc/x86_64-linux-gnu/4.9.1
)其dlopen
失败?
如果执行失败cc1plus
的错误进程dlopen
已停止 - 没有退出 - 我可以跟踪所有脚本和make
链启动它。 < / p>
如果你足够勇敢尝试重现我的错误(我不会问这个,这很费劲!)下载我的melt-plugin-snapshot-r213101-2014july27.tar.bz2
以及同时拥有gcc-4.8
的Debian / Sid(安装了4.8.3)和gcc-4.9
(4.9.1)及其plugin-dev(默认/usr/bin/gcc
为4.9.1版本),将我的插件快照解压缩到/tmp
并输入解压缩目录make MELTGCC=gcc-4.8 GCCMELT_CXX=g++-4.8
/tmp/melt-plugin-snapshot-r213101-2014july27/
最后我得错了
MELT BUILD SCRIPT INFO: meltfrom=melt-build-script.tpl:375/230-melt-build-script.tpl:451/377 meltmode=translateinit meltbase=warmelt-first meltstage=meltbuild-stage1 meltprevstage=meltbuild-stage0-quicklybuilt meltinit=meltbuild-stage0-quicklybuilt/warmelt-first.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-base.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-debug.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-macro.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-moremacro.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-normal.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-normatch.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-genobj.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-outobj.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-hooks.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-modes.quicklybuilt meltinclude= meltsrc=/tmp/melt-plugin-snapshot-r213101-2014july27/melt/warmelt-first.melt
MELT BUILD SCRIPT INFO: melt-build-script.tpl:375/230-melt-build-script.tpl:451/377 emit C++ code for warmelt-first of meltbuild-stage1
MELT BUILD SCRIPT INFO: melt-build-script.tpl:375/230-melt-build-script.tpl:451/377 argument file meltbuild-stage1/warmelt-first.args is
-Wno-shadow -frandom-seed=ea257ebecb10e5a2143d906632a799b0
-DGCCMELT_FROM_ARG="melt-build-script.tpl:375/230-melt-build-script.tpl:451/377"
-fplugin-arg-melt-mode=translateinit
-fplugin-arg-melt-arg=/tmp/melt-plugin-snapshot-r213101-2014july27/melt/warmelt-first.melt
-fplugin-arg-melt-output=meltbuild-stage1/warmelt-first
-fplugin-arg-melt-module-make-command='make'
-fplugin-arg-melt-module-makefile=/tmp/melt-plugin-snapshot-r213101-2014july27/melt-module.mk
-fplugin-arg-melt-module-cflags='-I /tmp/melt-plugin-snapshot-r213101-2014july27 -I /tmp/melt-plugin-snapshot-r213101-2014july27/melt/generated -I. -Imeltbuild-stage1 -Imeltbuild-stage0-quicklybuilt -I /usr/lib/gcc/x86_64-linux-gnu/4.8/plugin/melt-headers/1.1-rc1-snap-svnrev-213094 -I /usr/lib/gcc/x86_64-linux-gnu/4.8/plugin/include -I /usr/lib/gcc/x86_64-linux-gnu/4.8/plugin/include/c-family -I /tmp/melt-plugin-snapshot-r213101-2014july27/melt/generated -I /tmp/melt-plugin-snapshot-r213101-2014july27'
-fplugin-arg-melt-init=meltbuild-stage0-quicklybuilt/warmelt-first.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-base.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-debug.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-macro.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-moremacro.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-normal.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-normatch.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-genobj.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-outobj.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-hooks.quicklybuilt:meltbuild-stage0-quicklybuilt/warmelt-modes.quicklybuilt
-fplugin-arg-melt-workdir=meltbuild-workdir
-fplugin-arg-melt-tempdir=meltbuild-tempdir
-fplugin-arg-melt-source-path=meltbuild-stage1:meltbuild-stage0-quicklybuilt:.
-fplugin-arg-melt-module-path=meltbuild-stage1:meltbuild-stage0-quicklybuilt:.
-fplugin-arg-melt-bootstrapping
-fplugin-arg-melt-generate-work-link
-fplugin-arg-melt-generated-c-file-list=meltbuild-stage1/warmelt-first.cfilist
meltbuild-empty-file.c
cc1plus: error: cannot load plugin ./melt.so
./melt.so: undefined symbol: _Z28gt_ggc_mx_gimple_statement_dPv
MELT BUILD SCRIPT FAILURE: melt-build-script.tpl:375/230-melt-build-script.tpl:451/377 failed with arguments @meltbuild-stage1/warmelt-first.args
Makefile:429: recipe for target 'melt-translator' failed
make: *** [melt-translator] Error 1
rm gfmeltgcc_revision _melt-runtime.c gfmeltgcc_run_md5 gfmeltgcc_version_number _meltrunsup-inc.c
make MELTGCC=gcc-4.8 GCCMELT_CXX=g++-4.8 77.48s user 3.79s system 98% cpu 1:22.34 total
当然g++-4.9
错误地 dlopen
- 为GCC 4.8 melt.so
。错误是我的,有些东西正在开始g++
而不是g++-4.8
(应该由make
和shell变量传输)。
我没有找到我的问题的答案,但我做了一个解决方法:我修补了GCC 4.9.1源代码(文件gcc/plugin.c
函数try_init_one_plugin
)以在失败后添加一些语句{{1例如
dlopen
dl_handle = dlopen (plugin->full_name, RTLD_NOW | RTLD_GLOBAL);
if (!dl_handle)
{
char*errmsg = xstrdup(dlerror ());
fprintf(stderr,
"\n @@ GCC PLUGIN LOAD FAILURE pid %d %s: %s\n",
(int) getpid(), plugin->full_name, errmsg);
fflush(NULL);
system("pstree -a -h -l -s");
system("ps auxw");
fflush(NULL);
fprintf(stderr,
"\n @@ GCC PLUGIN LOAD FAILURE sleeping 8 seconds\n");
fflush(NULL);
sleep (8);
fprintf(stderr,
"\n @@ GCC PLUGIN LOAD FAILURE selfstopping\n");
fflush(NULL);
sleep (1);
kill (SIGSTOP, getpid());
fflush(NULL);
error ("cannot load plugin %s\n%s", plugin->full_name, errmsg);
free (errmsg);
return false;
}
,fprintf
和system
(fflush
的结果strdup
和free
}调用以上表单我的临时补丁。然后我编译了修补后的GCC 4.9.1并使用dlerror
技巧确保它被调用。
有了这个,我就能纠正我最初的错误。
修补PATH
会很困难且非常危险(在太多地方经常使用)。
我还想到了流程会计acct(2)&amp; acct(5) ......)。最后修补GCC是最容易(但有点可耻)的事情。
BTW,这样的错误就是为什么我越来越相信自由软件。如果我的编译器接受插件是封闭源代码,我将更难找到错误。
N.B。我会在几天内删除插件快照。