stackplz icon indicating copy to clipboard operation
stackplz copied to clipboard

请教,--jstack 标志在实际使用中提示 "unknown flag"

Open huigeqifei opened this issue 10 months ago • 7 comments

在项目的 README 中提到: --jstack 配合--kill SIGSTOP使用,可对堆栈中的jar/vdex进行解析

但是实际使用却提示Error: unknown flag: --jstack

Image

huigeqifei avatar Mar 11 '25 09:03 huigeqifei

从action下载最新的

SeeFlowerX avatar Mar 11 '25 12:03 SeeFlowerX

感谢您的回复。但是在实际使用过程中,又遇到了加上--jstack出现调用栈被截断的情况。请问是我的填写的命令行出了问题吗?自己在其他app测试又能显示java层堆栈。

图一使用的命令 ./stackplz_arm64 -n com.xxx.app --stack -s %file,mmap -o log3.txt

图二使用的命令 ./stackplz_arm64 -n com.xxx.app --stack -s openat,mmap --jstack --kill SIGSTOP --auto -o log3.txt

Image

Image

huigeqifei avatar Mar 14 '25 04:03 huigeqifei

确实会有这种情况,是go从c这边获取结果的时候,会出现字符串内容丢失的情况,我也没搞清楚怎么修复。。

SeeFlowerX avatar Mar 14 '25 05:03 SeeFlowerX

确实会有这种情况,是go从c这边获取结果的时候,会出现字符串内容丢失的情况,我也没搞清楚怎么修复。。

有没有可能是这里的原因:

const char* UnwindCallChain(char* map_buffer, UnwindOption* opt, uint64_t* regs_buf, void* stack_buf) {
    const char* result = "";
    // std::cerr << "pid:" << pid << "reg_mask:" << opt->reg_mask << "abi:" << opt->abi << std::endl;
    RegSet regs(opt->abi, opt->reg_mask, regs_buf);

    uint64_t sp_reg_value;
    if (!regs.GetSpRegValue(&sp_reg_value)) {
        std::cerr << "can't get sp reg value";
        return result;
    }
    
    uint64_t stack_addr = sp_reg_value;
    size_t stack_size = opt->dyn_size;
    
    std::unique_ptr<unwindstack::Regs> unwind_regs(GetBacktraceRegs(regs));
    if (!unwind_regs) {
      return result;
    }
    std::shared_ptr<unwindstack::Memory> stack_memory = unwindstack::Memory::CreateOfflineMemory(
        reinterpret_cast<const uint8_t*>(stack_buf), stack_addr, stack_addr + stack_size
    );

    std::unique_ptr<unwindstack::Maps> maps;
    maps.reset(new unwindstack::BufferMaps(map_buffer));
    maps->Parse();

    UnwinderWithPC unwinder(512, maps.get(), unwind_regs.get(), stack_memory, opt->show_pc);
    // default is true
    // unwinder.SetResolveNames(false);
    unwinder.Unwind();
    std::string frame_info = DumpFrames(unwinder);
    // int len = frame_info.length();
    // send(client_sockfd, &len, 4, 0);
    // send(client_sockfd, frame_info.c_str(), len, 0);
    result = frame_info.c_str();
    return result;
}

https://github.com/SeeFlowerX/unwinddaemon lib.cpp 代码这里,返回的字符指针是std::string中的字符地址,但std::string是一个栈上对象,是临时的,在函数退出时,std::string会被销毁,导致返回的字符指针变为悬挂指针(dangling pointer),访问该地址会导致未定义行为(undefined behavior)。

一旦其内存被覆盖,地址上将会出现意外内容或者无内容。 应该在堆上分配一段内存,然后从std::string中拷贝到新的内存中,再返回新分配的内存地址

WindySha avatar Jun 23 '25 09:06 WindySha

可以测试一下这个,应该能修复这个问题 https://github.com/SeeFlowerX/stackplz/actions/runs/15881821276

SeeFlowerX avatar Jun 25 '25 16:06 SeeFlowerX

感谢更新,但是好像还是有点问题 使用命令 ./stackplz_arm64 -n com.xxx.app --stack -s openat,mmap --jstack --kill SIGSTOP --auto -o log3.txt

Image

huigeqifei avatar Jun 26 '25 13:06 huigeqifei

这个看起来并没有被截断,应该是正常的

有的调用就是这样的,没办法再往上回溯了

SeeFlowerX avatar Jun 26 '25 13:06 SeeFlowerX