相关疑难解决方法(0)

怎么应该使用strace?

一位同事曾告诉我,当Linux上的所有内容都无法调试时,最后一个选项是使用strace.

我试图学习这个奇怪工具背后的科学,但我不是系统管理大师,我没有真正得到结果.

所以,

  • 究竟是什么,它做了什么?
  • 如何以及在何种情况下使用它?
  • 如何理解和处理输出?

简而言之,简单来说,这些东西是如何工作的?

linux debugging strace

266
推荐指数
8
解决办法
27万
查看次数

132
推荐指数
4
解决办法
10万
查看次数

78
推荐指数
6
解决办法
10万
查看次数

如何从用户空间访问系统调用?

我读了LKD 1中的一些段落, 我无法理解下面的内容:

从用户空间访问系统调用

通常,C库提供对系统调用的支持.用户应用程序可以从标准头中提取函数原型并与C库链接以使用您的系统调用(或者库例程,而该库例程又使用您的系统调用).但是,如果您刚刚编写了系统调用,那么glibc已经支持它是值得怀疑的!

值得庆幸的是,Linux提供了一组用于包装系统调用访问的宏.它设置寄存器内容并发出陷阱指令.这些宏被命名,其中介于0和6之间.该数字对应于传递给系统调用的参数数量,因为宏需要知道预期的参数数量,从而推入寄存器.例如,考虑系统调用,定义为_syscalln()nopen()

long open(const char *filename, int flags, int mode)
Run Code Online (Sandbox Code Playgroud)

在没有显式库支持的情况下使用此系统调用的syscall宏将是

#define __NR_open 5
_syscall3(long, open, const char *, filename, int, flags, int, mode)
Run Code Online (Sandbox Code Playgroud)

然后,应用程序可以简单地调用open().

对于每个宏,有2 + 2×n个参数.第一个参数对应于系统调用的返回类型.第二个是系统调用的名称.接下来是系统调用顺序的每个参数的类型和名称.的__NR_open定义是在<asm/unistd.h>; 它是系统呼叫号码.的_syscall3宏扩展到与联汇编C函数; 程序集执行上一节中讨论的步骤,将系统调用号和参数推送到正确的寄存器中,并发出软件中断以陷入内核.将此宏放在应用程序中是使用open()系统调用所需的全部内容.

让我们编写宏来使用我们精彩的新foo()系统调用,然后编写一些测试代码来展示我们的努力.

#define __NR_foo 283
__syscall0(long, foo)

