【问题标题】:Microsoft Visual Studio 2019 cross compiling CMake library - works but seg faultsMicrosoft Visual Studio 2019 交叉编译 CMake 库 - 有效但出现段错误
【发布时间】:2020-05-17 13:45:26
【问题描述】:

我有 MS Visual Studio 2019 设置,带有一个 CMake 项目和一个配置,可以在我网络上的树莓派上进行交叉编译。

我正在尝试构建一个简单的库 (libmylib.so)。奇怪的是它可以工作,但最后会出现故障。该库已构建并且该库工作正常,但最后我得到“异常未处理 - 分段错误”。所以我的设置显然有问题,只是不确定是什么。

这里是 CMakeLists.txt

# Root CMakeLists.txt
cmake_minimum_required (VERSION 3.8)

project ("native-test")

# Include sub-projects.
add_subdirectory("libmylib")
# libmylib\CMakeLists.txt
cmake_minimum_required (VERSION 3.8)

project("mylib")

add_library(mylib SHARED library.cpp utils.cpp)

target_include_directories(mylib PUBLIC 
    /usr/lib/jvm/java-8-openjdk-armhf/include
    /usr/lib/jvm/java-8-openjdk-armhf/include/linux
    )
set_target_properties(mylib PROPERTIES VERSION 1)

“输出”窗口中有一些输出,但我正在剪掉文本部分...如果这有帮助

shellexec 1.0
Copyright (C) 2016 Microsoft Corporation. All rights reserved.
Linux raspberrypi 4.19.66-v7+ #1253 SMP Thu Aug 15 11:49:46 BST 2019 armv7l
Last login: Sun May 17 13:35:25 2020 from 192.168.70.94
pi@raspberrypi:~$ =thread-group-added,id="i1"
GNU gdb (Raspbian 7.12-6) 7.12.0.20161007-git
This GDB was configured as "arm-linux-gnueabihf".
Type "show configuration" for configuration details.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Warning: Debuggee TargetArchitecture not detected, assuming x86_64.
=cmd-param-changed,param="pagination",value="off"

Program received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()
Segmentation fault

1017kill
The thread 'libmylib.so' (0x7bbb) has exited with code 0 (0x0).
The program 'libmylib.so' has exited with code 0 (0x0).

这几乎听起来像是在尝试将我的库作为本机可执行文件执行,但不确定我有什么问题。我是 Visual Studio 和 CMake 的新手,因此感谢您提供任何帮助

更新

这是所要求的代码。我会省略标题,但如果有帮助可以包含这些标题

// library.cpp
#include "library.h"

#ifdef __cplusplus
extern "C" {
#endif

    JNIEXPORT void JNICALL  Java_com_test_platform_arch_ArmLinuxPlatform_reboot(JNIEnv* env, jobject obj) {
        sync(); // write any pending mods to the filesystem
        printf("Rebooting...\n");
        int retCode = reboot(LINUX_REBOOT_CMD_RESTART);
        if (retCode != 0) {
            if (errno == EFAULT) {
                printf("Reboot Failed. EFAULT");
            }
            else if (errno == EINVAL) {
                printf("Reboot Failed. EINVAL");
            }
            else if (errno == EPERM) {
                printf("Reboot Failed. EPERM");
            }
            else {
                printf("Reboot Failed. Error=%i", errno);
            }
        }
        else
            printf("Reboot successful");
        printf("\n");
    }

    JNIEXPORT jint JNICALL Java_com_test_platform_arch_ArmLinuxPlatform_pid(JNIEnv* env, jobject obj) {
        return getpid();
    }

    JNIEXPORT jfloat JNICALL Java_com_test_platform_arch_ArmLinuxPlatform_cpuUsage(JNIEnv* env, jobject obj) {

        CPUData d1 = ReadStats();
        std::this_thread::sleep_for(std::chrono::milliseconds(250));
        CPUData d2 = ReadStats();

        const float ACTIVE_TIME = static_cast<float>(GetActiveTime(d2) - GetActiveTime(d1));
        const float IDLE_TIME = static_cast<float>(GetIdleTime(d2) - GetIdleTime(d1));
        const float TOTAL_TIME = ACTIVE_TIME + IDLE_TIME;

        return 100.0f * (ACTIVE_TIME / TOTAL_TIME);
    }

#ifdef __cplusplus
}
#endif
// utils.cpp
#include "utils.h"

#ifdef __cplusplus
extern "C" {
#endif

    CPUData ReadStats() {
        std::ifstream fileStat("/proc/stat");

        std::string line;

        std::getline(fileStat, line);

        std::istringstream ss(line);

        CPUData data;
        ss >> data.cpu;

        for (int i = 0; i < NUM_CPU_STATES; ++i)
            ss >> data.times[i];

        fileStat.close();

        return data;
    }

    size_t GetIdleTime(const CPUData& e)
    {
        return  e.times[S_IDLE] +
            e.times[S_IOWAIT];
    }

    size_t GetActiveTime(const CPUData& e)
    {
        return  e.times[S_USER] +
            e.times[S_NICE] +
            e.times[S_SYSTEM] +
            e.times[S_IRQ] +
            e.times[S_SOFTIRQ] +
            e.times[S_STEAL] +
            e.times[S_GUEST] +
            e.times[S_GUEST_NICE];
    }

#ifdef __cplusplus
}
#endif
// utils.h
#pragma once

#include <vector>
#include <chrono>
#include <thread>
#include <string>
#include <fstream>
#include <sstream>

#ifdef __cplusplus
extern "C" {
#endif

    const int NUM_CPU_STATES = 10;

    enum CPUStates
    {
        S_USER = 0,
        S_NICE,
        S_SYSTEM,
        S_IDLE,
        S_IOWAIT,
        S_IRQ,
        S_SOFTIRQ,
        S_STEAL,
        S_GUEST,
        S_GUEST_NICE
    };

    typedef struct CPUData
    {
        std::string cpu;
        size_t times[NUM_CPU_STATES];
    } CPUData;

    CPUData ReadStats();
    size_t GetIdleTime(const CPUData& e);
    size_t GetActiveTime(const CPUData& e);

#ifdef __cplusplus
}
#endif

【问题讨论】:

    标签: c++ cmake raspberry-pi cross-compiling visual-studio-2019


    【解决方案1】:

    来自https://www.geeksforgeeks.org/segmentation-fault-sigsegv-vs-bus-error-sigbus/

    Segmentation Fault(也称为 SIGSEGV,通常是信号 11)发生在程序尝试在为其分配的内存之外进行写入/读取或写入只能读取的内存时。换句话说,当程序尝试访问它无权访问的内存。 SIGSEGV 是“Segmentation Violation”的缩写。

    我们应该看到代码,我不认为这是编译器错误。

    【讨论】:

    • 我添加了代码,您可以看到它使用的是 JNI。奇怪的是,当我将此库加载到 java 运行时并执行本机函数时,这些函数工作正常。它只是 Visual Studio 在构建它后抛出了一个段错误。感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    相关资源
    最近更新 更多