- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
一般问题:如果调用它的脚本或 shell (bash) 命令将它调用到一个变量中,什么会导致本身运行良好的脚本挂起?
换句话说,怎么会有这样调用的脚本... /path/to/script arg arg
...当这样调用时失败并挂起... VAR=$(/path/to/script arg arg);
?
(在注意到软件故障导致大量初始测试给出错误结果后的主要编辑)
我的具体案例:我有一个运行良好的脚本(启动、停止或重新启动 Java 应用程序 Apache Solr,adapted from here)。代码如下,它的命令是sbin/service solr [action]
,例如 sbin/service solr start
.
从脚本或直接从控制台调用时(在我的情况下为 bash
),例如 sbin/service solr start
,它工作正常并快速完成。但是,如果它被调用到一个变量中,例如 VAR=$(sbin/service solr start);
,它可以工作,但会挂起 futext/clock_gettime 循环(跟踪如下)。如果它不是被调用到变量中,而是被调用到 strace
中,它也会挂起。 .
奇怪的是,其他脚本以相同的方式以相同的语法调用,例如sbin/service httpd start
,当被调用到一个变量时工作得很好。因此,很明显,当输出存储为变量时,脚本可能会挂起,但如果不是这种情况,则运行得很好。
以下是测试哪些调用挂起,哪些不挂起的结果:
挂机 ------------------------------------------------
VAR=$(/sbin/service solr start);
VAR=$(source /sbin/service solr start);
VAR=$(nohup /sbin/service solr start &);
source
启动服务导致服务不工作。
VAR=$(/sbin/service solr start >> /dev/null);
/dev/null
允许我们请求输出而不会导致它挂起。但是,它没有多大用处,因为没有收到实际输出。
/sbin/service solr start
VAR=$(/sbin/service httpd restart);
service
脚本,并且脚本的输出会毫无问题地传递给变量。
SOLR_DIR="[path/to/application]"
JAVA_OPTIONS="-Xms64m -Xmx64m -DSTOP.PORT=8079 -DSTOP.KEY=mustard -jar start.jar"
LOG_FILE="/var/log/solr.log"
JAVA="/usr/bin/java"
case $1 in
start)
echo "Starting Solr"
cd $SOLR_DIR
$JAVA $JAVA_OPTIONS 2> $LOG_FILE &
;;
stop)
echo "Stopping Solr"
cd $SOLR_DIR
$JAVA $JAVA_OPTIONS --stop
;;
restart)
$0 stop
sleep 1
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}" >&2
exit 1
;;
esac
var/log/solr.log
中没有错误或任何异常(在脚本中命名的日志文件)。 Centos Linux 服务器(如果相关)。
strace -f -o strace.out /path/to/script
在调用此脚本的脚本上,查看(大量!)输出文件
strace.out
.它将近 3mbs,这里有一些观察:
25687 futex(0x688d454, FUTEX_WAIT_PRIVATE, 1, {0, 49980000}) = -1 ETIMEDOUT (Connection timed out)
25687 futex(0x688d428, FUTEX_WAKE_PRIVATE, 1) = 0
25687 clock_gettime(CLOCK_MONOTONIC, {39074112, 932735888}) = 0
25687 clock_gettime(CLOCK_REALTIME, {1355007234, 333458000}) = 0
ps -p
即使我在脚本仍在运行时这样做,而输出文件仍在变大并且这些代码行仍在编写中。我不太确定这怎么可能。
solr/solr.xml
是一个 Solr 配置文件,需要读取它来启动 Solr过程):
25874 stat("solr/solr.xml", {st_mode=S_IFREG|0777, st_size=1320, ...}) = 0
25874 write(2, "Dec 8, 2012 5:12:05 PM org.apach"..., 106) = 106
25874 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 89
25874 fcntl(89, F_GETFL) = 0x2 (flags O_RDWR)
25874 fcntl(89, F_SETFL, O_RDWR|O_NONBLOCK) = 0
25874 setsockopt(89, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
25874 bind(89, {sa_family=AF_INET, sin_port=htons(8983), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
25874 listen(89, 50) = 0
25874 setsockopt(89, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
25874 lseek(12, 57747, SEEK_SET) = 57747
25874 read(12, "PK\3\4\n\0\0\0\10\0\221Vi>F\347\254\364\325\4\0\0002\t\0\0002\0\0\0", 30) = 30
25874 lseek(12, 57827, SEEK_SET) = 57827
25874 read(12, "\225V\377oSU\24\377\334\273\256\257_\36l\216m\254\262\351\224\241]\273\255\200\314/\5\246c\200"..., 1237) = 1237
25874 futex(0x2aaab0173054, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x2aaab0173050, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1} <unfinished ...>
25894 <... futex resumed> ) = 0
25894 futex(0x2aaab0173028, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
25874 <... futex resumed> ) = 1
25874 futex(0x2aaab0173028, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
25894 <... futex resumed> ) = 0
25894 futex(0x2aaab0173028, FUTEX_WAKE_PRIVATE, 1) = 0
25894 clock_gettime(CLOCK_REALTIME, {1355008325, 376033000}) = 0
25894 futex(0x2aaab0173054, FUTEX_WAIT_PRIVATE, 3, {0, 983000} <unfinished ...>
25874 <... futex resumed> ) = 1
25874 futex(0x2aaab0173054, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x2aaab0173050, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1} <unfinished ...>
25894 <... futex resumed> ) = 0
25894 futex(0x2aaab0173028, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
25874 <... futex resumed> ) = 1
25874 futex(0x2aaab0173028, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
25894 <... futex resumed> ) = 0
25894 futex(0x2aaab0173028, FUTEX_WAKE_PRIVATE, 1) = 0
25894 poll([{fd=89, events=POLLIN|POLLERR}], 1, -1 <unfinished ...>
25874 <... futex resumed> ) = 1
25874 write(2, "2012-12-08 17:12:05.376:INFO::St"..., 66) = 66
25874 write(2, "\n", 1) = 1
25874 mmap(0x41348000, 12288, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x41348000
25874 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
25874 sched_getaffinity(25874, 32, { ffff, 0, 0, 0 }) = 32
25874 sched_getaffinity(25874, 32, { ffff, 0, 0, 0 }) = 32
25874 gettid() = 25874
25874 rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
25874 rt_sigprocmask(SIG_UNBLOCK, [HUP ILL BUS FPE SEGV USR2 TERM], NULL, 8) = 0
25874 rt_sigprocmask(SIG_BLOCK, [QUIT], NULL, 8) = 0
25874 mmap(0x41348000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x41348000
25874 mprotect(0x41348000, 12288, PROT_NONE) = 0
25874 futex(0x10632d54, FUTEX_WAIT_PRIVATE, 1, NULL <unfinished ...>
25882 <... futex resumed> ) = -1 ETIMEDOUT (Connection timed out)
25882 futex(0x106cc428, FUTEX_WAKE_PRIVATE, 1) = 0
25882 clock_gettime(CLOCK_MONOTONIC, {39075204, 21489888}) = 0
25882 clock_gettime(CLOCK_REALTIME, {1355008325, 422198000}) = 0
25882 futex(0x106cc454, FUTEX_WAIT_PRIVATE, 1, {0, 49984000}) = -1 ETIMEDOUT (Connection timed out)
25882 futex(0x106cc428, FUTEX_WAKE_PRIVATE, 1) = 0
25882 clock_gettime(CLOCK_MONOTONIC, {39075204, 72479888}) = 0
25882 clock_gettime(CLOCK_REALTIME, {1355008325, 473185000}) = 0
25882 futex(0x106cc454, FUTEX_WAIT_PRIVATE, 1, {0, 49987000}) = -1 ETIMEDOUT (Connection timed out)
25882 futex(0x106cc428, FUTEX_WAKE_PRIVATE, 1) = 0
read()
在 channel 12 上。然后它只是循环 futex 和 clock_gettime 直到它被手动杀死。
nohup
运行调用此脚本的脚本并将输出转移到
/dev/null
,我在开始附近得到以下信息(输出文件中大约有 100kb):其中有很多:
25664 close(67) = -1 EBADF (Bad file descriptor)
25664 close(1023) = -1 EBADF (Bad file descriptor)
25664 open("/dev/null", O_RDWR) = 3
最佳答案
我很确定问题在于 shell 正在捕获/sbin/service 脚本和它启动的 solr 服务的输出,因此在继续之前将等待服务退出(或至少关闭其标准输出)。这是一个简单的演示:
$ bg_service() { while true; do sleep 10; done; }
$ start_bg_service() { echo "starting"; bg_service& echo "running"; }
$ start_bg_service
starting
[1] 8656
running
$ var=$(start_bg_service)
[It hangs at this point... until I open another shell and kill the background process]
关于linux - Shell 脚本挂起,但仅在调用变量或 strace 时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13782039/
我知道strace用途 ptrace做这份工作, 但它需要使用 TRACE_ME 运行目标进程在, 这不适用于已经运行的进程的情况。 它如何在已经运行的进程上工作? 最佳答案 strace -p -
精确是我在这里关注的重点...... mmap(0x37aa74d000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRI
我正在尝试调试 Gammu,一个“移动电话的库和命令行实用程序”,它在与调制解调器正常通信时“超时”。 gammu recognize -> 在指定的超时时间内没有响应。可能是手机未连接。 查看它产生
当我跑 strace -f strace /bin/ls 知道 strace 是如何工作的,它失败了 ptrace(PTRACE_TRACEME, 0, 0, 0) = -1 EPERM (Opera
[root@woyo test]# strace -o /tmp/lsof.strace -p 5625 Process 5625 attached - interrupt to quit q 有谁知
我想用strace跟踪系统调用。读写太多,因此我想将它们排除在外。 这是我的测试: strace -e trace=!read ls 我的电脑(ubuntu 14)无法运行此命令。错误消息是“!ope
我正在研究这个问题并决定自己实现该程序。 Interpreting STRACE output - pipes and forks strace 输出对我来说是不同的: execve("./fork"
我正在尝试调试 ngspice 的原因在运行模拟时将烦人的换行符打印到 stderr。我试图在可追溯到 1993 年的 2400 个源文件之一中找到它,但这并不像听起来那么容易!然而,这确实意味着我有
strace 密码: getcwd("/root"..., 4096) = 6 ltrace 密码: getcwd(NULL, 0)
open("/etc/ld.so.cache", O_RDONLY) = 3 open("/lib/libselinux.so.1", O_RDONLY) = 3 open("/lib/l
我有一个单线程的 unix 进程,它通过 tcp 与其他进程进行通信。 问题如下。 当我启动进程时,它会挂起(没有忙循环),直到我杀死它。 有趣的是,一旦我将 strace 附加到它,它就会继续以预期
我正在使用 strace 来查找程序中可能存在的错误,并且我有以下输出: open(0x7765533c, O_RDONLY) = -1 EACCES (Permission denied) 如何获取
我的 strace 给我这个输出 fcntl64(3, 0xe /* F_??? */, 0xff963a24) = 0 我希望看到类似的东西,在那里我可以看到 readalbe 内容而不是地址...
我有一个启动 libmicrohttpd 网络服务器(它管理自己的线程)的程序,然后在主线程中调用“暂停”,这样整个程序就不会退出。 我正在尝试对这个程序进行 strace,但是一旦我进入“暂停”调用
我想在后台运行 strace。例如,我在跑 strace -esetsid setsid sleep 123 但我想继续运行其他东西,直到 setsid 返回。显然,只需将 & 附加到 sleep 1
我有一个作为守护进程运行的 perl 脚本。它每 10 秒访问一次数据库,如果队列中有任何作业,它会生成一个单独的 shell 来执行单个作业。但脚本经常无法从数据库获取作业。 理想情况下应该像这
我知道它使用 ptrace 来实现, 它可以在寄存器中获取参数, 但他们只是数字, strace如何将它们转换成文字信息? 它只是针对每个系统调用的硬编码吗? 最佳答案 基本上,是的,它是硬编码的。如
我正在编写一个 python 程序,通过使用 ctypes 的挂载系统调用来挂载 fuse 文件系统。现在它在挂载系统调用中给出无效参数错误。我检查了所有的论点,它们似乎是正确的。我听 friend
尝试调试不返回 bash 提示符的程序,我使用了 strace并给它 PID。该程序是一个二进制文件,我没有源代码。根据strace , 有一个 -1 EBADF (Bad file descript
我正在尝试调试应用程序的启动。我想使用 strace 来跟踪应用程序在启动期间执行的系统调用,但是一旦应用程序启动,我不希望 strace 但是很难追踪到应用程序的启动。 有没有办法捕获应用程序启动的
我是一名优秀的程序员,十分优秀!