3568-12系统 cpp文件打印追踪debug信息

Cpp文件使用代码追踪源码函数调试
include $(CLEAR_VARS)
LOCAL_MODULE := mysettings
LOCAL_ARM_MODE :=arm
#LOCAL_SHARED_LIBRARIES := libutils libcutils liblog
LOCAL_CFLAGS :=
-fexceptions
-frtti

#Android.bp
#// 启用 C++ 异常和 RTTI

cpp: {

exception: “enabled”,

rtti: “enabled”,

},

#// 移除 cpp 属性,改用 cflags

cflags: [

“-fexceptions”, // 启用 C++ 异常

“-frtti”, // 启用 RTTI

],

#cflags: [

“-DANDROID_CPP_FEATURES=exceptions rtti”,

#],
#LOCAL_MODULE_FILENAME:=libjniUtil
LOCAL_SRC_FILES :=systemJni.cpp TestCJni.c TestCpp.cpp
#prop/watchprops.c prop/hashmap.c
LOCAL_LDLIBS :=-llog
#LOCAL_LDFLAGS := Wl,-hash-style=sysv
#libsysv-hash-table-library_ldflags := Wl,-hash-style=sysv
include $(BUILD_SHARED_LIBRARY)

#include <c++/v1/stdexcept>
//using namespace std;

//在 Android NDK 开发中,ALOG_ASSERT、ALOGE 和 abort 的头文件来源如下:
//ALOG_ASSERT / ALOGE:
//这些是 Android 特有的日志宏,用于 Native 层日志输出
// 头文件:#include <android/log.h>
// 需要在 Android.mk 中添加:LOCAL_LDLIBS += -llog
//abort():
//标准 C 库函数,用于异常终止程序
// 头文件:#include <stdlib.h>
// 标准库函数,无需额外链接库
// 示例代码:
#include <android/log.h> // ALOG_ASSERT, ALOGE
#include <stdlib.h> // abort

#define LOG_TAG “MyNativeCode”

void someFunction() {
int* ptr = nullptr;

// 断言检查,条件为false时终止并输出日志

// ALOG_ASSERT(ptr != nullptr, “Pointer should not be null!”);

// 输出错误日志但继续执行

// ALOGE(“This is an error message: %d”, 42);

// 直接终止程序
abort();

}
//注意:在非 Android 环境下,ALOG_* 宏不可用,需使用标准 C++ 日志方法替代

//3. 使用调试器(GDB/LlDB)
//通过调试器设置断点、单步执行和查看调用栈。
//bash
//# Android 设备调试示例
// adb shell gdbserver :5039 /path/to/your/binary # 在设备上启动 GDB 服务器
// arm-linux-androideabi-gdb # 主机端启动 GDB
// (gdb) target remote :5039 # 连接到设备
//(gdb) break funcA # 设置断点
//(gdb) continue # 继续执行
//(gdb) backtrace # 查看调用栈
//
// 优点:强大灵活,可实时查看变量状态。
//缺点:需要调试环境,可能影响程序行为

//4. 使用回溯库(Backtrace)
//在运行时动态获取调用栈信息,适合记录异常发生时的上下文。
//#include <backtrace/Backtrace.h>

void logStackTrace() {
// android::Backtrace bt;
// bt.Unwind(1); // 跳过当前函数
// bt.Dump(LOG_TAG); // 输出到日志
}

void funcC() {
if (/errorCondition/true) {
LOGE(“Error occurred! Stack trace:”);
// logStackTrace(); // 记录当前调用栈
}
}

//优点:无需调试器,适合生产环境捕获异常。
//缺点:依赖平台库(如 Android 的 libbacktrace)

//5. 使用编译选项(__builtin_return_address)
//GCC/Clang 提供的内置函数可获取调用者地址。
#include <stdio.h>

void printCaller() {
void* caller = __builtin_return_address(0); // 当前函数返回地址
void* parent = __builtin_return_address(1); // 调用者返回地址
printf(“%s: called from %p (parent=%p)\n”, func, caller, parent);
}

//优点:轻量级,无需额外库。
//缺点:返回地址需结合调试符号解析,可读性差。

//7. 自定义钩子(Hook)
//通过函数指针或动态链接库(DLL)注入修改函数行为。
// 使用 LD_PRELOAD 技术替换标准库函数
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>

// 原始函数指针
static ssize_t (real_write)(int fd, const void buf, size_t count) = NULL;

