Perl-多线程脚本打印内存映射和回溯 [英] Perl - Multithreading script prints memory map and backtrace

查看:136
本文介绍了Perl-多线程脚本打印内存映射和回溯的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我调用我的多线程perl脚本时,在某些情况下,它会引发类似于以下内容的异常.很抱歉,我无法共享代码.但是,如果真的需要,我可以尝试构建一个代码段(如果真的需要).因为我想这应该有一些理论上的答案.

When I invoke my multithreaded perl script, on a few occassions, it throws some exception similar to the following. I am sorry that I could not share code. But if really needed I can try to build a snippet (if really really required). Because I guess this should have some theoretical answer.

*** glibc detected *** perl: double free or corruption (!prev): 0x00007f775401e9a0 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3d74c75e66]
/lib64/libc.so.6[0x3d74c789b3]
/lib64/libc.so.6[0x3d74c7b880]
/lib64/libc.so.6(realloc+0xe5)[0x3d74c7baf5]
/usr/lib/../lib64/libcrypto.so.10(CRYPTO_realloc+0x5f)[0x7f775907bd8f]
/usr/lib/../lib64/libcrypto.so.10(lh_insert+0xee)[0x7f77590f763e]
/usr/lib/../lib64/libcrypto.so.10(OBJ_NAME_add+0x6b)[0x7f775907f12b]
/usr/lib/../lib64/libcrypto.so.10(EVP_add_cipher+0x27)[0x7f7759102387]
/usr/lib/../lib64/libcrypto.so.10(OpenSSL_add_all_ciphers+0x4b7)[0x7f7759106a07]
/usr/lib/../lib64/libcrypto.so.10(OPENSSL_add_all_algorithms_noconf+0xe)[0x7f775910653e]
/usr/local/lib/libssh2.so.1(libssh2_init+0x39)[0x7f77596800b9]

为什么会出现此类错误?

Why am I getting such errors?

我正在使用use Thread :: Queue;使用thread :: shared;请让我知道您的看法.

I am using use Thread::Queue; use threads::shared; Please let me know your views.

下面是线程库的版本信息.

Below are the thread libraries version info.

use threads; - installed v2.15 (latest - 2.16)
use Thread::Queue; - installed v3.12 (up to date)
use threads::shared; - installed v1.56 (latest - 1.57)
perl - installed v5.26.1

其他库为:

use YAML::XS 'LoadFile';  - 0.66 up to date
use Net::Netconf::Manager; - 1.02 up to date
use Config::Properties; - 1.80 up to date
use Sys::Syslog; - 0.35 up to date
use DateTime::Format::Strptime; - 1.74 up to date
use DateTime; - 1.44 up to date
use XML::LibXML; - 2.0129 (latest 2.0139)
use Regexp::Common qw/net/; - 2017060201 up to date
use Getopt::Long; - 2.5 up to date

推荐答案

要给您一个肯定的答案,我们需要一些可以运行并进行故障排除的东西.否则错误将无法重现.

To give you a firm answer, we need something we can run and troubleshoot. Otherwise the error is not reproducible.

已经说过-这看起来类似于我之前遇到的某些模块不是线程安全的事情-它们通常会运行良好,然后偶尔会在您的脸上爆炸.

Having said that - this looks like something similar to what I have encountered before with certain modules not being thread safe - they'll often run fine, and then very occasionally explode in your face.

例如 Crypt :: SSLeay 早在2008年. Net :: SSLeay 1.4.2之前的版本

E.g. Crypt::SSLeay back in 2008. Net::SSLeay prior to 1.4.2

一般的解决方法是停止在编译时使用use加载罪魁祸首-因为然后所有线程都继承相同的状态-而是在线程内 ,在运行时使用requireimport加载它们.这样,您就可以隔离它们-您的线程将花费稍微更长的时间来启动,但是无论如何,您都不应在perl中向这些线程发送垃圾邮件.

The general workaround is to stop loading the culprits at compile time with use - because then the same state is inherited by all threads - and instead within the thread, load them at runtime with require and import. By doing this, you're isolating them - your threads will take slightly longer to start, but you shouldn't be spamming threads anyway in perl.

或使用线程安全的其他模块.

Or use a different module that is thread safe.

关于您的更新和屏幕截图-提到了Net::SSH2-这意味着您的其他模块之一正在将其引入.

With your update and screenshot - Net::SSH2 is mentioned - and that implies one of your other modules is pulling that in.

但是 Net :: SSH线程安全表示

However Net::SSH thread safey indicates that libssh might have some constraints on thread safety:

线程安全:只是不要同时共享句柄

Thread-safe: just don't share handles simultaneously

您没有明确提及使用它,但是看起来它正在被另一个模块插入.大概是Net::Netconf::Manager.

You don't explicitly mention using it, but it looks like it's being pulled in by another module. At a guess, that'll be Net::Netconf::Manager.

还有第二个猜测-它很可能正在执行共享句柄",因为它没有意识到它正在线程中运行.

And as a second further guess - it might well be doing the 'share handles' because it doesn't realise it's being run in a thread.

所以这个模块是我建议在线程中隔离的模块:

So this module is the one I'd suggest isolating within the threads:

require 'Net::NetConf::Manager';
Net::NetConf::Manager -> import; 

然后在线程内进行实例化.

And do the instantiation within-thread.

在使用工作线程模型时,这应该是最小的开销,并且意味着您不会遇到此问题.

As you're using a worker-threads model, this should be minimal overhead, and will mean that you're not hitting this problem.

但更笼统地说-除非模块明确声明是安全的,否则认为模块是线程安全的是不明智的.通常,只要模块可以假定/暗示任何类型的资源共享,例如网络套接字,文件句柄,数据库连接等,主要的跳闸"点就可以.通常在实例化时创建套接字(例如,传递用户名的点/password),并且有两个线程试图同时驱动套接字是潜在的竞争条件.

But more generally - it's unwise to assume modules are thread safe unless they explicitly say they are. The major 'tripping' points are usually whenever any sort of resource sharing can be assumed/implied by the module, such as network sockets, file handles, database connections etc. Often a socket is created at instantiation (e.g. the point where you pass username/password) and having two threads trying to drive a socket concurrently is a potential race condition.

这篇关于Perl-多线程脚本打印内存映射和回溯的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