termux / termux-api

Termux add-on app which exposes device functionality as API to command line programs.
https://f-droid.org/en/packages/com.termux.api/
2.31k stars 457 forks source link

Can't use termux-battery-info in C program via system(3) call #252

Closed leha-bot closed 5 years ago

leha-bot commented 5 years ago

Problem description

Recently I noticed that termux-battery-status doesn't work anymore if I called it via system() function. It worked in August 2018, but seems to be broken after this milestone (I deduced it from my Telegram bot which running at tablet and using Termux API for battery info).

Steps to reproduce

Expected behavior Some output like:

{
  "health": "GOOD",
  "percentage": 54,
  "plugged": "PLUGGED_USB",
  "status": "CHARGING",
  "temperature": 28.600000381469727
}
system("termux-battery-status") returned 0"

Actual behavior

$ ./a.out
WARNING: linker: ./a.out: unused DT entry: type 0x6ffffef5 arg 0x23c
system("termux-battery-status") returned 11

Additional information termux-info:

Updatable packages:
All packages up to date
System information:
Linux localhost 3.10.33-g678969f #1 SMP PREEMPT Mon Aug 24 10:37:00 PDT 2015 armv7l Android
Termux-packages arch:
arm
Android version:
5.1.1
Device manufacturer:
NVIDIA
Device model:
SHIELD Tablet

adb logcat -s termux:* termux-api:* (from Windows Cmd):

D:\Progs\sdks\Android\sdk\platform-tools>adb logcat -s termux:* termux-api:*
--------- beginning of system
--------- beginning of main
--------- beginning of crash

Output if app debugged under GDB:

$ gdb ./a.out
GNU gdb (GDB) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "arm-linux-androideabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
--Type <RET> for more, q to quit, c to continue without paging--

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.out...done.
(gdb) run
Starting program: /data/data/com.termux/files/home/a.out
WARNING: linker: /data/data/com.termux/files/home/a.out: unused DT entry: type 0x6ffffef5 arg 0x23c
[Detaching after vfork from child process 13785]
{
  "health": "GOOD",
  "percentage": 54,
  "plugged": "PLUGGED_USB",
  "status": "CHARGING",
  "temperature": 30.5
}
system("termux-battery-status") returned 0
[Inferior 1 (process 13782) exited normally]
(gdb)

Output then app is launched under strace (it shows some weird SIGSEGVs inside SIGCHLD signal, which means that the inferior process created by system() has been crashed: https://gist.github.com/leha-bot/6ed4e1055b4073fb8ccb271c3c7a3e76

leha-bot commented 5 years ago

I also got the logcat -d "W:*" but it doesn't contain any termux-related stuff (except some linker warnings about unused entries)

Quasic commented 5 years ago

Did you run the compiled binary through termux-elf-cleaner?

BTW, Android 5 requires a separate cleaner.

ghost commented 5 years ago

Expected behavior Some output like:

{
 "health": "GOOD",
 "percentage": 54,
 "plugged": "PLUGGED_USB",
 "status": "CHARGING",
 "temperature": 28.600000381469727
}
system("termux-battery-status") returned 0"

As expected, no error: screenshot_20190211-021934_termux

Quasic commented 5 years ago
Welcome to Termux!

Wiki:            https://wiki.termux.com
Community forum: https://termux.com/community
IRC channel:     #termux on freenode
Gitter chat:     https://gitter.im/termux/termux
Mailing list:    termux+subscribe@groups.io

Search packages:   pkg search <query>
Install a package: pkg install <package>
Upgrade packages:  pkg upgrade
Learn more:        pkg help

07:32:14T5/2:~$ cd test

07:32:17T5/2:~/test$ cat test.c
#include <stdio.h>
#include <stdlib.h>

int main()
{
  const char *command = "termux-battery-status";
  int retcode = system(command);
  printf("system(\"%s\") returned %d\n", command, retcode);
  return 0;
}

07:32:31T5/2:~/test$ clang test.c

07:32:39T5/2:~/test$ ./a.out
WARNING: linker: ./a.out: unused DT entry: type 0x6ffffef5 arg 0x23c
{
  "health": "GOOD",
  "percentage": 57,
  "plugged": "UNPLUGGED",
  "status": "DISCHARGING",
  "temperature": 29.899999618530273
}
system("termux-battery-status") returned 0

07:32:47T5/2:~/test$ termux-elf-cleaner-5 a.out
termux-elf-cleaner: Removing the DT_GNU_HASH dynamic section entry from 'a.out'

07:33:08T5/2:~/test$ ./a.out
{
  "health": "GOOD",
  "percentage": 57,
  "plugged": "UNPLUGGED",
  "status": "DISCHARGING",
  "temperature": 29.899999618530273
}
system("termux-battery-status") returned 0

07:33:15T5/2:~/test$
ghost commented 5 years ago

@Quasic Looks like problem still exist but only on some ROMs. I was able to reproduce it on Android 6 (arm).

How to fix

unset LD_PRELOAD

- put this thing to your .bashrc (or something similar) and restart Termux.

screenshot_20190211-030028


This is problem related to termux-exec and possible bug in system libc and there no workaround other than completely disable termux-exec.

leha-bot commented 5 years ago

Thank you! It seems that this library is inside loaded modules (info dll in GDB):

(gdb) info dll
From        To          Syms Read   Shared Object Library
0x400009a0  0x40009cf8  Yes (*)     /system/bin/linker
0x4002e670  0x400755d8  Yes (*)     /system/lib/libc.so
0x4001a4b4  0x4001a67c  Yes (*)     /data/data/com.termux/files/usr/lib/libtermux-exec.so
0x400d6ab8  0x400d74a0  Yes (*)     /system/lib/libstdc++.so
0x400bcb80  0x400d0500  Yes (*)     /system/lib/libm.so
0x400b67e8  0x400b6dcc  Yes (*)     /system/lib/libnetd_client.so

I'll try to localize the issue and update OS at another Shield to 7.0 as it has (As I understood from NDK changelogs and discussion in this issue ).