Home Operation and Maintenance Linux Operation and Maintenance Share an example of obtaining current stack information on Linux and Windows

Share an example of obtaining current stack information on Linux and Windows

Jun 29, 2017 pm 03:35 PM
linux windows

The following editor will bring you an article on how to obtain the current stack information on Linux and Windows. The editor thinks it is quite good, so I will share it with you now and give it as a reference for everyone. Let’s follow the editor and take a look.

When writing stable and reliable software services, output stack information is often used so that users/developers can obtain accurate running information. Commonly used in log output, error reporting, and anomaly detection.

There is a relatively simple function to obtain stack information in Linux:


#include <stdio.h>
#include <execinfo.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>


void handler(int sig) {
 void *array[5];
 size_t size;

 // get void*&#39;s for all entries on the stack
 size = backtrace(array, 5);

 // print out all the frames to stderr
 fprintf(stderr, "Error: signal %d:\n", sig);
 char** msgs = backtrace_symbols(array, size);
 for(int i=1;i<size && msgs[i];++i)
 printf("[%d] %s\n", i, msgs[i]);
 exit(1);
}

void baz() {
 int *foo = (int*)-1; // make a bad pointer
 printf("%d\n", *foo);  // causes segfault
}

void bar() { baz(); }
void foo() { bar(); }


int main(int argc, char **argv) {
 signal(SIGSEGV, handler); // install our handler
 foo(); // this will call foo, bar, and baz. baz segfaults.
}
Copy after login

The above code is from the reference Slightly modified from stackoverflow. The core are the two functions backtrace and backtrace_symbols.

It is recommended to use the open source code StackWalker under Windows, which supports X86, AMD64, and IA64.

If you need the simplest code, then the following is the code I extracted, which is obviously more complicated than Linux. (Many functions of Win are more complicated to implement, and of course there are many functions that are much simpler to implement than Linux.)

I will give some explanations later.


#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <DbgHelp.h>
#include <TlHelp32.h>

using namespace std;

HANDLE ph;

void baz()
{
 int* v = 0;
 *v = 0;
}
void bar()
{
 baz();
}

void foo(){
 try {
  bar();
 }
 except(EXCEPTION_EXECUTE_HANDLER) {
  auto sire = SymInitialize(ph, 0, FALSE);
  sire = SymSetOptions(SymGetOptions() | SYMOPT_LOAD_LINES | SYMOPT_FAIL_CRITICAL_ERRORS);
  CONTEXT ctx = { 0 };
  ctx.ContextFlags = CONTEXT_FULL;
  RtlCaptureContext(&ctx);
  STACKFRAME64 sf = { 0 };
 #ifdef _M_IX86 // ignore IA64
  auto imageType = IMAGE_FILE_MACHINE_I386;
  sf.AddrPC.Offset = ctx.Eip;
  sf.AddrPC.Mode = AddrModeFlat;
  sf.AddrFrame.Offset = ctx.Ebp;
  sf.AddrFrame.Mode = AddrModeFlat;
  sf.AddrStack.Offset = ctx.Esp;
  sf.AddrStack.Mode = AddrModeFlat;
 #elif _M_X64
  auto imageType = IMAGE_FILE_MACHINE_AMD64;
  sf.AddrPC.Offset = ctx.Rip;
  sf.AddrPC.Mode = AddrModeFlat;
  sf.AddrFrame.Offset = ctx.Rsp;
  sf.AddrFrame.Mode = AddrModeFlat;
  sf.AddrStack.Offset = ctx.Rsp;
  sf.AddrStack.Mode = AddrModeFlat;
 #endif

  MODULEENTRY32 me;
  auto snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
  auto info = Module32First(snap, &me);
  while (info) {
   auto dw = SymLoadModule64(ph, 0, me.szExePath, me.szModule, (DWORD64)me.modBaseAddr, me.modBaseSize);
   if (!Module32Next(snap, &me))break;
  }
  CloseHandle(snap);
  auto thread = GetCurrentThread();

  PIMAGEHLP_SYMBOL64 sym = (IMAGEHLP_SYMBOL64 *)malloc(sizeof(IMAGEHLP_SYMBOL64) + 100);
  if (!sym)
   return;
  memset(sym, 0, sizeof(IMAGEHLP_SYMBOL64) + 100);
  sym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
  sym->MaxNameLength = 100;

  IMAGEHLP_LINE64 line = { 0 };
  line.SizeOfStruct = sizeof(line);
  for (;;) {
   auto result = StackWalk(imageType, ph, thread, &sf, &ctx, 0, SymFunctionTableAccess64, SymGetModuleBase64, 0);
   if (result) {
    DWORD64 offset = 0;
    DWORD offset_for_line = 0;
    CHAR und_fullname[100];

    if (sf.AddrPC.Offset != 0) {
     if (SymGetSymFromAddr64(ph, sf.AddrPC.Offset, &offset, sym)) {
      UnDecorateSymbolName(sym->Name, und_fullname, 100, UNDNAME_COMPLETE);
      cout << und_fullname;
     }

     if (SymGetLineFromAddr64(ph, sf.AddrPC.Offset, &offset_for_line, &line)) {
      cout << " " << line.FileName << "(" << line.LineNumber << ")";
     }
     cout << endl;
    }
   }
   else
    break;
  }
  SymCleanup(ph);
 }
}
int main()
{
 ph = GetCurrentProcess();
 foo();
 return 0;
}
Copy after login

