国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Table of Contents
問題內(nèi)容
解決方法
Home Backend Development Golang Golang+CGO using ucontext crashes (intentionally) with SIGSEGV or SIGTRAP when using different stacks

Golang+CGO using ucontext crashes (intentionally) with SIGSEGV or SIGTRAP when using different stacks

Feb 09, 2024 pm 12:15 PM
stack overflow

使用 ucontext 的 Golang+CGO 在使用不同堆棧時(shí)因 SIGSEGV 或 SIGTRAP 崩潰(故意)崩潰

php小編新一為您介紹一種使用ucontext的Golang+CGO技術(shù),該技術(shù)在切換不同堆棧時(shí)可能會(huì)因?yàn)镾IGSEGV或SIGTRAP而導(dǎo)致崩潰。這種崩潰是故意造成的,通過這種方式可以更好地理解和調(diào)試程序中的問題。本文將詳細(xì)介紹如何利用ucontext和Golang+CGO技術(shù)進(jìn)行堆棧切換,并對(duì)可能出現(xiàn)的崩潰進(jìn)行分析和解決。無論您是初學(xué)者還是有一定經(jīng)驗(yàn)的開發(fā)者,相信這篇文章都會(huì)對(duì)您有所幫助。

問題內(nèi)容

我目前正在編寫Golang + CGO程序,并將在CGO中使用posix ucontext。由于我所有的核心邏輯都將在ucontext的bind函數(shù)中,所以我們應(yīng)該捕獲所有錯(cuò)誤的代碼。我通過訪問空指針來測(cè)試它,這給了我完全不同的行為,所有這些行為都取決于 ucontext 使用的堆棧位置。以下是帶有簡化示例的更多詳細(xì)信息。

如果我在線程的堆棧上分配ucontext堆棧,它將觸發(fā)SIGSEGV。但如果我在堆上分配它,它會(huì)首先觸發(fā) SIGSEGV,然后在調(diào)用 morestack_noctxt 時(shí)觸發(fā) SIGTRAP,然后再調(diào)用 runtime.sigpanic。我該如何解決這個(gè)問題或者如何獲取 SIGSEGV?為什么需要morestack?

以下均為詳細(xì)信息,任何建議或意見將不勝感激。謝謝!

崩潰(使用 malloc 堆棧):

<code>fatal: morestack on g0
SIGTRAP: trace trap
PC=0x45f342 m=0 sigcode=128
signal arrived during cgo execution

goroutine 1 [syscall]:
runtime.cgocall(0x464870, 0xc000067f60)
    /usr/local/go/src/runtime/cgocall.go:157 +0x5c fp=0xc000067f38 sp=0xc000067f00 pc=0x40465c
main._Cfunc_core_logic()
    _cgo_gotypes.go:39 +0x45 fp=0xc000067f60 sp=0xc000067f38 pc=0x4646e5
main.coreLogic()
    /container_share/works/badstack/main.go:46 +0x17 fp=0xc000067f70 sp=0xc000067f60 pc=0x464737
main.main()
    /container_share/works/badstack/main.go:51 +0x17 fp=0xc000067f80 sp=0xc000067f70 pc=0x464777
runtime.main()
    /usr/local/go/src/runtime/proc.go:250 +0x1d3 fp=0xc000067fe0 sp=0xc000067f80 pc=0x436913
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc000067fe8 sp=0xc000067fe0 pc=0x45f4a1

goroutine 2 [force gc (idle)]:
runtime.gopark(0x47a860, 0x6cb4d0, 0x11, 0x14, 0x1)
    /usr/local/go/src/runtime/proc.go:381 +0xfd fp=0xc000054f88 sp=0xc000054f58 pc=0x436dbd
runtime.goparkunlock(0x0?, 0x0?, 0x0?, 0x0?)
    /usr/local/go/src/runtime/proc.go:387 +0x2a fp=0xc000054fb8 sp=0xc000054f88 pc=0x436e4a
runtime.forcegchelper()
    /usr/local/go/src/runtime/proc.go:305 +0xb0 fp=0xc000054fe0 sp=0xc000054fb8 pc=0x436b90
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc000054fe8 sp=0xc000054fe0 pc=0x45f4a1
created by runtime.init.6
    /usr/local/go/src/runtime/proc.go:293 +0x25

goroutine 3 [GC sweep wait]:
runtime.gopark(0x47a860, 0x6cb640, 0xc, 0x14, 0x1)
    /usr/local/go/src/runtime/proc.go:381 +0xfd fp=0xc000055758 sp=0xc000055728 pc=0x436dbd