int main ()
{
        long stack_size;

        stack_size = foo ();
        printf ("The kernel stack size is %ld\n", stack_size);
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

是什么 …

linux system-calls

17
推荐指数
2
解决办法
2万
查看次数

GCC内联汇编:在intel x86_64上注册约束

这是寄存器加载代码列表:

a eax
b ebx
c ecx
d edx
S esi
D edi
I常数值(0到31)
q,r动态分配寄存器(见下文)
g eax,ebx,ecx,edx或内存中
的变量a eax和edx合并为64位整数(使用long longs)

但这是intel i386的注册限制.我的问题是我可以在哪里找到intel x86_64系统的寄存器限制,例如:

?%r10
?%r8
?%的RDX

等等.

assembly gcc x86-64 inline-assembly

15
推荐指数
2
解决办法
8901
查看次数

Linux系统调用表或汇编语言的cheetsheet

有谁知道在汇编语言中为Linux系统调用找到汇总表或备忘单的位置?我通过int 0x80指令调用Linux系统调用,我需要不时地引用哪个寄存器包含什么值.

谢谢.

c linux assembly

11
推荐指数
1
解决办法
1万
查看次数

在C/C++中使用内联汇编

我正在尝试使用内联汇编...我读过这个页面http://www.codeproject.com/KB/cpp/edujini_inline_asm.aspx但我无法理解传递给我的函数的参数.

我正在写一个C写的例子..这是我的函数头:

write2(char *str, int len){
}
Run Code Online (Sandbox Code Playgroud)

这是我的汇编代码:

global write2
write2:
    push ebp
    mov ebp, esp
    mov eax, 4      ;sys_write
    mov ebx, 1      ;stdout
    mov ecx, [ebp+8]    ;string pointer
    mov edx, [ebp+12]   ;string size
    int 0x80        ;syscall
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能将代码传递给C函数...我正在做这样的事情:

write2(char *str, int len){
    asm ( "movl 4, %%eax;"
          "movl 1, %%ebx;"
          "mov %1, %%ecx;"
          //"mov %2, %%edx;"
          "int 0x80;"
           :
           : "a" (str), "b" (len)
    );
}
Run Code Online (Sandbox Code Playgroud)

那是因为我没有输出变量,所以我该如何处理呢?此外,使用此代码:

global main
main:
    mov ebx, 5866       ;PID
    mov ecx, …
Run Code Online (Sandbox Code Playgroud)

c linux x86 assembly inline-assembly

9
推荐指数
1
解决办法
2万
查看次数

32位Linux上的Syscall或sysenter?

从MS-DOS开始,我知道使用中断的系统调用.在旧论文中,我看到了int 80h在Linux上调用系统函数的参考.由于现在相当长的一段时间,我知道int 80h不赞成使用该syscall指令.但我不能让它在我的32位机器上工作.

这个问题

syscall指令仅用于64位平台吗?不是32位Linux使用syscall

样品测试

在我的32位Linux(Ubuntu Precise)上,该程序终止于核心转储:

global _start

_start:
        mov     eax, 4                ; 4 is write
        mov     ebx, 1                ; 1 is stdout
        mov     ecx, message          ; address of string
        mov     edx, length           ; number of bytes
        syscall

        mov     eax, 1                ; 1 is exit
        xor     ebx, ebx              ; return code 0
        syscall

message:
        db  10,"Hello, World",10,10
length  equ $ - message
Run Code Online (Sandbox Code Playgroud)

我试过sysenter而不是syscall,但它以同样的方式崩溃.

linux assembly 32-bit system-calls sysenter

8
推荐指数
2
解决办法
6401
查看次数

FreeBSD 系统调用比 Linux 破坏更多的寄存器?内联汇编优化级别之间的不同行为

最近我在玩 freebsd 系统调用,我对 i386 部分没有问题,因为它在这里有很好的记录但是我找不到 x86_64 的相同文档。

我看到人们在 linux 上使用相同的方式,但他们只使用程序集而不是 c。我想在我的例子中,系统调用实际上改变了一些被高优化级别使用的寄存器,所以它给出了不同的行为。

/* for SYS_* constants */
#include <sys/syscall.h>

/* for types like size_t */
#include <unistd.h>

ssize_t sys_write(int fd, const void *data, size_t size){
    register long res __asm__("rax");
    register long arg0 __asm__("rdi") = fd;
    register long arg1 __asm__("rsi") = (long)data;
    register long arg2 __asm__("rdx") = size;
    __asm__ __volatile__(
        "syscall"
        : "=r" (res)
        : "0" (SYS_write), "r" (arg0), "r" (arg1), "r" (arg2)
        : "rcx", "r11", "memory"
    ); …
Run Code Online (Sandbox Code Playgroud)

c freebsd x86-64 system-calls inline-assembly

7
推荐指数
1
解决办法
259
查看次数

如何在 ARM GCC 内联汇编中指定单个寄存器作为约束?

在 x86 内联汇编中,我可以这样写:

asm ("cpuid"
            : "=a" (_eax),
              "=b" (_ebx),
              "=c" (_ecx),
              "=d" (_edx)
            : "a" (op));
Run Code Online (Sandbox Code Playgroud)

所以在 matchin 约束中,而不是只写“=r”并让编译器选择寄存器,我可以说我想使用哪个特定的寄存器(=a 例如使用 %eax)

我怎样才能为 ARM 程序集做到这一点?ARM GCC 汇编手册http://www.ethernut.de/en/documents/arm-inline-asm.html指出,例如,我可以将约束“r”用于通用寄存器 R0-R15“w”之一" 对于 VFP 浮点寄存器 S0-S31 之一

但是我怎样才能将一个操作数限制在例如 s1 呢?或特定的通用寄存器?

gcc arm inline-assembly

5
推荐指数
1
解决办法
3561
查看次数

标签 统计

assembly ×6

linux ×6

inline-assembly ×4

c ×3

system-calls ×3

x86-64 ×3

gcc ×2

x86 ×2

32-bit ×1

abi ×1

arm ×1

debugging ×1

freebsd ×1

strace ×1

sysenter ×1

unix ×1