• lighttpd 项目 faq 页用 ruby at 2026年09月24日

    推荐一个能上首页推荐的 perl 项目:: https://github.com/openresty/stapxx

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    use Getopt::Long qw( GetOptions :config no_ignore_case);
    use File::Spec ();
    use File::Temp qw( tempdir );
    use FindBin ();
    
    sub quote_sh_args ($);
    
    GetOptions("D=s@",          \(my $D_opts),
               "c=s",           \(my $shcmd),
               "d=s@",          \(my $d_opts),
               "arg=s%",        \(my $args),
               "args",          \(my $print_args),
               "dump-src",      \(my $dump_src),
               "sample-pid=i",  \(my $sample_pid),
               "exec=s",        \(my $exec_path),
               "help",          \(my $help),
               "master=i",      \(my $master_pid),
               "x=i",           \(my $pid),
               "e=s",           \(my $src),
               "v",             \(my $verbose),
               "skip-badvars",  \(my $skip_badvars),
               "I=s@",          \(my $Inc))
       or die usage();
    
    push @$Inc, '.', "$FindBin::Bin/tapset";
    
    #warn "Inc: @$Inc\n";
    
    if ($^O ne 'linux') {
        die "Only linux is supported but I am on $^O.\n";
    }
    
    if ($print_args && $args && %$args) {
        die "No --arg is allowed when --args is specified.\n";
    }
    
    my $ver = `stap -V 2>&1`;
    if (!defined $ver) {
        die "Systemtap not installed or its \"stap\" utility is not visible to the PATH environment: $!\n";
    }
    
    if ($ver =~ /version\s+(\d+\.\d+)/i) {
        my $v = $1;
        my $min_ver = 2.3;
        if ($v < $min_ver) {
            die "ERROR: at least systemtap $min_ver is required but found $v\n";
        }
    
    } else {
        die "ERROR: unknown version of systemtap:\n$ver\n";
    }
    
    if ($help) {
        print usage();
        exit;
    }
    
    my %set_D_opts;
    for my $opt (@$D_opts) {
        #warn "$opt\n";
        if ($opt =~ /^([_A-Z]+)=/) {
            $set_D_opts{$1} = 1;
        }
    }
    
    if (!$set_D_opts{MAXACTION}) {
        push @$D_opts, "MAXACTION=100000";
    }
    
    if (!$set_D_opts{MAXMAPENTRIES}) {
        push @$D_opts, "MAXMAPENTRIES=5000";
    }
    
    if (!$set_D_opts{MAXBACKTRACE}) {
        push @$D_opts, "MAXBACKTRACE=200";
    }
    
    my $infile;
    if (!defined $src) {
        $infile = shift
            or die "No input file specified.\n";
    
        $src = read_src_file($infile);
    
    } else {
        $infile = "-e";
    }
    
    my (%StdVars, %UsedLibs, %DSOs, %LibPaths, %UsedStdVars);
    
    my @stap_opts;
    
    if ($verbose) {
        push @stap_opts, "-v";
    }
    
    if ($d_opts) {
        for my $opt (@$d_opts) {
            push @stap_opts, '-d', $opt;
        }
    }
    
    if (defined $skip_badvars) {
        push @stap_opts, "--skip-badvars";
    }
    
    for my $opt (@$D_opts) {
        push @stap_opts, "-D$opt";
    }
    
    if (defined $exec_path) {
        if (!-f $exec_path) {
            die "$exec_path not found.\n";
        }
    
        $StdVars{exec_path} = $exec_path;
        push @stap_opts, '-d', $exec_path;
    
        open my $in, "ldd $exec_path|"
            or die "cannot run the command \"ldd $exec_path\": $!\n";
        while (<$in>) {
            if (m{\s+(\/\S+\.so(?:\.\d+)*)}) {
                my $path = $1;
                #warn "Found DSO $path.\n";
                $DSOs{$path} = 1;
            }
        }
    
        for my $path (sort keys %DSOs) {
            push @stap_opts, '-d', $path;
        }
    
        close $in;
    }
    
    if (defined $pid) {
        if (defined $master_pid) {
            die "-x <pid> and --master <pid> are exclusive.\n";
        }
    
        push @stap_opts, "-x", $pid;
        my $exec_file = "/proc/$pid/exe";
        if (!-f $exec_file) {
            die "Nginx process $pid is not running or ",
                "you do not have enough permissions.\n";
        }
    
        $StdVars{pid_ok} = gen_pid_test_condition();
        $StdVars{target} = $pid;
    
        if (!defined $exec_path) {
            $exec_path = readlink $exec_file;
            $StdVars{exec_path} = $exec_path;
            push @stap_opts, "-d", $exec_path;
        }
    
        process_dso($pid);
    }
    
    if (defined $master_pid) {
        #push @stap_opts, "-x", $master_pid;
        my $exec_file = "/proc/$master_pid/exe";
        if (!-f $exec_file) {
            die "Nginx process $master_pid is not running or ",
                "you do not have enough permissions.\n";
        }
    
        if (!defined $exec_path) {
            $exec_path = readlink $exec_file;
            $StdVars{exec_path} = $exec_path;
            push @stap_opts, "-d", $exec_path;
        }
    
        # process DSO files
        my @pids = get_child_processes($master_pid);
        if (@pids == 0) {
            die "No child processes found for $master_pid.\n";
        }
    
        $StdVars{pid_ok} = gen_pid_test_condition(\@pids);
        $StdVars{target} = "@pids";
    
        my $pid = $pids[0];
        process_dso($pid);
    }
    
    if ($sample_pid) {
        process_dso($sample_pid);
    }
    
    if (!defined $StdVars{pid_ok} && defined $exec_path) {
        $StdVars{pid_ok} = '1';
    }
    
    if (!defined $StdVars{target} && defined $exec_path) {
        $StdVars{target} = 'ANY';
    }
    
    if (!$print_args) {
        while (my ($k, $v) = each %$args) {
            #warn "getting $k => $v";
            $StdVars{"arg_$k"} = $v;
        }
    }
    
    my %used_args;
    
    my $stap_src = process_src($infile, $src);
    if ($dump_src) {
        print $stap_src;
        exit;
    }
    
    if ($print_args) {
        for my $name (sort keys %used_args) {
            my $default = $used_args{$name};
            print "\t--arg $name=VALUE";
            if (defined $default) {
                print " (default: $default)\n";
    
            } else {
                print "\n";
            }
        }
        exit;
    }
    
    for my $key (keys %$args) {
        if (!$UsedStdVars{"arg_$key"}) {
            my $val = $args->{$key};
            if (!defined $val) {
                $val = '';
            }
            warn "WARNING: \$^arg_$key is defined by \"--arg $key=$val\", "
                 ."but never used.\n";
        }
    }
    
    my $tmpdir = tempdir("stapxx-XXXXXXXX", CLEANUP => 1);
    while (my ($lib, $src) = each %UsedLibs) {
        my $outfile = "$tmpdir/$lib.stp";
        open my $out, ">$outfile"
            or die "Cannot open $outfile for writing: $!\n";
        print $out $src;
        close $out;
    }
    
    push @stap_opts, "-I", $tmpdir;
    
    if (defined $shcmd) {
        push @stap_opts, "-c", $shcmd;
    }
    
    my $cmd = "stap " . quote_sh_args(\@stap_opts) . " -";
    #warn $cmd;
    open my $in, "|$cmd"
        or die "Cannot run stap: $!\n";
    print $in $stap_src;
    close $in;
    
    sub eval_usr_var {
        my ($file, $usr_vars, $var) = @_;
        if (defined $usr_vars->{$var}) {
            return $usr_vars->{$var};
        }
    
        die "$file: line $.: Undefined user varaible \$*$var.\n";
    }
    
    sub eval_std_var {
        my ($file, $var, $trait_name, $trait_val) = @_;
    
        $UsedStdVars{$var} = 1;
    
        if (defined $StdVars{$var}) {
            return $StdVars{$var};
        }
    
        if (defined $trait_name) {
            #warn "trait: $trait_name";
            if ($trait_name eq 'default') {
                if ($print_args && $var =~ /^arg_(\w+)$/) {
                    $used_args{$1} = $trait_val;
                }
                $StdVars{$var} = $trait_val;
                return $trait_val;
    
            } else {
                die "$file: line $.: unknown trait name: $trait_name\n";
            }
        }
    
        if ($print_args) {
            if ($var =~ /^arg_(\w+)$/) {
                $used_args{$1} = undef;
            }
            return '';
        }
    
        if ($var eq 'exec_path') {
            die "$file: line $.: \$^exec_path is used but neither -x <pid> ",
                "nor --exec <path> is specified.\n";
    
        } elsif ($var =~ /^arg_(\w+)$/) {
            die "$file: line $.: \$^$var is used but no --arg $1=VAL option is specified.\n";
    
        } elsif ($var =~ /^(lib\w+)_path$/) {
            my $prefix = $1;
            my $libpath = find_dso_path($prefix);
            if (!$libpath) {
                warn "$file: line $.: $prefix is not found, assuming it is statically linked.\n";
                if (!defined $StdVars{exec_path}) {
                    die "No -x <pid> option is specified.\n";
                }
    
                $LibPaths{$prefix} = $StdVars{exec_path};
                return $StdVars{exec_path};
            }
    
            return $libpath;
    
        } else {
            die "$file: line $.: Undefined built-in variable \$^$var.\n";
        }
    }
    
    sub find_dso_path {
        my $pat = shift;
    
        my $path = $LibPaths{$pat};
        if ($path) {
            return $path;
        }
    
        my $name;
        if ($pat !~ /^lib(\S+)/) {
            die "bad pattern: $pat";
        }
    
        $name = $1;
    
        my $found_path;
        for my $path (sort keys %DSOs) {
            #warn "checking $path against $pat";
            if ($path =~ m{\blib\Q$name\E[-.\d]*\.so(?:\.\d+)*$}) {
                $LibPaths{$pat} = $path;
                $found_path = $path;
                warn "Found exact match for $pat: $path\n";
                last;
        }
    
            if ($path =~ m{\b(?:lib)?\Q$name\E[^/\s]*?\.so(?:\.\d+)*$}) {
                if ($found_path) {
                    warn "Ignored ambiguous library $path for \"$pat\"\n";
                    next;
                }
    
                $LibPaths{$pat} = $path;
                $found_path = $path;
            }
        }
    
        return $found_path;
    }
    
    sub read_src_file {
        my $infile = shift;
        open my $in, $infile
            or die "Cannot open $infile for reading: $!\n";
        my $src = do { local $/; <$in> };
        close $in;
        return $src;
    }
    
    sub use_libs {
        my ($file, $libs) = @_;
        #warn "libs: $libs";
        my @libs = split /\s*,\s*/, $libs;
        for my $lib (@libs) {
            #warn "processing $lib...";
            my $path = join("/", split /\./, $lib) . ".sxx";
            #warn $path;
            for my $dir (@$Inc) {
                my $abspath = File::Spec->catfile($dir, $path);
                #warn "Testing $abspath\n";
                #warn "exist: ", (-f $abspath) ? 1 : 0;
                if (-f $abspath) {
                    my $src = read_src_file($abspath);
                    $UsedLibs{$lib} = process_src($abspath, $src);
                    goto next_lib;
                }
            }
            die "$file: line $.: cannot find \@user24 library $lib\n";
    next_lib:
        }
        return "";
    }
    
    sub process_src {
        my ($file, $src) = @_;
    
        my %usr_vars;
        my @bits;
    
        my $libname_pat = qr/(?:\w+(?:\.\w+)*)/;
        # process the input file
        open my $in, '<', \$src or die $!;
    
        while (<$in>) {
            if ($. == 1 && /^\#!/) {
                $_ = "#!/usr/bin/env stap\n";
                next;
            }
    
            s{\$\^(arg_\w+)(?:\s*:(\w+)\s*\((.*?)\))?}{eval_std_var($file, $1, $2, $3)}eg;
            s{\@pfunc\s*\(\s*(\w+)\s*\)}{process("\$^exec_path").function("$1")}g;
            s{\$\^(\w+|lib[-.\w]+_path)(?:\s*:(\w+)\s*\((.*?)\))?}{eval_std_var($file, $1, $2, $3)}eg;
            s{\$\*(\w+)\s*:=\s*(\&?\@(?:cast|var)\(.*?\)(?:\[\d+\])?)}{$usr_vars{$1} = $2; ""}eg;
            s{\$\*(\w+)}{eval_usr_var($file, \%usr_vars, $1)}eg;
            s{\@use\s+($libname_pat(?:\s*,\s*$libname_pat)*)}{use_libs($file, $1)}eg;
    
        } continue {
            push @bits, $_;
        }
    
        close $in;
        return join '', @bits;
    }
    
    sub usage {
        return <<'_EOC_';
    Usage:
        stap++ [optoins] [infile]
    
    Options:
        --arg NM=VAL    Specify extra user arguments (for $^arg_NM).
        --args          Print all available arguments for --arg.
        -c CMD     start the probes, run CMD, and exit when it finishes
        -d PATH         Load debug info for the specified objects
        -D NM=VAL       Emit macro definition into generated C code.
        -e SCRIPT       Run given script.
        --exec PATH     Specify the executable file path to be traced.
        --help          Print this help.
        -I PATH         Specify the stap++ tapset library search directory.
        --master PID    Specify the master pid whose child processes are traced.
        --sample-pid PID  Sample process to inspect DSO objects to load via -d
        -v              Be verbose.
        -x PID          Sets target() to PID (also for $^exec_path and $^libxxx_path).
    
    Examples:
        stap++ -x 12345 -e 'probe begin { println("hello") exit() }'
        stap++ -x 12345 infile.ss
    _EOC_
    }
    
    sub get_child_processes {
        my $pid = shift;
        my @files = glob "/proc/[0-9]*/stat";
        my @children;
        for my $file (@files) {
            #print "file: $file\n";
            if ($file =~ m{^/proc/$pid/}) {
                next;
            }
    
            open my $in, $file or next;
            my $line = <$in>;
            close $in;
            if ($line =~ /^(\d+) \S+ \S+ (\d+)/) {
                my ($child, $parent) = ($1, $2);
                if ($parent eq $pid) {
                    push @children, $child;
                }
            }
        }
    
        @children = sort { $a <=> $b } @children;
        return @children;
    }
    
    sub gen_pid_test_condition {
        my $pids = shift;
        if (!$pids) {
            return "pid() == target()";
        }
    
        my @c;
        for my $pid (@$pids) {
            push @c, "pid() == $pid";
        }
        return '(' . join(" || ", @c) . ')';
    }
    
    sub process_dso {
        my $pid = shift;
        my $maps_file = "/proc/$pid/maps";
        open my $in, $maps_file
            or die "Cannot open $maps_file for reading: $!\n";
    
        while (<$in>) {
            if (m{\S+\.so(?:\.\d+)*$}) {
                my $path = $&;
                $DSOs{$path} = 1;
                #warn "seeing $path";
            }
        }
    
        for my $path (sort keys %DSOs) {
            push @stap_opts, "-d", $path;
        }
    }
    
    sub quote_sh_args ($) {
        my ($args) = @_;
        for my $arg (@$args) {
           if ($arg =~ m{^[- "&%;,|?*.+=\w:/()]*$}) {
              if ($arg =~ /[ "&%;,|?*()]/) {
                 $arg = "'$arg'";
              }
              next;
           }
           $arg =~ s/\\/\\\\/g;
           $arg =~ s/'/\\'/g;
           $arg =~ s/\n/\\n/g;
           $arg =~ s/\r/\\r/g;
           $arg =~ s/\t/\\t/g;
           $arg = "\$'$arg'";
        }
        return "@$args";
    }
    

    你们觉得怎么样

  • lighttpd 项目 faq 页用 ruby at 2026年09月24日

    顺便发一个小福利,打开 win10 设置,结束掉 explorer,然后设置里面还能用默认的微软拼音

  • lighttpd 项目 faq 页用 ruby at 2026年09月24日

    还有 chinaunix 的百度百科里面说明了定期生成静态页面来减少服务器负载,说明依赖 react.js 还有其他出路

  • lighttpd 项目 faq 页用 ruby at 2026年09月24日
  • temporary picture r 站压缩图片太厉害了临时给手机传个照片都不可以

  • 作者在阿里巴巴上过班可以介绍内推啊支付宝肯定有工作一定是作者自私自利不愿意分享,像我大专都还没说话;不支持 IE8 或者 IE11,对了建议大家在没有必要的情况下关闭浏览器的硬件加速,IE 浏览器在 F12 里面仿真,左上角保存仿真设置

  • voidlinux 可以试用 at 2026年09月22日

    我现在把 voidlinux 当成简版 opensuse 来用因为 opensuse 好像很混乱,wiki 乱写

  • 暂时隐藏暂时隐藏 at 2026年09月22日

    只要谷歌放弃疯狂赞助 python 一切都会好起来的

  • 暂时隐藏暂时隐藏 at 2026年09月22日

    现在我终于比人工智能值钱了!!!

  • 暂时隐藏暂时隐藏 at 2026年09月22日

    现在人工智能已经收费高了,你认为中美欧人工智能差距大另说

  • 暂时隐藏暂时隐藏 at 2026年09月22日

    除了顽固份子博客园,几乎没人用 ASP

  • 隔壁 chinaunix 也升级停服了真是的国内脚本论坛怎么这么难全靠 php 支撑

  • 如何申请物理最大内存 at 2026年09月22日

    习惯写脚本语言没有心思学 java 或者 c#,广东的大学学计算机学费超贵

  • voidlinux 可以试用 at 2026年09月21日

    这个系统更新比较频繁

  • 对了我专业不是软工,自学 perl 来这里是为了添加人气

  • sqlite3 很简单啊看 ruby 的 gem 页面介绍就可以了

  • 交流电不值钱,大专学的水利水电工程

  • 常见的绕过 internet 的方法 at 2026年09月20日

    可能是我的手机和电信诈骗团伙在同一个小区的网络里面还没有出 10.0.0.???网络的时候被入侵了

  • 推荐访问 global 点 v2ex 点 co,必须加安全链接

  • 这个 list 比数组快了百倍 at 2026年09月20日

    大部分依赖处理器和操作系统编译优化,实在不行用显卡计算,你看人工智能依赖的硬件变好之后连 js 这种烂货都能天天用,以前 js 都是在比烂链最后的

  • 欢迎使用 perl5 的 mojolicious 框架

  • 看来你是 ruby 的粉丝建议你好好学习 perl,但是 perl6 基本没多少人用

  • 主要是网上教如何写一个 Excel 的教程太多让我失去信心,但是一看 php 版本还是 8,我对生活又充满了信心

  • 你看你上传的图片都压缩成什么样子了我还以为是我老旧的浏览器有问题

  • 个人情感宣泄 at 2026年09月20日

    日常批评 java 占内存实在是太高了

  • voidlinux 可以试用 at 2026年09月20日

    如果需要电脑被常见 linux 病毒感染可以临时使用一下

  • voidlinux 可以试用 at 2026年09月20日

    对不起发帖时间电脑中了盗号木马并被骗钱了现在基本修好电脑了

  • perl 编译快多了 at 2026年09月20日

    以前没用过四核以上的电脑

  • 你该不会连 sqlite 也没用过吧

  • opensuse 和 fedora 都有常见 gem 的打包