runtime.goparkunlock(0x0?, 0x0?, 0x0?, 0x0?)
    /usr/local/go/src/runtime/proc.go:387 +0x2a fp=0xc000055788 sp=0xc000055758 pc=0x436e4a
runtime.bgsweep(0x0?)
    /usr/local/go/src/runtime/mgcsweep.go:278 +0x98 fp=0xc0000557c8 sp=0xc000055788 pc=0x421998
runtime.gcenable.func1()
    /usr/local/go/src/runtime/mgc.go:178 +0x26 fp=0xc0000557e0 sp=0xc0000557c8 pc=0x415f66
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc0000557e8 sp=0xc0000557e0 pc=0x45f4a1
created by runtime.gcenable
    /usr/local/go/src/runtime/mgc.go:178 +0x6b

goroutine 4 [GC scavenge wait]:
runtime.gopark(0x47a860, 0x6cb6c0, 0xd, 0x14, 0x2)
    /usr/local/go/src/runtime/proc.go:381 +0xfd fp=0xc000055f48 sp=0xc000055f18 pc=0x436dbd
runtime.goparkunlock(0x47ca80?, 0x1?, 0x0?, 0x0?)
    /usr/local/go/src/runtime/proc.go:387 +0x2a fp=0xc000055f78 sp=0xc000055f48 pc=0x436e4a
runtime.(*scavengerState).park(0x6cb6c0)
    /usr/local/go/src/runtime/mgcscavenge.go:400 +0x4b fp=0xc000055fa0 sp=0xc000055f78 pc=0x41f44b
runtime.bgscavenge(0x0?)
    /usr/local/go/src/runtime/mgcscavenge.go:628 +0x45 fp=0xc000055fc8 sp=0xc000055fa0 pc=0x41fa25
runtime.gcenable.func2()
    /usr/local/go/src/runtime/mgc.go:179 +0x26 fp=0xc000055fe0 sp=0xc000055fc8 pc=0x415f06
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc000055fe8 sp=0xc000055fe0 pc=0x45f4a1
created by runtime.gcenable
    /usr/local/go/src/runtime/mgc.go:179 +0xaa

rax    0x17
rbx    0x476413
rcx    0x460c95
rdx    0x17
rdi    0x2
rsi    0x476413
rbp    0x7f18906b3ff0
rsp    0x7f18906b3fd8
r8     0xffffffff
r9     0x0
r10    0x8
r11    0x246
r12    0xc000067c70
r13    0x0
r14    0x6cb760
r15    0x0
rip    0x45f342
rflags 0x206
cs     0x33
fs     0x0
gs     0x0
</code>

崩潰(線程堆棧):

<code>fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x4647a0]

runtime stack:
runtime.throw({0x479118?, 0xffffffffffffffff?})
    /usr/local/go/src/runtime/panic.go:1047 +0x5d fp=0x7fff293551f0 sp=0x7fff293551c0 pc=0x43417d
runtime.sigpanic()
    /usr/local/go/src/runtime/signal_unix.go:825 +0x285 fp=0x7fff29355220 sp=0x7fff293551f0 pc=0x4495a5

goroutine 1 [syscall]:
runtime.cgocall(0x464890, 0xc000067f60)
    /usr/local/go/src/runtime/cgocall.go:157 +0x5c fp=0xc000067f38 sp=0xc000067f00 pc=0x40465c
main._Cfunc_core_logic()
    _cgo_gotypes.go:39 +0x45 fp=0xc000067f60 sp=0xc000067f38 pc=0x4646e5
main.coreLogic()
    /container_share/works/badstack/main.go:46 +0x17 fp=0xc000067f70 sp=0xc000067f60 pc=0x464737
main.main()
    /container_share/works/badstack/main.go:51 +0x17 fp=0xc000067f80 sp=0xc000067f70 pc=0x464777
runtime.main()
    /usr/local/go/src/runtime/proc.go:250 +0x1d3 fp=0xc000067fe0 sp=0xc000067f80 pc=0x436913
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc000067fe8 sp=0xc000067fe0 pc=0x45f4a1

goroutine 2 [force gc (idle)]:
runtime.gopark(0x47a880, 0x6cb4d0, 0x11, 0x14, 0x1)
    /usr/local/go/src/runtime/proc.go:381 +0xfd fp=0xc000054f88 sp=0xc000054f58 pc=0x436dbd
