c - 如何在 C/C++ 中写入不同线程的堆栈?

标签 c multithreading assembly stack shared-memory

我知道这是个坏主意!当然,为了安全编程,给定线程的堆栈应该被认为是该线程私有(private)的。但是 POSIX 至少保证一个线程的所有内存都由其他线程共享和写入,这意味着一个线程的堆栈可以(理论上)由另一个线程写入。所以我很好奇如何做到这一点。

我能想到的唯一方法是将线程 B 中的局部变量地址传递给线程 A,然后让 A 开始写入该一般区域。但这并不能完全模拟 C 中的函数调用。特别是我很好奇是否可以说,让线程 A sleep ,而它的程序计数器设置为某个接受参数的函数的第一行,然后在线程 B 上实际上将这些参数压入堆栈,然后恢复线程 A 并让它执行,就好像该函数最初是在线程 A 中使用这些参数调用的一样。我认为这需要线程 B 至少能够在 x86 调用约定下访问线程 A 的寄存器,我不确定这是否可能。

最佳答案

好的,访问线程堆栈的一种方法是自己分配堆栈内存并在创建线程时分配它。这可以通过 pthread_attr_setstack() 来实现称呼。

以下代码将线程堆栈设置为手动分配的内存(此处为 malloc),而不是系统分配的。稍后您可以在创建线程后访问 mystack 指针。此类代码的一个用例是,您可以转储线程堆栈以获取其快照,稍后您可以恢复该线程。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <limits.h>

   void *thread(void *arg) {
      char *ret;
      printf("thread() entered with argument '%s'\n", (char *)arg);
      if ((ret = (char*) malloc(20)) == NULL) {
        perror("malloc() error");
        exit(2);
      }
      strcpy(ret, "This is a test");
      pthread_exit(ret);
    }

    int main(void)
    {
       pthread_attr_t attr;
       int              rc;

      pthread_t thid;
      void *ret;

       void  *mystack;
       size_t mystacksize = 2 * PTHREAD_STACK_MIN;

       if (pthread_attr_init(&attr) == -1) {
          exit(1);
       }

       /* Get a big enough stack and align it on 4K boundary. */
       mystack = malloc(PTHREAD_STACK_MIN * 3);
       if (mystack != NULL) {
          printf("Using PTHREAD_STACK_MIN to align stackaddr %x.\n", mystack);
          mystack = (void *)((((long)mystack + (PTHREAD_STACK_MIN - 1)) /
                              PTHREAD_STACK_MIN) * PTHREAD_STACK_MIN);
       } else {
          exit(2);
       }

       printf("Setting stackaddr to %x\n", mystack);
       printf("Setting stacksize to %x\n", mystacksize);
       rc = pthread_attr_setstack(&attr, mystack, mystacksize);
       if (rc != 0) {
          printf("pthread_attr_setstack returned: %d\n", rc);
          exit(3);
       } else {
          printf("Set stackaddr to %x\n", mystack);
          printf("Set stacksize to %x\n", mystacksize);
       }


      if (pthread_create(&thid, &attr, thread, "thread 1") != 0) {
        exit(1);
      }

      if (pthread_join(thid, &ret) != 0) {
        exit(3);
      }

      printf("thread exited with '%s'\n", ret);
       rc = pthread_attr_destroy(&attr);
       if (rc != 0) {
          exit(5);
       }

       exit(0);
    }

让我们知道这是否是您想要的。抱歉缩进和编码风格不好。

关于c - 如何在 C/C++ 中写入不同线程的堆栈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1647130/

相关文章:

c - 尝试读取段错误,直到在 C 中遇到 header

c++ - 如何在 PBC 中存储序列化元素?

c - 为什么结构占用的空间比它需要的多?

java - 如何在 java 中运行一个线程,让我知道另一个线程何时死亡?

c - STRB 有效,除非目标地址发生移位

Java Swing 应用程序卡住

java - 具有等待和通知的 3 个线程的死锁行为

c# - 如何在 C# 中为枚举类型应用 InterLocked.Exchange?

assembly - 我应该如何使用英特尔的文档获取与 x86 中的 `ModeR/M` 指令相对应的 `call dword ptr` 字节?

assembly - XOR是MIPS中的伪命令吗?