[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81712":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":13,"contributorsCount":12,"subscribersCount":12,"size":12,"stars1d":12,"stars7d":12,"stars30d":12,"stars90d":12,"forks30d":12,"starsTrendScore":12,"compositeScore":14,"rankGlobal":9,"rankLanguage":9,"license":15,"archived":16,"fork":16,"defaultBranch":17,"hasWiki":18,"hasPages":16,"topics":19,"createdAt":9,"pushedAt":9,"updatedAt":20,"readmeContent":21,"aiSummary":22,"trendingCount":12,"starSnapshotCount":12,"syncStatus":23,"lastSyncTime":24,"discoverSource":25},81712,"stackwhere","cilium\u002Fstackwhere","cilium","A tool for exploring where BPF stack usage comes from",null,"Go",41,0,1,40,"Apache License 2.0",false,"main",true,[],"2026-06-12 04:01:35","# Stackwhere\n\nWhere is the stack usage of my BPF program coming from? \n\nIn BPF, every byte of stack usage counts, the verifier limits us to 512 bytes of stack per BPF program or 256 bytes when combining tail calls and BPF-to-BPF functions. You cannot always tell which variables in your sources contribute to stack usage due to compiler optimizations. `stackwhere` uses DWARF debug info to get information about stack usage from the actual ELF file.\n\n## Installation\n\n### Release binary\n\n1. Go to https:\u002F\u002Fgithub.com\u002Fcilium\u002Fstackwhere\u002Freleases and find the latest stable release.\n2. Download the binary for your OS and CPU architecture.\n3. Unpack the .tar.gz archive and move binary to permanent directory\n\n#### Example on Linux AMD64\n\n```bash\nwget https:\u002F\u002Fgithub.com\u002Fcilium\u002Fstackwhere\u002Freleases\u002Fdownload\u002Fv0.2.0\u002Fstackwhere_0.2.0_linux_amd64.tar.gz\n\n# Optional, verify checksum\nwget https:\u002F\u002Fgithub.com\u002Fcilium\u002Fstackwhere\u002Freleases\u002Fdownload\u002Fv0.2.0\u002Fstackwhere_0.2.0_checksums.txt\nsha256sum -c stackwhere_0.2.0_checksums.txt --ignore-missing\n# Should say: stackwhere_0.2.0_linux_amd64.tar.gz: OK\n\ntar -xzf stackwhere_0.2.0_linux_amd64.tar.gz\nsudo mv stackwhere \u002Fusr\u002Fbin\u002Fstackwhere\n```\n\n### Go install\n\nInstall the latest version by running `go install github.com\u002Fcilium\u002Fstackwhere\u002Fcmd\u002Fstackwhere@latest`.\n\n## Usage\n\nStackwhere uses DWARF debug info, which requires the .o files to be created with the `-g` compiler option and to not\nbe stripped.\n\n### Inspecting collections\n\nThe `list` (alias `l`) sub-command lists the peak stack usage for each program \u002F function in the given\nobject file.\n\n```\n$ stackwhere list {path to .o}\n128 bytes - my_example_program\n 80 bytes - my_other_program\n 20 bytes - small_function\n```\n\n### Inspecting programs\n\nThe `list` (alias `l`) sub-command lists a detailed per program listing when a program name is specified as the second\nargument.\n\n```\n$ stackwhere list {path to .o} {name of program}\nR10-16:\n  8 - example_var1 @ \u002Fsome\u002Fpath\u002Fto\u002Fyour\u002Fsources\u002Fbpf.c:12\nR10-24:\n  16 - example_var2 @ \u002Fsome\u002Fpath\u002Fto\u002Fyour\u002Fsources\u002Fbpf.c:14\nR10-40:\n  8 - example_var3 @ \u002Fsome\u002Fpath\u002Fto\u002Fyour\u002Fsources\u002Fbpf.c:20\n  4 - example_var5 @ \u002Fsome\u002Fpath\u002Fto\u002Fyour\u002Fsources\u002Fbpf.c:41\nR10-48:\n  8 - example_var4 @ \u002Fsome\u002Fpath\u002Fto\u002Fyour\u002Fsources\u002Fbpf.c:21\n```\n\nThis prints each offset into the stack found in the program when attributable to something found in the sources. Stack offsets are always R10 minus some fixed offset, BPF does not have push\u002Fpop instructions, so stack size is always predetermined and offsets within it assigned by the compiler. R10 is the stack frame the function.\n\nStack usage happens in three situations:\n1. A local variable or function argument is larger than 8 bytes, and thus cannot fit in a register value.\n2. All register values are full, variables or intermediate values are spilled onto the stack.\n3. A pointer to a local variable or attribute is passed to a helper function or kfunc.\n\nSo local variables and function arguments of inlined functions can appear in the output, be referred to as \"variables\".\n\nMultiple variables can share the same offset when their lifetimes do not overlap, so stack slots are reused by the compiler when it thinks its safely able to. Stackwhere groups variables at the same offsets together and outputs them from low offsets (the \"bottom\" of the stack) to high offsets (\"top\" top of the stack).\n\nSpilling of unamed values, such as intermediate values of an expression does not appear in this output (at this this). Such spilled values can share stack slots with named variables and may use gaps in offsets that are shown. \n\n## Tips for reducing stack usage\n\nThe limiting factor for a BPF program is the **peak** memory usage, some ideas to reduce peak memory usage are:\n\n1. Removing variables. not always possible, but a 1 byte variable can take up a whole 8 byte stack slot.\n2. Shorten variable lifetimes. Use inlined functions or variable scopes to limit the lifetime of a variable. Attempt to order code such that variables can have smaller lifetimes. This promotes stack slot reuse, less variables alive a the same time, smaller peak usage.\n3. Utilize non-stack memory. Avoid storing variables which can be derived from the program context. Use map values instead of copying and holding onto individual field values. Use per-CPU map values or global variables to store large values (that are not used as input to branching logic).\n4. Split programs into tail calls.\n5. Reduce function call depth.\n\nWarning, some of these measures may increase verifier complexity and\u002For runtime performance, there are always tradeoffs.\n","Stackwhere 是一个用于探索 BPF 程序栈使用来源的工具。它通过 DWARF 调试信息从 ELF 文件中获取栈使用情况，帮助开发者理解哪些变量或函数对栈空间的消耗最大，从而优化 BPF 代码以满足严格的栈大小限制（每个 BPF 程序最多 512 字节）。项目采用 Go 语言编写，并提供了详细的安装和使用指南，支持通过预编译二进制文件或直接用 Go 安装最新版本。该工具特别适用于需要深入分析和优化 BPF 程序栈使用的场景，如网络性能监控、安全策略实施等，对于希望提高 BPF 程序效率和稳定性的开发者来说非常有用。",2,"2026-06-11 04:06:03","CREATED_QUERY"]