1

我正在尝试用单声道编写 ac# 程序来获取有关 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 的调用发生的。奇怪的是,我不调用这个函数。

所以我现在处于死胡同,希望能得到你的帮助。

问候

4

0 回答 0