gpt4 book ai didi

perl - 如何跟踪 XS .so 文件?

转载 作者:行者123 更新时间:2023-12-03 23:50:20 37 4
gpt4 key购买 nike

我有一个小的 Perl 程序。程序加载一个模块。模块加载一个带有 XSLoader 的 .so 文件.这个 Perl 在 Linux 上运行,是用 gcc 和 -DDEBUGGING 构建的。 ,然后是 .so 文件。我可以重新编译。

执行 Perl 程序时,如何跟踪 .so 文件中的 C 函数?我需要按照它们运行的​​顺序知道函数的名称。也有函数参数会很好。

最佳答案

这是一个使用 gdb 进入共享库的示例。我正在使用 Linux(Ubuntu 18.04)。

我首先使用 perlbrew 安装了 Perl 的调试版本:

perlbrew install perl-5.26.2 --as=5.26.2d -DDEBUGGING
perlbrew use 5.26.2d

然后,我在文件夹 /home/hakon/mylib 中创建了一个共享库(为了测试目的而精简到非常少的内容):

mylib.c

此函数改编自 perlxstut 中的示例 3:
#include <math.h>
#include "myclib.h"
double my_clib_function( double arg ) {
if (arg > 0.0) {
arg = floor(arg + 0.5);
} else if (arg < 0.0) {
arg = ceil(arg - 0.5);
} else {
arg = 0.0;
}
return arg;
}

myclib.h :
double my_clib_function( double arg );

然后我创建了共享库 libmylib.so :
gcc -g -c -fpic mylib.c
gcc -g -shared -o libmylib.so mylib.o

请注意,我们通过将 libmylib.so 开关设置为 -g 来在 gcc 中包含调试符号。

现在,我们可以创建一个 .xs 文件来调用共享库函数(在文件夹 /home/hakon/myxstest 中):

Mytest.xs
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "myclib.h"

MODULE = Mytest PACKAGE = Mytest

void
wrapper(arg)
double arg
CODE:
arg = my_clib_function( arg);
OUTPUT:
arg

然后我们需要将 XS 文件链接到 Perl 包名:

lib/Mytest.pm :
package Mytest;
use 5.022001;
use strict;
use warnings;

require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw() ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
our $VERSION = '0.01';

require XSLoader;
XSLoader::load('Mytest', $VERSION);

接下来,我们需要一个像 ExtUtils::MakeMaker 这样的构建系统来编译
XS 文件(进入另一个共享库):

Makefile.PL :
use 5.022001;
use ExtUtils::MakeMaker;
my $lib_dir = '/home/hakon/mylib';
WriteMakefile(
NAME => 'Mytest',
VERSION_FROM => 'lib/Mytest.pm',
PREREQ_PM => {},
ABSTRACT_FROM => 'lib/Mytest.pm',
AUTHOR => 'Håkon Hægland <xxx.yyy@gmail.com>',
LIBS => ["-L$lib_dir -lmylib"],
INC => "-I. -I$lib_dir",
OPTIMIZE => '-g',
);

请注意,我们使用 Mytest.so 请求调试符号(对于 OPTIMIZE => '-g' 共享对象),并通过使用 libmylib.soLIBS 参数来告知另一个共享库 WriteMakefile() 的位置。

然后我们编译 XS 代码:
perl Makefile.PL
make

最后,我们编写一个小的测试 Perl 脚本:

p.pl
#! /usr/bin/env perl
use feature qw(say);
use strict;
use warnings;
use ExtUtils::testlib;
use Mytest;

my $res = 3.5;
Mytest::wrapper( $res ); # <-- Warning: modifies $res in place !
say $res;

我们可以知道在我们的测试脚本 gdb 上运行 p.pl :
$ gdb -q --args perl p.pl
Reading symbols from perl...done.

我们在 XS 文件的第 14 行设置断点:
(gdb) break Mytest.xs:14
No source file named Mytest.xs.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (Mytest.xs:14) pending.

然后运行脚本:
(gdb) run
Starting program: /home/hakon/perlbrew/perls/5.26.2d/bin/perl p.pl
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, XS_Mytest_wrapper (cv=0x555555bdc860) at Mytest.xs:14
14 arg = my_clib_function( arg);

现在我们已经停在 XS 文件中我们将调用共享库函数的位置。如果我们愿意,我们可以检查将要传递的参数:
(gdb) p arg
$1 = 3.5

然后步入共享库:
(gdb) s
my_clib_function (arg=3.5) at mylib.c:5
5 if (arg > 0.0) {

等等..

关于perl - 如何跟踪 XS .so 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50643536/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com