- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试在 NASM/x86 程序集中使用 sys_brk 分配一些内存。 sys_break返回break的新地址,这是数据段的末尾,对吧?那么我新分配的内存驻留在哪里?我假设它位于旧中断值和新中断值之间。因此,如果我使用 sys_brk 分配 64 字节内存,我可以使用从调用 sys_brk 之前存储的旧中断值开始的接下来的 64 字节。我说得对吗?
我分配内存的汇编代码看起来有点像这样。 https://gist.github.com/nikAizuddin/f4132721126257ec4345
另一个附带问题是;
我应该在 Assembly 中编写一个函数,该函数返回指向动态分配的内存的指针,并且该函数将从 C 程序中调用。我如何从程序的 C 端释放这 block 内存?只需调用 free() 就足够了吗?
最佳答案
brk(2)
手册页(部分:C 库/内核 ABI 差异)描述了如何在 Linux 系统调用之上实现 glibc 包装器,成功时返回新的 brk,失败时返回旧的 brk。
据我了解,当前中断之后的内存未映射。当前中断下方的地址是数据段的一部分(在数据+bss+堆的意义上)。文档并不清楚中断是否必须页面对齐。 (即,您可以使用 sbrk(64),还是只能使用 sbrk(4096)?)如果启用了 ASLR,则初始中断将是经过 BSS 末尾的某个随机距离。
参见:What does the brk() system call do?该问题的答案有 an example of using sbrk to replace malloc for code-golf 。所以是的,旧的中断是要返回的地址。显然,您可以 sbrk
任何您想要的增量,而不仅仅是页面。
您是编写内存分配器的人。 sbrk
只是让您从操作系统中获得更多信息,如 mmap(MAP_ANONYMOUS)
但灵 active 较差。 它不能帮助您跟踪空闲 block ,因此您可以将它们用于将来的分配,而不是总是从操作系统获取更多。
返回通过 sbrk
获得的内存的方法是使用负参数调用 sbrk
。显然,这需要后进先出的使用模式,这就是为什么 glibc 的 malloc 仅使用 sbrk 进行小型分配(释放时可以放入空闲列表,以供将来的 malloc 分发)。大的分配最好立即返回到操作系统,而不是保持映射,因此 glibc 的 malloc 使用 mmap
来实现这些分配。
永远不要对不是从 malloc(3)
获取的内存(或相关函数,如 strdup(3)
,在文档中说明您可以并且应该 free(3)
内存)调用 free(3)
。)不知道如果您在程序中断下方的内存页上调用 munmap
会发生什么。也许它会起作用,但是如果中断减少到那里,您的数据段中就会有一个漏洞,可能会导致问题。
在汇编中,Linux brk
系统调用采用要设置中断的地址。 如 the man page notes ,它要么返回成功,要么返回失败时的旧中断,而不是像 -ENOMEM
这样的 -errno
代码。
参见 Assembly x86 brk() call use 以 x86-64 为例。
可以使用正整数或负整数偏移量的 POSIX API 可以通过始终调用两次来实现,或者像 glibc 一样跟踪全局变量中的当前中断。要初始化该变量,请使用 brk
一次并请求地址 0
,这将失败,如下面的 strace 输出所示。
这与使用 POSIX API 执行的操作类似,使用 increment = 0
调用 sbrk
。
这就是 glibc 的 malloc(3)
内部所做的事情:
$ strace -e brk ls 2>&1 | m
brk(0) = 0x650000
brk(0) = 0x650000
brk(0x671000) = 0x671000
brk 手册页提到了 end(3)
。显然,全局变量位于文本、数据和 bss 段的末尾。然而,&end
只是“接近”程序中断,这就是为什么malloc仍然需要进行系统调用来获得初始中断。我不知道为什么会有多余的 brk(0)
。这些是原始系统调用,而不是库函数调用,因此 sbrk(0)
可能无法解释它。
关于linux - 当我使用 brk 系统调用时,我分配的内存实际上从哪里开始,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32885127/
自从升级 NodeJs 以来,我从 Visual Studio 2017 运行 Nodejs 时遇到此错误。 断点也不起作用。有任何解决这个问题的方法吗? 注意:VS版本是15.5.6NodeJS 版
我已经使用 VS 2015 在我的计算机上安装了 nodeJs 并进行了设置。当我尝试运行示例 hello world 应用程序时,它抛出以下错误: verb(node:14096) [DEP0062
当我在 Visual Studio 中运行 Node.js 应用程序时,我收到以下消息:DeprecationWarning: 'node --debug' 和 'node --debug-brk'
根据Linux程序员手册: brk() and sbrk() change the location of the program break, whichdefines the end of the
据我所知,在 brk() 系统调用之后,额外的虚拟内存尚未分配(即页表尚未增长以容纳新的虚拟地址)。我的印象是这些页表被添加为 那么...为什么您需要 brk() 系统调用?为什么内核不能在内存访问进
这是 strace -T -ttt -ff -x -y -o pid.trace -p 2145 的输出。跟踪如下。 1503431273.934716 semop(1204093022, {{0,
我写了一个基本的自定义内存管理分配器,它会获取一 block 内存,预先创建 X 对象,这样每当我需要“创建”一个对象时,我就可以获取一个预先创建的对象并简单地分配数据成员(内存已经分配)。 我使用了
我正在尝试将内存动态分配到堆中,然后在这些内存地址中分配值。我了解如何分配内存,但我如何将例如寄存器中的值分配给第一个动态内存地址? 这是我到目前为止: push rbp mov rb
我正在尝试将内存动态分配到堆中,然后在这些内存地址中分配值。我了解如何分配内存,但我如何将寄存器中的值分配给第一个动态内存地址?这是我目前所拥有的: push rbp mov rbp,
我想知道在内核源代码版本 >= 2.6 中定义了 brk。那是哪个c文件包含它的定义? grep 并没有透露太多。另外 sbrk 是在 glibc 中实现的吗? 最佳答案 它在 mmap.c 中。寻找
我正在尝试在 NASM/x86 程序集中使用 sys_brk 分配一些内存。 sys_break返回break的新地址,这是数据段的末尾,对吧?那么我新分配的内存驻留在哪里?我假设它位于旧中断值和新中
不使用brk是否可以实现malloc库函数?我可以使用 sbrk(0) 找出程序中断的当前位置,然后使用 sbrk(size) 对其进行递增吗? 如果是,那么为什么首先要添加 brk? 最佳答案 br
有人可以解释为什么这个“无休止的”循环会很快出现段错误吗?例如,假设我们有这个功能: #!/bin/bash foo() { foo }; foo 8-10 秒后出现段错误。通过 strace 检
我在很多地方(musl 邮件列表、macOS 论坛等)听说 brk() 和 sbrk() 是不安全的。这些地方很多要么根本不解释,要么解释的很模糊。例如,this链接指出“这些功能从根本上被破坏了”,
虽然我知道 Unix 系统调用 brk 和函数 sbrk 的作用,但我不知道它们代表什么。谁能赐教一下? 最佳答案 它来自于“破值”。 我引用:“更改是通过重置进程的中断值并分配适当的空间量来进行的。
我是新手,任何人都可以通过一个简短的例子说出 brk 和 sbrk 之间的确切区别吗?有没有效率因素可以从两者中选择任何一个?malloc 和 new 内部调用 brk 或 sbrk。 最佳答案 in
我编写了一个小的 hello world 程序,并在其二进制文件上运行 strace,它列出了所有在我的 Hello_world 程序执行过程中调用的系统调用。 strace ./a.out exec
我发现并研究了x86 memory access segmentation fault它在我的代码中不起作用。区别可能在于我不使用单独的 .text 和 .data 段,而是通过创建自定义 ELF h
我正在尝试通过简单的脚本使用 Node 检查器。我有一些控制台日志,因此我可以判断它是否正在运行。我尝试了两种方法: Node 调试 test.js 通过这种方法,调试器在 Chrome 中打开,但不
我正在使用 Node v6.10.0 并试图弄清楚为什么我的 --debug-brk 如此缓慢。如果没有此标志(仅使用 --inspect 或 --debug),它几乎是瞬时的,尽管调试器仍然需要很长
我是一名优秀的程序员,十分优秀!