使用liblvm2app.so

时间:2016-01-13 14:58:40

标签: mono pinvoke rhel lvm

我正在尝试用单声道编写一个c#程序来获取有关vgs(卷组),lvs(逻辑卷)和pvs(物理卷)的信息。 我正在使用centOS7系统。 要获取有关lvm的信息,请定义API(https://sourceware.org/git/?p=lvm2.git;a=blob;f=liblvm/lvm2app.h)。 c ++中的示例程序与上面链接的API完美配合(https://www.redhat.com/archives/lvm-devel/2010-September/msg00025.html)。 但是我遇到了麻烦,使用pinvoke从我的c#程序中调用API。

我已设法获取版本数据。 因此,我假设,可以对库进行调整。

lvm2app.h

包装类:

public class liblvm2wrapper
{
    [DllImport ("liblvm2app.so")]
    public static extern IntPtr lvm_init (IntPtr system_dir);

    [DllImport ("liblvm2app.so")]
    public static extern IntPtr lvm_errmsg (IntPtr libh);

    [DllImport ("liblvm2app.so", CharSet = CharSet.Ansi)]
    public static extern IntPtr lvm_library_get_version ();

    [DllImport ("liblvm2app.so", CharSet = CharSet.Ansi)]
    public static extern IntPtr lvm_vg_open(IntPtr libh, [MarshalAs (UnmanagedType.LPStr)]string vgname, [MarshalAs (UnmanagedType.LPStr)]string mode, int flags);

    [DllImport ("liblvm2app.so")]
    public static extern void lvm_quit (IntPtr libh);
}

主要

class Program
{
    static void Main(string[] args)
    {
          IntPtr lvmHandle = liblvm2.lvm_init(IntPtr.Zero);
          if(lvmHandle == IntPtr.Zero) return;

          IntPtr versionPtr = liblvm2wrapper.lvm_library_get_version();
          string version = Marshal.PtrToStringAnsi(versionPtr); // works

          // segFault occurs at the next line of code, if the name describes an existing vg
          // bash: line 1: 43812 Segmentation fault (core dumped) '/usr/bin/mono' --debug --debugger-agent=transport=dt_socket,address=127.0.0.1:51779 "home/user/Documents/test/bin/x64/Debug/test.exe"
          IntPtr vgHandle = liblvm2wrapper.lvm_vg_open(lvmHandle , "volume_group", "r", 0); 
          if(vgHandle == IntPtr.Zero)
          {
              // if the string ("volume_group") passed to the function lvm_vg_open does not describe ane existing volume group, an empty pointer is returned and a valid error message is obtained calling the function below (lvm_errmsg)
              Console.WriteLine(Marshal.PtrToStringAnsi(liblvm2wrapper.lvm_errmsg(lvmHandle)));
          }
          liblvm2wrapper.lvm_quit(lvmHandle);
    }
}

从我所听到的,应该使用gdb来分析分段错误。 我按照http://pastebin.com/Kza9kemJ中的示例(不能发布第三个链接,因为这是一个新帐户。

并获得以下输出:

[root@vm user]# gdb --args mono '/home/user/Documents/test/bin/x64/Debug/test.exe' 
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-64.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/bin/mono-sgen...(no debugging symbols found)...done.
warning: File "/usr/bin/mono-sgen-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load:/usr/bin/mono-gdb.py".
To enable execution of this file add
    add-auto-load-safe-path /usr/bin/mono-sgen-gdb.py
line to your configuration file "/root/.gdbinit".
To completely disable this security protection add
    set auto-load safe-path /
line to your configuration file "/root/.gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual.  E.g., run from the shell:
    info "(gdb)Auto-loading safe path"
(gdb) r
Starting program: /usr/bin/mono /home/user/Documents/test/bin/x64/Debug/test.exe
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7fffee916700 (LWP 43646)]
2.02.130(2)-RHEL7 (2015-10-14)
[Thread 0x7fffee916700 (LWP 43646) exited]
[Inferior 1 (process 43645) exited normally]
Program received signal SIGSEGV, Segmentation fault.
0x00007fffee3fda0c in lvm_lv_get_name () from /lib64/liblvm2app.so
(gdb) bt
#0  0x00007fffee3fda0c in lvm_lv_get_name () from /lib64/liblvm2app.so
#1  0x00000000400164e0 in ?? ()
#2  0x0000000000b22d18 in ?? ()
#3  0x00007ffff000b378 in ?? ()
#4  0x0000000000000000 in ?? ()
(gdb) info sharedlibrary liblvm2app.so
From                To                  Syms Read   Shared Object Library
0x00007fffee3fcc20  0x00007fffee4a02c8  Yes (*)     /lib64/liblvm2app.so
(*): Shared library is missing debugging information.
(gdb) info register
rax            0x0  0
rbx            0xb22d70 11677040
rcx            0xa12590 10560912
rdx            0x0  0
rsi            0x7ffff000bae8   140737219967720
rdi            0xb22d70 11677040
rbp            0x7fffffffdbb0   0x7fffffffdbb0
rsp            0x7fffffffda80   0x7fffffffda80
r8             0x0  0
r9             0xaabc   43708
r10            0x7ffff72947b8   140737340065720
r11            0x7fffee3fd9f0   140737190550000
r12            0x7ffff000b378   140737219965816
r13            0x0  0
r14            0x7fffffffdf10   140737488346896
r15            0xb22d70 11677040
rip            0x7fffee3fda0c   0x7fffee3fda0c <lvm_lv_get_name+28>
eflags         0x10246  [ PF ZF IF RF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0
---Type <return> to continue, or q <return> to quit---
gs             0x0  0
(gdb) info frame
Stack level 0, frame at 0x7fffffffdaa0:
 rip = 0x7fffee3fda0c in lvm_lv_get_name; saved rip 0x400164e0
 called by frame at 0x7fffffffdaa8
 Arglist at 0x7fffffffda78, args: 
 Locals at 0x7fffffffda78, Previous frame's sp is 0x7fffffffdaa0
 Saved registers:
  rbx at 0x7fffffffda90, rip at 0x7fffffffda98
(gdb) 

从这个输出可能的结论是,通过调用函数lvm_lv_get_name发生分段错误。 奇怪的是,我不称这个功能。

所以我现在处于死胡同,非常感谢你的帮助。

问候

0 个答案:

没有答案