runtime.goparkunlock(0x0?, 0x0?, 0x0?, 0x0?)
    /usr/local/go/src/runtime/proc.go:387 +0x2a fp=0xc000054fb8 sp=0xc000054f88 pc=0x436e4a
runtime.forcegchelper()
    /usr/local/go/src/runtime/proc.go:305 +0xb0 fp=0xc000054fe0 sp=0xc000054fb8 pc=0x436b90
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc000054fe8 sp=0xc000054fe0 pc=0x45f4a1
created by runtime.init.6
    /usr/local/go/src/runtime/proc.go:293 +0x25

goroutine 3 [GC sweep wait]:
runtime.gopark(0x47a880, 0x6cb640, 0xc, 0x14, 0x1)
    /usr/local/go/src/runtime/proc.go:381 +0xfd fp=0xc000055758 sp=0xc000055728 pc=0x436dbd
runtime.goparkunlock(0x0?, 0x0?, 0x0?, 0x0?)
    /usr/local/go/src/runtime/proc.go:387 +0x2a fp=0xc000055788 sp=0xc000055758 pc=0x436e4a
runtime.bgsweep(0x0?)
    /usr/local/go/src/runtime/mgcsweep.go:278 +0x98 fp=0xc0000557c8 sp=0xc000055788 pc=0x421998
runtime.gcenable.func1()
    /usr/local/go/src/runtime/mgc.go:178 +0x26 fp=0xc0000557e0 sp=0xc0000557c8 pc=0x415f66
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc0000557e8 sp=0xc0000557e0 pc=0x45f4a1
created by runtime.gcenable
    /usr/local/go/src/runtime/mgc.go:178 +0x6b

goroutine 4 [GC scavenge wait]:
runtime.gopark(0x47a880, 0x6cb6c0, 0xd, 0x14, 0x2)
    /usr/local/go/src/runtime/proc.go:381 +0xfd fp=0xc000055f48 sp=0xc000055f18 pc=0x436dbd
runtime.goparkunlock(0x47caa0?, 0x1?, 0x0?, 0x0?)
    /usr/local/go/src/runtime/proc.go:387 +0x2a fp=0xc000055f78 sp=0xc000055f48 pc=0x436e4a
runtime.(*scavengerState).park(0x6cb6c0)
    /usr/local/go/src/runtime/mgcscavenge.go:400 +0x4b fp=0xc000055fa0 sp=0xc000055f78 pc=0x41f44b
runtime.bgscavenge(0x0?)
    /usr/local/go/src/runtime/mgcscavenge.go:628 +0x45 fp=0xc000055fc8 sp=0xc000055fa0 pc=0x41fa25
runtime.gcenable.func2()
    /usr/local/go/src/runtime/mgc.go:179 +0x26 fp=0xc000055fe0 sp=0xc000055fc8 pc=0x415f06
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc000055fe8 sp=0xc000055fe0 pc=0x45f4a1
created by runtime.gcenable
    /usr/local/go/src/runtime/mgc.go:179 +0xaa
</code>

GDB(帶 malloc 堆棧):

這將調(diào)用runtime.morestack_noctxt,并最終得到badstack,因?yàn)樗挥趃0的堆棧上。

<code>(gdb) b runtime.sigpanic
Breakpoint 1 at 0x449320: file /usr/local/go/src/runtime/signal_unix.go, line 822.
(gdb) r
Starting program: /container_share/works/badstack/main
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7fffd05d3700 (LWP 213229)]
[New Thread 0x7fffcfdd2700 (LWP 213230)]
[New Thread 0x7fffcf5d1700 (LWP 213231)]
[New Thread 0x7fffcedd0700 (LWP 213232)]
[New Thread 0x7fffce58f700 (LWP 213233)]
[New Thread 0x7fffcdd8e700 (LWP 213234)]

Thread 1 "main" received signal SIGSEGV, Segmentation fault.
0x00000000004647a0 in core () at /container_share/works/badstack/main.go:18
18    *ptr = 1024;
(gdb) c
Continuing.