// 替换函数
ssize_t write(int fd, const void* buf, size_t count) {
printf(“HOOK: write(fd=%d, buf=%p, count=%zu)\n”, fd, buf, count);

// 调用原始函数
if (!real_write) {
    // 关键修改:显式类型转换
    real_write = (ssize_t (*)(int, const void *, size_t))dlsym(RTLD_NEXT, "write");
    // 检查dlsym调用是否失败
    if (!real_write) {
        fprintf(stderr, "dlsym error: %s\n", dlerror());
        // 处理错误,例如返回错误值或调用原始write
        return -1;
    }
}
return real_write(fd, buf, count);

}

//优点:无需修改源代码,适合第三方库调试。
//缺点:侵入性强,可能导致不稳定

using namespace std;
//cPP语言抛出异常

void throwTest() {
// std::shared_ptraidl::android::hardware::camera::device::ICameraDevice aidl =NULL;
// aidl = aidl.make_shared();
// aidl.get();
// aidl.get();
// throw exception(“throwException 抛出异常对象”);
// __throw_length_error();
//::open()
//::write()
//pwrite()
throw new std::bad_alloc();
throw std::runtime_error(std::string(func));
throw std::bad_typeid();
throw std::range_error(std::string(func));
throw std::bad_alloc();
throw std::exception();
throw std::bad_exception();
throw std::bad_cast();

int index =0;

int size =0;
// 替换为
// ALOG_ASSERT(index < size, “%s: index out of range (index=%d, size=%d)”,
// func, index, size);

// 方案 2:使用日志 + 终止(适合生产环境)
// 如果需要在生产环境中保留错误记录但不崩溃,可以使用日志 + 条件终止。
// cpp
// 严重错误,记录日志后终止程序
// ALOGF(“FATAL: %s: index out of range (index=%d, size=%d)”,
// func, index, size);
abort(); // 可选:是否强制终止

// 或仅记录错误(不终止)
// ALOGE(“ERROR: %s: index out of range (index=%d, size=%d)”,
// func, index, size);

// 方案 3:使用断言(仅用于调试)
// ALOG_ASSERT( “%s: index out of range”, func);
// 或者使用系统断言
assert( “index out of range”);

    // 正常处理

// LOGI(ERROR) << func << “: index out of range”;

throw std::out_of_range(std::string(__func__));
throw std::invalid_argument(std::string(__func__));
throw std::current_exception();
throw std::exception();
throw std::exception_ptr();
//  __throw_logic_error(__func__);
throw std::bad_exception();
throw std::bad_exception();

throw std::overflow_error(std::string(__func__));
throw std::underflow_error(std::string(__func__));

// throw std::length_error(std::string(func));
throw std::domain_error(std::string(func));

throw std::invalid_argument(std::string(__func__));
throw std::out_of_range(std::string(__func__));
throw std::runtime_error(std::string(__func__));
throw std::out_of_range(std::string(__func__));
char *test;
test = nullptr;
if (strcmp("", "")) {

}

}

  1. 使用标准 C++ 日志替代方案
    cpp
    #include #include // for abort()
    void someFunction() {
    int* ptr = nullptr;

    // 替代ALOG_ASSERT:条件不满足时终止程序
    if (ptr == nullptr) {
    std::cerr << “Assertion failed: Pointer should not be null!” << std::endl;
    std::abort();
    }

    // 替代ALOGE:输出错误信息
    std::cerr << "This is an error message: " << 42 << std::endl;

    // 或使用printf风格(需包含)
    // printf(“This is an error message: %d\n”, 42);}

  2. 自定义日志宏(推荐方案)
    创建一个跨平台的日志头文件,兼容 Android 和非 Android 环境:

cpp
// utils/Logger.h#ifndef UTILS_LOGGER_H#define UTILS_LOGGER_H
#ifdef ANDROID
#include <android/log.h>
#define LOG_TAG “MyApp”
#define LOG_ERROR(…) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, VA_ARGS)
#define LOG_ASSERT(condition, …) ((condition) ? (void)0 :
(__android_log_assert(#condition, LOG_TAG, VA_ARGS), std::abort()))#else
#include
#include
#define LOG_ERROR(…) fprintf(stderr, VA_ARGS)
#define LOG_ASSERT(condition, …) ((condition) ? (void)0 :
(fprintf(stderr, “Assertion failed: %s\n”, #condition),
fprintf(stderr, VA_ARGS),
std::abort()))#endif
#endif // UTILS_LOGGER_H

使用示例:

cpp
#include “utils/Logger.h”
void someFunction() {
int* ptr = nullptr;

LOG_ASSERT(ptr != nullptr, "Pointer should not be null!");
LOG_ERROR("This is an error message: %d\n", 42);}

这种方案的优势是:

完全兼容 Android 环境的原有日志
可以在非 Android 环境(如 Windows/Linux 桌面开发)中正常工作
保持了与 ALOG_系列宏一致的使用习惯

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

android framework

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值