Please link dbghelp.lib for compilation

The core is StackWalk and SymGetSymFromAddr64, SymGetLineFromAddr64.

StackWalk is used to get the next layer of stack.

SymGetSymFromAddr64 is used to get the current function name.

SymGetLineFromAddr64 is used to obtain the file and line number of the function.

In order for these three functions to work properly, it is necessary to initialize the symbol-related functions (SymInitialize), obtain the current thread description table (RtlCaptureContext), and load the used module (SymLoadModule64).

The two header files are used.

After the above code is executed, stack information will be output on the console.

The above is the detailed content of Share an example of obtaining current stack information on Linux and Windows. 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

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.

Undress AI Tool

Undress AI Tool

Undress images for free

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)

Linux Architecture: Unveiling the 5 Basic Components Linux Architecture: Unveiling the 5 Basic Components Apr 20, 2025 am 12:04 AM

The five basic components of the Linux system are: 1. Kernel, 2. System library, 3. System utilities, 4. Graphical user interface, 5. Applications. The kernel manages hardware resources, the system library provides precompiled functions, system utilities are used for system management, the GUI provides visual interaction, and applications use these components to implement functions.

What computer configuration is required for vscode What computer configuration is required for vscode Apr 15, 2025 pm 09:48 PM

VS Code system requirements: Operating system: Windows 10 and above, macOS 10.12 and above, Linux distribution processor: minimum 1.6 GHz, recommended 2.0 GHz and above memory: minimum 512 MB, recommended 4 GB and above storage space: minimum 250 MB, recommended 1 GB and above other requirements: stable network connection, Xorg/Wayland (Linux)

How to run java code in notepad How to run java code in notepad Apr 16, 2025 pm 07:39 PM

Although Notepad cannot run Java code directly, it can be achieved by using other tools: using the command line compiler (javac) to generate a bytecode file (filename.class). Use the Java interpreter (java) to interpret bytecode, execute the code, and output the result.

How to check the warehouse address of git How to check the warehouse address of git Apr 17, 2025 pm 01:54 PM

To view the Git repository address, perform the following steps: 1. Open the command line and navigate to the repository directory; 2. Run the "git remote -v" command; 3. View the repository name in the output and its corresponding address.

Where to write code in vscode Where to write code in vscode Apr 15, 2025 pm 09:54 PM

Writing code in Visual Studio Code (VSCode) is simple and easy to use. Just install VSCode, create a project, select a language, create a file, write code, save and run it. The advantages of VSCode include cross-platform, free and open source, powerful features, rich extensions, and lightweight and fast.

vscode terminal usage tutorial vscode terminal usage tutorial Apr 15, 2025 pm 10:09 PM

vscode built-in terminal is a development tool that allows running commands and scripts within the editor to simplify the development process. How to use vscode terminal: Open the terminal with the shortcut key (Ctrl/Cmd). Enter a command or run the script. Use hotkeys (such as Ctrl L to clear the terminal). Change the working directory (such as the cd command). Advanced features include debug mode, automatic code snippet completion, and interactive command history.

How to use VSCode How to use VSCode Apr 15, 2025 pm 11:21 PM

Visual Studio Code (VSCode) is a cross-platform, open source and free code editor developed by Microsoft. It is known for its lightweight, scalability and support for a wide range of programming languages. To install VSCode, please visit the official website to download and run the installer. When using VSCode, you can create new projects, edit code, debug code, navigate projects, expand VSCode, and manage settings. VSCode is available for Windows, macOS, and Linux, supports multiple programming languages ​​and provides various extensions through Marketplace. Its advantages include lightweight, scalability, extensive language support, rich features and version

laravel installation code laravel installation code Apr 18, 2025 pm 12:30 PM

To install Laravel, follow these steps in sequence: Install Composer (for macOS/Linux and Windows) Install Laravel Installer Create a new project Start Service Access Application (URL: http://127.0.0.1:8000) Set up the database connection (if required)

See all articles