Skip to content
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

Update probe_bash.go #479

Merged
merged 1 commit into from
Feb 8, 2024
Merged

Update probe_bash.go #479

merged 1 commit into from
Feb 8, 2024

Conversation

sancppp
Copy link
Contributor

@sancppp sancppp commented Feb 5, 2024

Fixed a text error in a comment

Copy link
Member

@cfc4n cfc4n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感谢贡献。这个pr只是修改了注释,能否也参与做一些代码上的贡献呢?比如,bash模块有个缺陷,在启动ecapture后,第一个bash命令监控不到,丢失了。能否定位一下这个bug,一起修复了?非常感谢。


Thank you for your contribution. This PR only modified the comments. Can you also contribute to some code changes? For example, there is a defect in the bash module where the first bash command cannot be monitored and is lost after starting ecapture. Could you help locate this bug and fix it together? Thank you very much.

@sancppp
Copy link
Contributor Author

sancppp commented Feb 5, 2024

感谢贡献。这个pr只是修改了注释,能否也参与做一些代码上的贡献呢?比如,bash模块有个缺陷,在启动ecapture后,第一个bash命令监控不到,丢失了。能否定位一下这个bug,一起修复了?非常感谢。

Thank you for your contribution. This PR only modified the comments. Can you also contribute to some code changes? For example, there is a defect in the bash module where the first bash command cannot be monitored and is lost after starting ecapture. Could you help locate this bug and fix it together? Thank you very much.

首先,我去测试了一下BCC中的bashreadline工具,发现也有同样的问题。

再用uprobe/uretprobe给bash::readline这个函数打断点,发现bash的运行会阻塞在readline这个函数,当接收到回车时获取缓冲区内容。表现为新建一个bash terminal时会触发uprobe,输入回车之后会触发uretprobe打印出输入的命令然后立刻触发uprobe。因此使用uretprobe去监控bash::readline会丢失第一个命令。

然后我下载了gnu bash 5.1.16的源码,得知了readline函数的返回值是由readline_internal_teardown这个函数得来的
将hook函数由readline更改为readline_internal_teardown之后,能够解决eCapture bash启动后第一个命令丢失的问题。

另外,我翻阅了老版本的bash,1996年的bash2.0版本中也是相同的函数处理流程,因此应该不需要判断bash的版本来判断hook哪个函数。

如果您觉得这个更改没问题的话,晚些时候我也去给BCC提个PR。

@@ -146,8 +147,8 @@ func (b *MBashProbe) setupManagers() {
{
Section: "uretprobe/bash_readline",
EbpfFuncName: "uretprobe_bash_readline",
AttachToFuncName: "readline",
//UprobeOffset: 0x8232, //若找不到 readline 函数,则使用offset便宜地址方式。
AttachToFuncName: "readline_internal_teardown",
Copy link
Member

@cfc4n cfc4n Feb 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

近期在准备春节的事情,我晚点测试一下。

@cfc4n
Copy link
Member

cfc4n commented Feb 5, 2024

感谢分析,对于定位的原因,能否贴一些bash对应hook函数的代码片段? readline函数调用readline_internal_teardown是实现,哪个文件的多少行。

另外,在你修改probe_bash.go部份,建议给一些注释说明一下,清晰地介绍选择这个函数的原因。 或者附上这个pr的链接。

@sancppp
Copy link
Contributor Author

sancppp commented Feb 5, 2024

bash::readline.c代码片段:

#if defined (READLINE_CALLBACKS)
#  define STATIC_CALLBACK
#else
#  define STATIC_CALLBACK static
#endif


STATIC_CALLBACK char *
readline_internal_teardown (int eof)
{
  ...
  return (eof ? (char *)NULL : savestring (the_line));
}


/* Read a line of input from the global rl_instream, doing output on
   the global rl_outstream.
   If rl_prompt is non-null, then that is our prompt. */
static char *
readline_internal (void)
{
  readline_internal_setup ();
  rl_eof_found = readline_internal_charloop ();
  return (readline_internal_teardown (rl_eof_found));
}


/* Read a line of input.  Prompt with PROMPT.  An empty PROMPT means
   none.  A return value of NULL means that EOF was encountered. */
char *
readline (const char *prompt)
{
  char *value;
  ...
  value = readline_internal (); //阻塞等待,直到收到回车键信号
  ...
  return (value);
}

可见:

  1. readline函数通过调用static修饰的函数readline_internal阻塞等待用户输入的命令。
  2. readline_internal在接受回车键信号后调用STATIC_CALLBACK宏修饰的readline_internal_teardown函数进行返回。
  3. STATIC_CALLBACKREADLINE_CALLBACKS约束。

bash::rlconf.h中默认开启了READLINE_CALLBACKS

因此:

  1. 在bash的符号表中没有static修饰的函数readline_internal,不方便ebpf的hook函数(理论上可以通过offset找到其位置,然而我不太会💩,之后有空继续完善)。
  2. 若要解决eCapture bash启动后第一次bash命令丢失的问题,需要将hook函数由readline更改为readline_internal_teardown

Copy link
Member

@cfc4n cfc4n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM,thanks. 明天我测试一下这个pr

@sancppp
Copy link
Contributor Author

sancppp commented Feb 7, 2024

iovisor/bcc#4903 给BCC交的补丁被merge了,感谢大佬给的机会😍。

@cfc4n
Copy link
Member

cfc4n commented Feb 8, 2024

iovisor/bcc#4903 给BCC交的补丁被merge了,感谢大佬给的机会😍。

恭喜,希望这可以引领你走上一个新台阶。

也欢迎你可以继续为开源社区做贡献。

@cfc4n cfc4n merged commit d579a65 into gojue:master Feb 8, 2024
6 checks passed
@sancppp sancppp deleted the patch-1 branch February 8, 2024 05:04
@cfc4n cfc4n mentioned this pull request Feb 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants