如何跟踪XS .so文件? [英] How do I trace through an XS .so file?

查看:149
本文介绍了如何跟踪XS .so文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小的Perl程序。该程序将加载一个模块。该模块使用 XSLoader 加载.so文件。该Perl在Linux上运行,并使用gcc和 -DDEBUGGING 构建,随后的.so文件也是如此。我可以重新编译。

I have a small Perl program. The program loads a module. The module loads an .so file with XSLoader. This Perl runs on Linux and is built with gcc and -DDEBUGGING, and subsequently so is the .so file. I can recompile.

执行Perl程序时,如何在.so文件中跟踪C函数?我需要按它们运行的​​顺序知道这些函数的名称。

When the Perl program is executed, how do I trace through the C functions in the .so file? I need to know the names of the functions in the order they run. It would be nice to have the function arguments, too.

推荐答案

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

Here is an example of using gdb to step into a shared library. I am using Linux (Ubuntu 18.04).

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

I first installed a debugging version of Perl using perlbrew:

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

然后,我在文件夹 / home / hakon / mylib中创建了一个共享库(出于测试目的,其内容精简至最小)

mylib.c

此功能改编自 perlxstut 中的示例3:

This function is adapted from example 3 in perlxstut:

#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 <中包含了调试符号/ code>,方法是将 -g 切换到 gcc

Note that we have included debugging symbols in libmylib.so by giving the -g switch to gcc.

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

Now, we can create an .xs file that will call the shared library function (in folder /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软件包名称:

Then we need to link the XS file to a Perl package name:

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文件(到另一个共享库中):

Next, we need a build system like ExtUtils::MakeMaker to compile the XS file (into another shared library):

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',然后我们使用 LIBS通知其他共享库 libmylib.so 的位置。 WriteMakefile()的code>参数。

Note that we request debugging symbols (for the Mytest.so shared object) with OPTIMIZE => '-g' and we inform about the location of the other shared library libmylib.so by using the LIBS argument to WriteMakefile().

我们然后编译XS代码:

We then compile the XS code:

perl Makefile.PL
make

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

Finally, we write a small test Perl script:

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

We can know run gdb on our test script p.pl:

$ gdb -q --args perl p.pl
Reading symbols from perl...done.

我们在XS文件的第14行设置了一个断点:

We set a breakpoint at line 14 in the XS file:

(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文件中停止了调用共享库函数的位置。如果需要,我们可以检查将要传递的参数:

Now we have stopped at the point in the XS file where we will call the shared library function. If we want, we can inspect the arguments that will be passed:

(gdb) p arg
$1 = 3.5

然后进入共享库:

(gdb) s
my_clib_function (arg=3.5) at mylib.c:5
5       if (arg > 0.0) {

依此类推。

这篇关于如何跟踪XS .so文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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