Thread 1 "main" hit Breakpoint 1, runtime.sigpanic () at /usr/local/go/src/runtime/signal_unix.go:822
822 func sigpanic() {
(gdb) p $rsp
$1 = (void *) 0x7fffcd58cfe8
(gdb) x/x $r14+0x10
0x6cb770 <runtime.g0+16>:   0xff7fed70
(gdb) c
Continuing.
fatal: morestack on g0
</code>

GDB(帶有線程堆棧):

這似乎一切都按預(yù)期進(jìn)行。

<code>(gdb) b runtime.sigpanic
Breakpoint 1 at 0x449320: file /usr/local/go/src/runtime/signal_unix.go, line 822.
(gdb) r
Starting program: /container_share/works/badstack/main
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7fffd05d3700 (LWP 214288)]
[New Thread 0x7fffcfdd2700 (LWP 214289)]
[New Thread 0x7fffcf5d1700 (LWP 214290)]
[New Thread 0x7fffcedd0700 (LWP 214291)]
[New Thread 0x7fffce5cf700 (LWP 214292)]

Thread 1 "main" received signal SIGSEGV, Segmentation fault.
0x00000000004647a0 in core () at /container_share/works/badstack/main.go:18
18    *ptr = 1024;
(gdb) c
Continuing.

Thread 1 "main" hit Breakpoint 1, runtime.sigpanic () at /usr/local/go/src/runtime/signal_unix.go:822
822 func sigpanic() {
(gdb) p $rsp
$1 = (void *) 0x7fffffffd8e8
(gdb) x/x $r14+0x10
0x6cb770 <runtime.g0+16>:   0xff7fed70
(gdb) c
Continuing.
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x4647a0]
</code>

環(huán)境:

? clang -v                                                                     
clang version 16.0.6 (Red Hat 16.0.6-2.module_el8+588+6f71ce7b)

? gcc -v                                                                       
gcc version 8.4.1 20200928 (Red Hat 8.4.1-1) (GCC)

? uname -a
Linux 6cc94b77abd7 6.4.16-orbstack-00103-g02b40eb69695 #1 SMP Wed Sep 13 10:13:30 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

復(fù)制者:

編譯: CC=clang CXX=clang++ CFLAGS="-g -O0" go build -gcflags="all=-N -l" main.go

package main

/*
#include <stdio.h>
#include <stddef.h>
#include <ucontext.h>
#include <stdlib.h>

static ucontext_t uctx_main, uctx_core;

void core()
{
  // core logic


  // trigger crash
  int* ptr = NULL;
  *ptr = 1024;
}

void core_logic()
{
  size_t size = 1024 * 1024;
  char stack[size]; // SIGSEGV
  //void* stack = malloc(size); // SIGTRAP

  if (getcontext(&uctx_core) == -1)
    printf("failed to getcontext");

  uctx_core.uc_stack.ss_sp = stack;
  uctx_core.uc_stack.ss_size = size;
  uctx_core.uc_link = &uctx_main;

  makecontext(&uctx_core, core, 0);

  if (swapcontext(&uctx_main, &uctx_core) == -1)
    printf("failed to swapcontext");

  printf("back\n");
}
*/
// #cgo CFLAGS: -g -O0
import "C"

func coreLogic() {
  C.core_logic()
}

func main() {
  // Call the C function from Go
  coreLogic()
}

這是我的猜測(cè),但似乎不正確:當(dāng)我使用堆堆棧時(shí),它被視為有堆棧溢出,并且應(yīng)該更多堆棧,但最終發(fā)現(xiàn)它是g0,然后是致命的。但看起來 goroutine 的堆棧比線程的堆棧低得多?

更新于2023年9月24日:

對(duì)于純 C 程序,無論我使用什么堆棧,它都會(huì)獲得 SIGSEGV。

<code>#include <stdio.h>
#include <stddef.h>
#include <ucontext.h>
#include <stdlib.h>

static ucontext_t uctx_main, uctx_core;

void core()
{
  // core logic


  // trigger crash
  int* ptr = NULL;
  *ptr = 1024;
}

void core_logic()
{
  size_t size = 100 * 1024 * 1024;
  //char stack[size]; // SIGSEGV
  void* stack = malloc(size); // SIGTRAP

  if (getcontext(&uctx_core) == -1)
    printf("failed to getcontext");

  uctx_core.uc_stack.ss_sp = stack;
  uctx_core.uc_stack.ss_size = size;
  uctx_core.uc_link = &uctx_main;

  makecontext(&uctx_core, core, 0);

  if (swapcontext(&uctx_main, &uctx_core) == -1)
    printf("failed to swapcontext");

  printf("back\n");
}

void coreLogic() {
  core_logic();
}

int main() {
  coreLogic();
  return 0;
}
</code>

解決方法

