-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Feature/ksym backtrace #11768
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
liulangrenaaa
wants to merge
3
commits into
RT-Thread:master
Choose a base branch
from
liulangrenaaa:feature/ksym-backtrace
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Feature/ksym backtrace #11768
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| /* | ||
| * Copyright (c) 2006-2026, RT-Thread Development Team | ||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| #include <rtthread.h> | ||
|
|
||
| #ifdef RT_USING_KSYMS | ||
|
|
||
| /* These objects are replaced by the generated table when using GCC builds. */ | ||
| rt_weak volatile const rt_uintptr_t rt_ksym_first_addr = 0; | ||
| rt_weak volatile const rt_uint32_t rt_ksym_count = 0; | ||
| rt_weak volatile const rt_uint32_t rt_ksym_entries[1][3] = {{0, 0, 0}}; | ||
| rt_weak const char rt_ksym_names[1] = ""; | ||
|
|
||
| static rt_uintptr_t _rt_ksym_normalize_addr(rt_uintptr_t addr) | ||
| { | ||
| #if defined(ARCH_ARM) && !defined(ARCH_CPU_64BIT) | ||
| return addr & ~((rt_uintptr_t)1); | ||
| #else | ||
| return addr; | ||
| #endif | ||
| } | ||
|
|
||
| static rt_uintptr_t _rt_ksym_entry_addr(rt_uint32_t index) | ||
| { | ||
| return rt_ksym_first_addr + rt_ksym_entries[index][0]; | ||
| } | ||
|
|
||
| rt_err_t rt_ksym_lookup(rt_uintptr_t addr, struct rt_ksym_info *info) | ||
| { | ||
| rt_uint32_t low; | ||
| rt_uint32_t high; | ||
| rt_uintptr_t start; | ||
| rt_uint32_t size; | ||
|
|
||
| if (!info) | ||
| return -RT_EINVAL; | ||
| if (rt_ksym_count == 0) | ||
| return -RT_ENOSYS; | ||
|
|
||
| addr = _rt_ksym_normalize_addr(addr); | ||
|
|
||
| if (addr < rt_ksym_first_addr || | ||
| addr - rt_ksym_first_addr > 0xffffffffu) | ||
| return -RT_ENOENT; | ||
|
|
||
| low = 0; | ||
| high = rt_ksym_count; | ||
| while (high - low > 1) | ||
| { | ||
| rt_uint32_t middle = low + (high - low) / 2; | ||
|
|
||
| if (_rt_ksym_entry_addr(middle) <= addr) | ||
| low = middle; | ||
| else | ||
| high = middle; | ||
| } | ||
|
|
||
| if (_rt_ksym_entry_addr(low) > addr) | ||
| return -RT_ENOENT; | ||
|
|
||
| /* Keep aliases together even if a hand-built table contains them. */ | ||
| while (low > 0 && | ||
| _rt_ksym_entry_addr(low - 1) == _rt_ksym_entry_addr(low)) | ||
| { | ||
| low--; | ||
| } | ||
|
|
||
| start = _rt_ksym_entry_addr(low); | ||
| size = rt_ksym_entries[low][2]; | ||
|
|
||
| if (size == 0 && addr != start) | ||
| return -RT_ENOENT; | ||
| if (size != 0 && addr - start >= size) | ||
| return -RT_ENOENT; | ||
|
|
||
| info->name = &rt_ksym_names[rt_ksym_entries[low][1]]; | ||
| info->start = start; | ||
| info->offset = addr - start; | ||
| info->size = size; | ||
|
|
||
| return RT_EOK; | ||
| } | ||
|
|
||
| #endif /* RT_USING_KSYMS */ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| /* | ||
| * Copyright (c) 2006-2026, RT-Thread Development Team | ||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| #include <rtthread.h> | ||
| #include "utest.h" | ||
| #include "utest_assert.h" | ||
|
|
||
| static void __attribute__((noinline)) ksym_test_level1(void); | ||
| static void __attribute__((noinline)) ksym_test_level2(void); | ||
| static void __attribute__((noinline)) ksym_test_level3(void); | ||
|
|
||
| static void __attribute__((noinline)) ksym_test_level1(void) | ||
| { | ||
| ksym_test_level2(); | ||
| } | ||
|
|
||
| static void __attribute__((noinline)) ksym_test_level2(void) | ||
| { | ||
| ksym_test_level3(); | ||
| } | ||
|
|
||
| static void __attribute__((noinline)) ksym_test_level3(void) | ||
| { | ||
| rt_backtrace(); | ||
| } | ||
|
|
||
| static void test_ksym_lookup(void) | ||
| { | ||
| struct rt_ksym_info info; | ||
| rt_uintptr_t address; | ||
|
|
||
| address = (rt_uintptr_t)(void *)ksym_test_level1; | ||
| uassert_int_equal(rt_ksym_lookup(address, &info), RT_EOK); | ||
| uassert_str_equal(info.name, "ksym_test_level1"); | ||
| uassert_int_equal(info.start, | ||
| #if defined(ARCH_ARM) && !defined(ARCH_CPU_64BIT) | ||
| address & ~((rt_uintptr_t)1) | ||
| #else | ||
| address | ||
| #endif | ||
| ); | ||
| uassert_int_equal(info.offset, 0); | ||
|
|
||
| #if defined(ARCH_ARM) && !defined(ARCH_CPU_64BIT) | ||
| uassert_int_equal(rt_ksym_lookup(address | 1, &info), RT_EOK); | ||
| uassert_int_equal(info.offset, 0); | ||
| #endif | ||
|
|
||
| uassert_int_equal(rt_ksym_lookup((rt_uintptr_t)-1, &info), -RT_ENOENT); | ||
| uassert_int_equal(rt_ksym_lookup(address, RT_NULL), -RT_EINVAL); | ||
| } | ||
|
|
||
| static void test_ksym_static_chain(void) | ||
| { | ||
| struct rt_ksym_info info; | ||
|
|
||
| #if defined(ARCH_ARM_CORTEX_A) || defined(ARCH_ARMV8) | ||
| ksym_test_level1(); | ||
| #endif | ||
| uassert_int_equal(rt_ksym_lookup((rt_uintptr_t)(void *)ksym_test_level2, | ||
| &info), RT_EOK); | ||
| uassert_str_equal(info.name, "ksym_test_level2"); | ||
| } | ||
|
|
||
| static rt_err_t utest_tc_init(void) | ||
| { | ||
| return RT_EOK; | ||
| } | ||
|
|
||
| static rt_err_t utest_tc_cleanup(void) | ||
| { | ||
| return RT_EOK; | ||
| } | ||
|
|
||
| static void testcase(void) | ||
| { | ||
| UTEST_UNIT_RUN(test_ksym_lookup); | ||
| UTEST_UNIT_RUN(test_ksym_static_chain); | ||
| } | ||
|
|
||
| UTEST_TC_EXPORT(testcase, "core.ksym", utest_tc_init, utest_tc_cleanup, 10); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这会更改内核文件,而这个功能目前只是 ARM 端少数几个才存在,并不适合于放入到内核中。
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@BernardXiong 熊大,感谢 review。这里补充一下这个功能的设计意图。
KSYMS 本身并不是针对 Cortex-A 实现的,我原本是希望把它作为一个架构无关的地址到函数符号解析能力。当前只是 Cortex-A 的 backtrace 路径完成得比较完整,其他架构还没有全部接入。
目前 ARM32、AArch64 和 RISC-V64 的 GCC/ELF 符号表生成和最终 ELF 地址验证都已经测试过,RISC-V64 上
rt_ksym_lookup()也能够正常解析函数符号;RISC-V 后面的 backtrace 失败是在现有 frame-pointer unwind 路径中,不是 KSYMS lookup 本身的问题。如果这里主要 concern 是目前实际使用 KSYMS 的 backtrace consumer 太少,我可以继续调整这个 PR:
src/ksym.c中目前的 ARM/Thumb 地址处理移到架构侧,使 resolver 本身完全不包含 architecture-specific logic;这样
src/ksym.c只负责通用的 symbol lookup,各架构仍然只负责自己的 unwind。如果即使有多个架构 consumer,这类 symbol resolver 仍然不适合放在
src/,我也可以再调整目录和模块归属。请问您这里主要考虑的是目前 consumer 数量还比较少,还是认为 KSYMS 这类诊断功能本身就不应该放在 kernel
src/?