djberg96 / sys-proctable

A cross-platform Ruby interface for gathering process information on your operating system
Apache License 2.0
150 stars 33 forks source link

bug with processes name not ASCII #83

Closed deemytch closed 4 years ago

deemytch commented 4 years ago

Found that occasionally, when experimenting with changing processes names.

djberg96 commented 4 years ago

@deemytch Interesting, I wonder if we should just always force encoding. Any chance of adding some specs?

deemytch commented 4 years ago

Any chance of adding some specs?

Yep, I'll try to write some next week. Also, have no idea how (and do I need?) to mock that. I'm not sure about forcing, cause there's still are systems with C system encoding.

djberg96 commented 4 years ago

@deemytch Yes, you should be able to mock it with something like this:

allow(IO).to receive(:read).with("/proc/xxx/environ").and_return("some non-ascii text")
expect(Sys::ProcTable.ps(xxx).environ).to eq(what_you_expect)
djberg96 commented 4 years ago

@deemytch Just curious what shell you're using, and how you set a non-ascii environment variable. My attempts to export Ἑλλάς="GREECE", for example, were failures.

deemytch commented 4 years ago

Zsh, archlinux. I wrote a ruby microservice, that changes his $0 (processname) to something found in config file. And I'm also curious ;) Yep, in bash it's not working.

% СЛОВО="Word"
% echo ${СЛОВО}
Word
% echo $LANG
ru_RU.UTF-8
djberg96 commented 4 years ago

@deemytch Fighting with it yet. I can set the env well enough, but I think rbenv is using bash under the hood, because when I fire up irb and check ENV['СЛОВО'] I get nil.

deemytch commented 4 years ago

I don't use rbenv nor others. That code works on my comp and in virtual server at hezner.

#!/usr/bin/ruby

$0 = 'Название программы'
ENV['Ещё разное'] = 'Какая-то строка'
sleep 5
ENV.each{|k,v| puts "$#{ k } = '#{ v }'" }
puts `ps axu`
sleep 5

last lines of output looks like

root      220249  0.0  0.0      0     0 ?        I    10:22   0:00 [kworker/3:2-events]
root      220391  0.0  0.0      0     0 ?        I<   10:24   0:00 [kworker/u9:2]
root      220515  0.0  0.0      0     0 ?        I    10:26   0:00 [kworker/1:1-events]
root      220516  0.0  0.0      0     0 ?        I    10:26   0:00 [kworker/1:3-events]
root      220517  0.0  0.0      0     0 ?        I    10:26   0:00 [kworker/3:3]
root      220523  0.0  0.0      0     0 ?        I    10:26   0:00 [kworker/0:2-events]
root      220666  0.0  0.0      0     0 ?        I    10:28   0:00 [kworker/u8:0]
devuser   220714  1.2  0.1  77872 13588 pts/0    S+   10:29   0:00 Название программы
devuser   220715  0.0  0.0   9708  3376 pts/0    R+   10:29   0:00 ps axu
deemytch commented 4 years ago

Also just checked centos server at work

# cat программа.sh
#!/usr/bin/sh

ps ax
sleep 10
18115 ?        S      0:00 [kworker/0:0]
18301 ?        S      0:00 [kworker/u4:2]
18500 ?        S      0:00 [kworker/1:2]
18623 ?        S      0:00 [kworker/0:2]
18883 ?        R      0:00 [kworker/1:1]
19101 ?        Ss     0:00 sshd: devuser [priv]
19103 ?        D      0:00 sshd: devuser@pts/0
19104 pts/0    Ss     0:00 -bash
19428 pts/0    S+     0:00 /usr/bin/sh ./программа.sh
19429 pts/0    R+     0:00 ps ax
# echo $LANG
en_US.UTF-8
# cat /etc/centos-release
CentOS Linux release 7.7.1908 (Core)
djberg96 commented 4 years ago

@deemytch I could not replicate the issue on Fedora 32. I ran the script in the background that you provided, fired up irb in another terminal, and ran Sys::ProcTable.ps(:pid => xxxxx), and it worked fine. I can see the Russian cmdline name. I even tried modifying the $LANG env variable first for both the script and the irb session, but it still worked.

That said, it doesn't look like the environment variable is getting stored in /proc/xxxxx/environ at all on my Fedora VM, which is where your issue originates. I looked at that file directly, and it's like it's not even there. Does Linux (or Fedora) simply ignore non-ascii environment variables in the proc filesystem if your system encoding is English? That I don't know.

Anyway, it's probably easier for me to simulate this through rspec that fiddling with my system's encoding. I will see what I can do.

djberg96 commented 4 years ago

@deemytch Just curious, what happens if you run strings /proc/xxxxx/environ?

deemytch commented 4 years ago

Yep! strings do not see any cyrillic and filter out such folder names inserting carriage return. So PWD=/home/devuser/work/проект/bpapi became

PWD=/home/devuser/work/
/bpapi

Also I espesially exported environment variable

% export ПЕРЕМЕННАЯ=ЗНАЧЕНИЕ
% echo $ПЕРЕМЕННАЯ        
ЗНАЧЕНИЕ

but cat /proc/$$/environ also does not show me that variable, even I see there my cyrillic folder names.

deemytch commented 4 years ago

Also https://unix.stackexchange.com/questions/29128/how-to-read-environment-variables-of-a-process

djberg96 commented 4 years ago

@deemytch Ok, let's just always force encode it, and skip the retry bit. So just:

IO.read("/proc/#{file}/environ").force_encoding("UTF-8").split("\0").each{ |str|

Also, please remove the .gitignore, I do that kind of stuff globally, I don't want it in the repo.

djberg96 commented 4 years ago

@deemytch See https://github.com/djberg96/sys-proctable/pull/85.

deemytch commented 3 years ago

Thank you, had new job, being very busy.