这几天我们一直在处理非常奇怪的问题。
我什至无法理解它是如何发生的——当第三方 (MATLAB) 程序使用我们的共享库时,它会以某种方式用它自己的符号覆盖我们的一些符号(准确地说是增强)。这些符号是静态链接的并且 (!!) 是本地的。
这是交易 - 我们使用 boost 1.47,MATLAB 有 boost 1.40。目前,库在从我们的库调用它们的 boost(正则表达式)时会出现段错误。
所以,这是神奇的:
linux-vdso.so.1 => (0x00007fff4abff000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007f1a3fd65000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f1a3fa51000)
libm.so.6 => /lib/libm.so.6 (0x00007f1a3f7cd000)
libgomp.so.1 => /usr/lib/libgomp.so.1 (0x00007f1a3f5bf000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f1a3f3a8000)
libc.so.6 => /lib/libc.so.6 (0x00007f1a3f024000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1a414f9000)
librt.so.1 => /lib/librt.so.1 (0x00007f1a3ee1c000)
nm -g --defined-only libmysharedlib.so addr1 T OurCSymbol1 addr2 T OurCSymbol2 addr3 T OurCSymbol3 ...
[ 0] 0x00007f21fddbb0a9 bin/libmwfl.so+00454825 fl::sysdep::linux::unwind_stack(void const**, unsigned long, unsigned long, fl::diag::thread_context const&)+000009 [ 1] 0x00007f21fdd74111 bin/glnxa64/libmwfl.so+00164113 fl::diag::stacktrace_base::capture(fl::diag::thread_context const&, unsigned long)+000161 [ 2] 0x00007f21fdd7d42d bin/glnxa64/libmwfl.so+00201773 [ 3] 0x00007f21fdd7d6b4 bin/glnxa64/libmwfl.so+00202420 fl::diag::terminate_log(char const*, fl::diag::thread_context const&, bool)+000100 [ 4] 0x00007f21fce525a7 bin/glnxa64/libmwmcr.so+00365991 [ 5] 0x00007f21fb9eb8f0 lib/libpthread.so.0+00063728 [ 6] 0x00007f21f3e939a9 libboost_regex.so.1.40.0+00342441 boost::re_detail::perl_matcher, std::allocator > >, boost::regex_traits > >::match_all_states()+000073 [ 7] 0x00007f21f3eb6546 bin/glnxa64/libboost_regex.so.1.40.0+00484678 boost::re_detail::perl_matcher, std::allocator > >, boost::regex_traits > >::match_imp()+000758 [ 8] 0x00007f21c04ad595 lib/libmysharedlib.so+04855189 bool boost::regex_match, std::allocator > >, char, boost::regex_traits > >(__gnu_cxx::__normal_iterator, __gnu_cxx::__normal_iterator, boost::match_results, std::allocator > > >&, boost::basic_regex > > const&, boost::regex_constants::_match_flags)+000245 [ 9] 0x00007f21c04a71c7 lib/libmysharedlib.so+04829639 myfunc2()+000183 [ 10] 0x00007f21c01b41e3 lib/libmysharedlib.so+01737187 myfunc1()+000307
众所周知,MATLAB 仅使用 RTLD_NOW 标志执行 dlopen。
人们,请和我一起思考。 现在我什至不想解决这个问题,只是想简单地了解 ld&elf 的行为。
编辑: 小的附加问题:我怎么理解,没有特殊的链接器选项,linux 中的符号.so 库永远不会通过地址链接?所以即使是静态链接的局部符号也会在运行时解析?
最佳答案
检查ld 的-Bsymbolic 选项。
如果指定了-Bsymbolic,那么在创建共享时
对象 ld 将尝试将对全局符号的引用绑定(bind)到定义
在 共享库中。默认是将绑定(bind)延迟到运行时。
举个例子可能会更清楚。
假设 example.o 包含对定义在
global.o,
$ nm example.o | grep ' U'
U _GLOBAL_OFFSET_TABLE_
U globalfn
$ nm global.o | grep ' T'
00000000 T globalfn
和两个共享对象,normal.so 和 symbolic.so,构建为
如下:
$ cc -fPIC -c example.c
$ cc -c global.c
$ rm -f archive.a; ar cr archive.a global.o
$ ld -shared -o normal.so example.o archive.a
$ ld -Bsymbolic -shared -o symbolic.so example.o archive.a
反汇编 normal.so 的代码显示调用
globalfn 实际上是在遍历过程链接表,并且
因此调用的最终目的地是在运行时确定的。
$ objdump --disassemble normal.so
...snip...
00000194 <example>:
...snip...
1a6: e8 d9 ff ff ff call 184 <globalfn@plt>
...snip...
$ readelf -r normal.so
Relocation section '.rel.plt' at offset 0x16c contains 1 entries:
Offset Info Type Sym.Value Sym. Name
00001244 00000207 R_386_JUMP_SLOT 000001b8 globalfn
而在 symbolic.so 中,调用总是调用的定义
共享对象中的 globalfn。
$ objdump --disassemble symbolic.so
...snip...
0000016c <shared>:
...snip...
17e: e8 0d 00 00 00 call 190 <globalfn>
...snip...
$ readelf -r symbolic.so
There are no relocations in this file.
关于c++ - Ld 神奇地覆盖静态链接的符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7201667/
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我在pry中定义了一个函数:to_s,但我无法调用它。这个方法去哪里了,怎么调用?pry(main)>defto_spry(main)*'hello'pry(main)*endpry(main)>to_s=>"main"我的ruby版本是2.1.2看了一些答案和搜索后,我认为我得到了正确的答案:这个方法用在什么地方?在irb或pry中定义方法时,会转到Object.instance_methods[1]pry(main)>defto_s[1]pry(main)*'hello'[1]pry(main)*end=>:to_s[2]pry(main)>defhello[2]pry(main)
在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
我正在使用Rails构建一个简单的聊天应用程序。当用户输入url时,我希望将其输出为html链接(即“url”)。我想知道在Ruby中是否有任何库或众所周知的方法可以做到这一点。如果没有,我有一些不错的正则表达式示例代码可以使用... 最佳答案 查看auto_linkRails提供的辅助方法。这会将所有URL和电子邮件地址变成可点击的链接(htmlanchor标记)。这是文档中的代码示例。auto_link("Gotohttp://www.rubyonrails.organdsayhellotodavid@loudthinking.
我正在尝试用Prawn生成PDF。在我的PDF模板中,我有带单元格的表格。在其中一个单元格中,我有一个电子邮件地址:cell_email=pdf.make_cell(:content=>booking.user_email,:border_width=>0)我想让电子邮件链接到“mailto”链接。我知道我可以这样链接:pdf.formatted_text([{:text=>booking.user_email,:link=>"mailto:#{booking.user_email}"}])但是将这两行组合起来(将格式化文本作为内容)不起作用:cell_email=pdf.make_c
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我正在尝试在Rails上安装ruby,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我