最后,我在 Go 團(tuán)隊(duì)成員的幫助下解決了這個(gè)問題,打開了一個(gè)問題 在 Golang 的 github 存儲(chǔ)庫中,如果您需要的話。

TL;DR:這是從 Go1.21 開始的錯(cuò)誤,應(yīng)該在 Go1.22 中修復(fù)。即使您使用 Go1.20,由于另一個(gè)錯(cuò)誤,您可能仍然面臨這個(gè)問題。如果有人需要的話,也許我稍后會(huì)發(fā)布更多詳細(xì)信息,或者您可以在我之前提到的問題中查看更多詳細(xì)信息。

The above is the detailed content of Golang+CGO using ucontext crashes (intentionally) with SIGSEGV or SIGTRAP when using different stacks. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

PHP Tutorial
1502
276
Spring Security 6: cors() is deprecated and marked for removal Spring Security 6: cors() is deprecated and marked for removal Feb 10, 2024 pm 11:45 PM

I have the following code: publicSecurityFilterChainsecurityFilterChain(HttpSecurityhttp)throwsException{returnhttp.httpBasic().disable().cors().and().csrf().disable().authorizeHttpRequests().requestMatchers("

Golang+CGO using ucontext crashes (intentionally) with SIGSEGV or SIGTRAP when using different stacks Golang+CGO using ucontext crashes (intentionally) with SIGSEGV or SIGTRAP when using different stacks Feb 09, 2024 pm 12:15 PM

I'm currently writing a Golang+CGO program and will be using posixucontext in CGO. Since all my core logic will be in ucontext's bind function, we should catch all errors in the code. I tested it by accessing a null pointer, which gave me completely different behavior, all depending on the stack location used by the ucontext. Below are more details with simplified examples. If I allocate the ucontext stack on the thread's stack, it triggers SIGSEGV. But if I allocate it on the heap, it triggers SIGSEGV first and then SIGT when morestack_noctxt is called

How to solve C++ runtime error: 'stack overflow'? How to solve C++ runtime error: 'stack overflow'? Aug 25, 2023 pm 10:00 PM

How to solve the C++ runtime error: 'stackoverflow' In a C++ program, when the recursion level is too deep or the memory used by the program exceeds the stack capacity, a runtime error "stackoverflow" will occur. When this error occurs, the program crashes, and it is difficult to identify the specific cause. This article will introduce some ways to solve 'stackoverflow' errors and provide some code examples. The main cause of the runtime error "stackoverflow" is that within the stack

Do C++ lambda expressions support recursion? Do C++ lambda expressions support recursion? Apr 17, 2024 pm 09:06 PM

Yes, C++ Lambda expressions can support recursion by using std::function: Use std::function to capture a reference to a Lambda expression. With a captured reference, a Lambda expression can call itself recursively.

Why does c++ crash when it starts executing? Why does c++ crash when it starts executing? Apr 22, 2024 pm 05:57 PM

Reasons for a C++ program to crash when starting include: missing required libraries or dependencies, uninitialized pointers or reference stack overflows, segfaults, operating system configuration issues, program errors, hardware issues

Recursive implementation of C++ functions: Comparative analysis of recursive and non-recursive algorithms? Recursive implementation of C++ functions: Comparative analysis of recursive and non-recursive algorithms? Apr 22, 2024 pm 03:18 PM

The recursive algorithm solves structured problems through function self-calling. The advantage is that it is simple and easy to understand, but the disadvantage is that it is less efficient and may cause stack overflow. The non-recursive algorithm avoids recursion by explicitly managing the stack data structure. The advantage is that it is more efficient and avoids the stack. Overflow, the disadvantage is that the code may be more complex. The choice of recursive or non-recursive depends on the problem and the specific constraints of the implementation.

What impact do C++ functions have on program performance? What impact do C++ functions have on program performance? Apr 12, 2024 am 09:39 AM

The impact of functions on C++ program performance includes function call overhead, local variable and object allocation overhead: Function call overhead: including stack frame allocation, parameter transfer and control transfer, which has a significant impact on small functions. Local variable and object allocation overhead: A large number of local variable or object creation and destruction can cause stack overflow and performance degradation.

What is the relationship between recursive calls and exception handling in Java functions? What is the relationship between recursive calls and exception handling in Java functions? May 03, 2024 pm 06:12 PM

Exception handling in recursive calls: Limiting recursion depth: Preventing stack overflow. Use exception handling: Use try-catch statements to handle exceptions. Tail recursion optimization: avoid stack overflow.

See all articles