After building the RISCV tools and GCC (cloned from lowrisc, isa-sim and not riscv-tools), i'm stuck in the debugging with Gdb phase here.
In the second terminal target remote in gdb times out.
In the first terminal when i run spike --gdb-port 9824 pk tests/debug or spike --gdb-port 9824 pk hello.c it yields:
spike: unrecognized option --gdb-port
usage: spike [host options] <target program> [target options]
Host Options:
-p <n> Simulate <n> processors
-m <n> Provide <n> MB of target memory
-d Interactive debug mode
-g Track histogram of PCs
-h Print this help message
--ic=<S>:<W>:<B> Instantiate a cache model with S sets,
--dc=<S>:<W>:<B> W ways, and B-byte blocks (with S and
--l2=<S>:<W>:<B> B both powers of 2).
--extension=<name> Specify RoCC Extension
--extlib=<name> Shared library to load
I don't know if it has to do with configuring gdb on its own ? Or is it built and configured when i ran ./build.sh for the riscv tools.
If not, could you please correct the --gdb-port command (I'm new to linux) I've tried --gdb-port=9824 or --gdb-port:9824 and it's the same.
Thank you
Message spike: unrecognized option --gdb-port says that spike, not gdb can't recognize option. Spike is from riscv-isa-sim, not from riscv-tools. And LowRisc variant of Spike - https://github.com/lowRISC/riscv-isa-sim is many commits behind master:
This branch is 3 commits ahead, 172 commits behind riscv:master.
Latest commit e220bc4 on May 19, 2016 #wsong83 wsong83 Merge commit '0d084d5' into update
One of not ported commit added gdb support to spike from https://github.com/riscv/riscv-isa-sim (and documented it in https://github.com/riscv/riscv-isa-sim#debugging-with-gdb), but it is not pulled to https://github.com/lowRISC/riscv-isa-sim (and not documented at https://github.com/lowRISC/riscv-isa-sim). gdb-related commits were from Oct 2016, Jun 2016, May 2016, and the --gdb-port was added in d1d8863086c57f04236418f21ef8a7fbfc184b0b (Mar 19, 2016) https://github.com/riscv/riscv-isa-sim/commit/d1d8863086c57f04236418f21ef8a7fbfc184b0b
+ fprintf(stderr, " --gdb-port=<port> Listen on <port> for gdb to connect\n");
+ parser.option(0, "gdb-port", 1, [&](const char* s){gdb_port = atoi(s);});
You can try merging changes between isa sims or ask lowRisc authors to merge or just try to use spike from riscv...
Related
I'm new to kernel development and I would like to know how to run/debug the linux kernel using QEMU and gdb. I'm actually reading Robert Love's book but unfortunately it doesn't help the reader on how to install proper tools to run or debug the kernel... So what I did was to follow this tutorial http://opensourceforu.efytimes.com/2011/02/kernel-development-debugging-using-eclipse/. I'm using eclipse as an IDE to develop on the kernel but I wanted first to get it work under QEMU/gdb. So what I did so far was:
1) To compile the kernel with:
make defconfig (then setting the CONFIG_DEBUG_INFO=y in the .config)
make -j4
2) Once the compilation is over I run Qemu using:
qemu-system-x86_64 -s -S /dev/zero -kernel /arch/x86/boot/bzImage
which launch the kernel in "stopped" state
3) Thus I have to use gdb, I try the following command:
gdb ./vmlinux
which run it correctly but... Now I don't know what to do... I know that I have to use remote debugging on the port 1234 (default port used by Qemu), using the vmlinux as the symbol table file for debugging.
So my question is: What should I do to run the kernel on Qemu, attach my debugger to it and thus, get them work together to make my life easier with kernel development.
I'd try:
(gdb) target remote localhost:1234
(gdb) continue
Using the '-s' option makes qemu listen on port tcp::1234, which you can connect to as localhost:1234 if you are on the same machine. Qemu's '-S' option makes Qemu stop execution until you give the continue command.
Best thing would probably be to have a look at a decent GDB tutorial to get along with what you are doing. This one looks quite nice.
Step-by-step procedure tested on Ubuntu 16.10 host
To get started from scratch quickly I've made a minimal fully automated QEMU + Buildroot example at: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/c7bbc6029af7f4fab0a23a380d1607df0b2a3701/gdb-step-debugging.md Major steps are covered below.
First get a root filesystem rootfs.cpio.gz. If you need one, consider:
a minimal init-only executable image: https://unix.stackexchange.com/questions/122717/custom-linux-distro-that-runs-just-one-program-nothing-else/238579#238579
a Busybox interactive system: https://unix.stackexchange.com/questions/2692/what-is-the-smallest-possible-linux-implementation/203902#203902
Then on the Linux kernel:
git checkout v4.15
make mrproper
make x86_64_defconfig
cat <<EOF >.config-fragment
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_KERNEL=y
CONFIG_GDB_SCRIPTS=y
EOF
./scripts/kconfig/merge_config.sh .config .config-fragment
make -j"$(nproc)"
qemu-system-x86_64 -kernel arch/x86/boot/bzImage \
-initrd rootfs.cpio.gz -S -s \
-append nokaslr
On another terminal, from inside the Linux kernel tree, supposing you want to start debugging from start_kernel:
gdb \
-ex "add-auto-load-safe-path $(pwd)" \
-ex "file vmlinux" \
-ex 'set arch i386:x86-64:intel' \
-ex 'target remote localhost:1234' \
-ex 'break start_kernel' \
-ex 'continue' \
-ex 'disconnect' \
-ex 'set arch i386:x86-64' \
-ex 'target remote localhost:1234'
and we are done!!
For kernel modules see: How to debug Linux kernel modules with QEMU?
For Ubuntu 14.04, GDB 7.7.1, hbreak was needed, break software breakpoints were ignored. Not the case anymore in 16.10. See also: https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/901944
The messy disconnect and what come after it are to work around the error:
Remote 'g' packet reply is too long: 000000000000000017d11000008ef4810120008000000000fdfb8b07000000000d352828000000004040010000000000903fe081ffffffff883fe081ffffffff00000000000e0000ffffffffffe0ffffffffffff07ffffffffffffffff9fffff17d11000008ef4810000000000800000fffffffff8ffffffffff0000ffffffff2ddbf481ffffffff4600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000
Related threads:
https://sourceware.org/bugzilla/show_bug.cgi?id=13984 might be a GDB bug
Remote 'g' packet reply is too long
http://wiki.osdev.org/QEMU_and_GDB_in_long_mode osdev.org is as usual an awesome source for these problems
https://lists.nongnu.org/archive/html/qemu-discuss/2014-10/msg00069.html
nokaslr: https://unix.stackexchange.com/questions/397939/turning-off-kaslr-to-debug-linux-kernel-using-qemu-and-gdb/421287#421287
Known limitations:
the Linux kernel does not support (and does not even compile without patches) with -O0: How to de-optimize the Linux kernel to and compile it with -O0?
GDB 7.11 will blow your memory on some types of tab completion, even after the max-completions fix: Tab completion interrupt for large binaries Likely some corner case which was not covered in that patch. So an ulimit -Sv 500000 is a wise action before debugging. Blew up specifically when I tab completed file<tab> for the filename argument of sys_execve as in: https://stackoverflow.com/a/42290593/895245
See also:
https://github.com/torvalds/linux/blob/v4.9/Documentation/dev-tools/gdb-kernel-debugging.rst official Linux kernel "documentation"
Linux kernel live debugging, how it's done and what tools are used?
When you try to start vmlinux exe using gdb, then first thing on gdb is to issue cmds:
(gdb) target remote localhost:1234
(gdb) break start_kernel
(continue)
This will break the kernel at start_kernel.
BjoernID's answer did not really work for me. After the first continuation, no breakpoint is reached and on interrupt, I would see lines such as:
0x0000000000000000 in ?? ()
(gdb) break rapl_pmu_init
Breakpoint 1 at 0xffffffff816631e7
(gdb) c
Continuing.
^CRemote 'g' packet reply is too long: 08793000000000002988d582000000002019[..]
I guess this has something to do with different CPU modes (real mode in BIOS vs. long mode when Linux has booted). Anyway, the solution is to run QEMU first without waiting (i.e. without -S):
qemu-system-x86_64 -enable-kvm -kernel arch/x86/boot/bzImage -cpu SandyBridge -s
In my case, I needed to break at something during boot, so after some deciseconds, I ran the gdb command. If you have more time (e.g. you need to debug a module that is loaded manually), then the timing doesn't really matter.
gdb allows you to specify commands that should be run when started. This makes automation a bit easier. To connect to QEMU (which should now already be started), break on a function and continue execution, use:
gdb -ex 'target remote localhost:1234' -ex 'break rapl_pmu_init' -ex c ./vmlinux
As for me the best solution for debugging the kernel - is to use gdb from Eclipse environment. You should just set appropriate port for gdb (must be the same with one you specified in qemu launch string) in remote debugging section. Here is the manual:
http://www.sw-at.com/blog/2011/02/11/linux-kernel-development-and-debugging-using-eclipse-cdt/
On Linux systems, vmlinux is a statically linked executable file that contains
the Linux kernel in one of the object file formats supported by Linux, which
includes ELF, COFF and a.out. The vmlinux file might be required for kernel
debugging, symbol table generation or other operations, but must be made
bootable before being used as an operating system kernel by adding a multiboot
header, bootsector and setup routines.
An image of this initial root file system must be stored somewhere accessible
by the Linux bootloader to the boot firmware of the computer. This can be the
root file system itself, a boot image on an optical disc, a small partition on
a local disk (a boot paratition, usually using ext4 or FAT file systems), or a
TFTP server (on systems that can boot from Ethernet).
Compile linux kernel
Build the kernel with this series applied, enabling CONFIG_DEBUG_INFO (but leave CONFIG_DEBUG_INFO_REDUCED off)
https://www.kernel.org/doc/html/latest/admin-guide/README.html
https://wiki.archlinux.org/index.php/Kernel/Traditional_compilation
https://lwn.net/Articles/533552/
Install GDB and Qemu
sudo pacman -S gdb qemu
Create initramfs
#!/bin/bash
# Os : Arch Linux
# Kernel : 5.0.3
INIT_DIR=$(pwd)
BBOX_URL="https://busybox.net/downloads/busybox-1.30.1.tar.bz2"
BBOX_FILENAME=$(basename ${BBOX_URL})
BBOX_DIRNAME=$(basename ${BBOX_FILENAME} ".tar.bz2")
RAM_FILENAME="${INIT_DIR}/initramfs.cpio.gz"
function download_busybox {
wget -c ${BBOX_URL} 2>/dev/null
}
function compile_busybox {
tar xvf ${BBOX_FILENAME} && cd "${INIT_DIR}/${BBOX_DIRNAME}/"
echo "[*] Settings > Build options > Build static binary (no shared libs)"
echo "[!] Please enter to continue"
read tmpvar
make menuconfig && make -j2 && make install
}
function config_busybox {
cd "${INIT_DIR}/${BBOX_DIRNAME}/"
rm -rf initramfs/ && cp -rf _install/ initramfs/
rm -f initramfs/linuxrc
mkdir -p initramfs/{dev,proc,sys}
sudo cp -a /dev/{null,console,tty,tty1,tty2,tty3,tty4} initramfs/dev/
cat > "${INIT_DIR}/${BBOX_DIRNAME}/initramfs/init" << EOF
#!/bin/busybox sh
mount -t proc none /proc
mount -t sysfs none /sys
exec /sbin/init
EOF
chmod a+x initramfs/init
cd "${INIT_DIR}/${BBOX_DIRNAME}/initramfs/"
find . -print0 | cpio --null -ov --format=newc | gzip -9 > "${RAM_FILENAME}"
echo "[*] output: ${RAM_FILENAME}"
}
download_busybox
compile_busybox
config_busybox
Boot Linux Kernel With Qemu
#!/bin/bash
KER_FILENAME="/home/debug/Projects/kernelbuild/linux-5.0.3/arch/x86/boot/bzImage"
RAM_FILENAME="/home/debug/Projects/kerneldebug/initramfs.cpio.gz"
qemu-system-x86_64 -s -kernel "${KER_FILENAME}" -initrd "${RAM_FILENAME}" -nographic -append "console=ttyS0"
$ ./qemuboot_vmlinux.sh
SeaBIOS (version 1.12.0-20181126_142135-anatol)
iPXE (http://ipxe.org) 00:03.0 C980 PCI2.10 PnP PMM+07F92120+07EF2120 C980
Booting from ROM...
Probing EDD (edd=off to disable)... o
[ 0.019814] Spectre V2 : Spectre mitigation: LFENCE not serializing, switching to generic retpoline
can't run '/etc/init.d/rcS': No such file or directory
Please press Enter to activate this console.
/ # uname -a
Linux archlinux 5.0.3 #2 SMP PREEMPT Mon Mar 25 10:27:13 CST 2019 x86_64 GNU/Linux
/ #
Debug Linux Kernel With GDB
~/Projects/kernelbuild/linux-5.0.3 ➭ gdb vmlinux
...
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0xffffffff89a4b852 in ?? ()
(gdb) break start_kernel
Breakpoint 1 at 0xffffffff826ccc08
(gdb)
Display all 190 possibilities? (y or n)
(gdb) info functions
All defined functions:
Non-debugging symbols:
0xffffffff81000000 _stext
0xffffffff81000000 _text
0xffffffff81000000 startup_64
0xffffffff81000030 secondary_startup_64
0xffffffff810000e0 verify_cpu
0xffffffff810001e0 start_cpu0
0xffffffff810001f0 __startup_64
0xffffffff81000410 pvh_start_xen
0xffffffff81001000 hypercall_page
0xffffffff81001000 xen_hypercall_set_trap_table
0xffffffff81001020 xen_hypercall_mmu_update
0xffffffff81001040 xen_hypercall_set_gdt
0xffffffff81001060 xen_hypercall_stack_switch
0xffffffff81001080 xen_hypercall_set_callbacks
0xffffffff810010a0 xen_hypercall_fpu_taskswitch
0xffffffff810010c0 xen_hypercall_sched_op_compat
0xffffffff810010e0 xen_hypercall_platform_op
I'm using a Blue Pill board (STM32F103CB with 128kB of flash according to st-info --probe) via a clone ST-Link/V2 like this one. I've also tested using a genuine ST-Link/V2 like this one. I get the same result, described below, with both programmers.
My system is Linux (Debian LXDE) and I've installed OpenOCD from Liviu Ionescu's releases here.
My OpenOCD installation is working. As well as the Blue Pill I have a ST-Nucleo-F103RB board, and I can connect to it using OpenOCD. The command
openocd -f board/st_nucleo_f103rb.cfg
using the standard .cfg file that ships with OpenOCD gives
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
none separate
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : clock speed 950 kHz
Info : STLINK v2 JTAG v29 API v2 SWIM v18 VID 0x0483 PID 0x374B
Info : using stlink api v2
Info : Target voltage: 3.271135
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
But I still haven't managed to connect to my Blue Pill using the ST-Link/V2 programmers. I've read everything I can find, including relevant sections of https://elinux.org/Category:OpenOCD and as much as I can personally digest of http://openocd.org/doc/. The following is where I've got to.
The .cfg file stm32f103c8_blue_pill.cfg doesn't work for me. It produces the output described below.
Based on what I've read I've prepared my own .cfg file at ../board/stm32f103.cfg. It says:
source [find interface/stlink.cfg]
transport select hla_swd
source [find target/stm32f1x.cfg]
#source [find board/stm32f103c8_blue_pill.cfg]
#reset_config srst_only
#reset_config none separate
Sources I've read suggest this should work, but it doesn't. Using my .cfg described above, it I can use either target/stm32f1x.cfg or board/stm32f103c7_blue_pill.cfg, and I still get the same output as described below. (In the case of both of those .cfg files I'm using the standard files, as shipped with OpenOCD.) I've tested with both of the reset_config variants shown above, and with neither. None of the combinations works.
The file interface/stlink.cfg that I'm using is modified. I've changed it to state the correct device_desc "ST-LINK/V2" and the correct vid_pid 0x0483 0x3748. (Both confirmed using lsusb.) So, ignoring commented lines, stlink.cfg reads
interface hla
hla_layout stlink
hla_device_desc "ST-LINK/V2"
hla_vid_pid 0x0483 0x3748
I've experimented with including the hla_serial of the programmer. Interestingly, lsusb can't find the full serial number. st-info --probe finds the serial number, but gives a slightly different number from the STLinkUpgrade firmware application. I've tried using both serial numbers. No difference.
Here's the command I give to OpenOCD:
openocd -s ~/stm32/openocd/scripts -f board/stm32f103.cfg
Notice that I have to set the path using -s for this command. With the ST-Nucleo-F103RB board, I don't have to do this. With the stm32f103.cfg file, however, if I don't set the path I get:
Error: Can't find board/stm32f103.cfg
in procedure 'script'
If I use the full command shown above, with -s to set the path, I get:
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
/[..]stm32/openocd/scripts/target/stm32f1x.cfg:47: Error: invalid command name "dap"
in procedure 'script'
at file "embedded:startup.tcl", line 60
at file "/[..]stm32/openocd/scripts/board/stm32f103.cfg", line 18
at file "/[..]stm32/openocd/scripts/target/stm32f1x.cfg", line 47
Here's the offending line 47 of stm32f1x.cfg:
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
I've searched for items on Stackoverflow/ similar about Error: invalid command name "dap". Using the OpenOCD documentation I understand that the dap create command exists, and roughly what it does. The most similar reported error I've found documented is at https://elinux.org/OpenOCD_Troubleshooting:_Invalid_Command_Name_JTAG, and the solution suggested there doesn't seem to be applicable because I'm not invoking interface/stlink.cfg from the command line.
I can't see what I'm doing wrong, and I'm now completely stuck. If someone can give me a steer I'd be really grateful. Sorry it's such a long post.
I just encountered this problem too. Officially there are no binaries provided, only source code. But there are two sites which release binaries was recommended by OpenOCD official:
1. Maintained by Freddie Chopin.
2. Maintained by Liviu Ionescu in Github.
I tried the latest version(OpenOCD 0.10.0 commit date: 2017-01-22 20:31:28 build date: 2017-01-23) released from Freddie Chopin's site, and I encountered this Error: invalid command name "dap" problem. But all *.cfg files I referenced had ran normally in my another computer with another OpenOCD binary(although I forgot where did I download that binary).
Not sure what went wrong, so I turned to the latest version(gnu-mcu-eclipse-openocd-0.10.0-11-20190118-1134-win64.zip) released by GNU MCU Eclipse(maintained by Liviu Ionescu), the error was gone, problem solved.
PS: I'm not saying there is a bug in Freddie Chopin's build, but if someone encountered this problem, maybe you can solve it by trying the version which is currently under actively maintained.
Agree with Wulfric, using standard install for OpenOCD
sudo apt install openocd
gave the "dap" error.
However the github version openocd-xpack worked correctly.
Using:
Linux clamps 4.15.0-66-generic #75-Ubuntu SMP ... as remote, Windows 8/10 as client target MIMXRT1010-EVK
I am trying to write simple program, that uses libftdi, and I have come across a strange problem.
When running the program as non-root it looks like this:
./BoxDriver
Naruszenie ochrony pamięci (zrzut pamięci)
And in Dmesg the last line I see is:
[ 3320.467864] BoxDriver[4205]: segfault at 0 ip 00007f05c2821f7a sp 00007ffd9c6c9c00 error 4 in libftdi.so.1.20.0[7f05c2820000+7000]
I am using Ubuntu:
Linux AdamsPC 3.19.0-30-generic #34-Ubuntu SMP Fri Oct 2 22:08:41 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
And FTDI device:
Bus 001 Device 011: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC
The program runs fine, when it is running as a root:
sudo ./BoxDriver
OK, started
I have also tried to debug the source code (in eclipse ang gcc, no seg fault occurred), and the problem is with:
ftdi_usb_open(ftc, 0x0403, 0x6010)
It always returns -8, that stands for : "get product description failed"
I have searched for any answer, most are about adding user to dialout group, or adding rule to udev, but none of answers I have founded worked.
Any suggestions are highly appreciated. Thanks
There is a few different ways to fix this but generally it sounds like your user account does not have permission to interface with the USB device. You could add the user to the appropriate group I believe for ubuntu that is dialout so.
sudo usermod -a -G dialout user
Alternatively if multiple accounts need to use it but they all should have permissions you could change the filesystem it's mounted to to have full permissions.
sudo chmod 777 /media/drive_name
We are trying to track down a Conditional jump or move depends on uninitialised value in a C++ project reported by Valgrind. The address provided in the finding is not really helpful because it points to the end of a GCC extended assembly block, and not the actual variable causing the trouble.
According to the Valgrind's Eliminating undefined values with Valgrind, the easy way, we can use VALGRIND_CHECK_MEM_IS_DEFINED or VALGRIND_CHECK_VALUE_IS_DEFINED after including <memcheck.h>. Additionally, those macros or functions are apparently documented in the header file (there is definitely no man page for them).
However, when I include <memcheck.h> or <valgrind/memcheck.h>, it results in:
fatal error: memcheck.h: No such file or directory
Based on Stack Overflow's How do I find which rpm package supplies a file I'm looking for?, I performed a RPM file search, but its returning 0 hits for memcheck.h.
QUESTIONS
The blog article is a bit dated. Does the information still apply?
If the information is accurate, then where do I find memcheck.h?
$ uname -a
Linux localhost.localdomain 4.1.4-200.fc22.x86_64 #1 SMP Tue Aug 4 03:22:33 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
$ g++ --version
g++ (GCC) 5.1.1 20150618 (Red Hat 5.1.1-4)
...
$ valgrind --version
valgrind-3.10.1
You have to install the RPM valgrind-devel which contains memcheck.h.
The *-devel packages are typically located in the "optional" repositories (e.g. rhel-x86_64-server-optional-6 on RHEL 6). Also, you can find the RPM on Google, download it, and install it on its own. With either approach, memcheck.h is typically placed in /usr/include/valgrind once installed.
Another way to dig into uninitialised value error with valgrind is to
use the embedded gdbserver.
You can then put breakpoints in your program, and interactively
check the definedness of various addresses/length using various
memcheck monitor commands such as:
check_memory [addressable|defined] <addr> [<len>]
check that <len> (or 1) bytes at <addr> have the given accessibility
and outputs a description of <addr>
See e.g. http://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.monitor-commands
for more information
On a Windows(R) machine the following function can be used for querying the system power status of the machine:
BOOL WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS lpSystemPowerStatus);
Is there something similar for a Linux machine?
On most linux systems a daemon named acpid runs all the time monitoring for ACPI events and normally logs info to /var/log/acpid or /var/log/messages. There is a manpage for it at http://linux.die.net/man/8/acpid. acpid stores current ACPI info in /proc/acpi although that's being relocated to /sys somewhere and /sys/power/state holds the current power state seen by catting it (cat /sys/power/state). More info about ACPI is at http://acpi.sourceforge.net/documentation/sleep.html. JCM mentioned a command line tool for ACPI status monitoring named AcpiTool available at http://sourceforge.net/projects/acpitool/. I built that on CentOS and it works fine. Just follow the instructions in its INSTALL file to install it -- it requires a C++ compiler, which is commonly on linux or if not install one using yum or apt.
dmidecode can do many kinds of queries for low level issues including system power supply and controls, see http://linux.die.net/man/8/dmidecode
In collaboration with freedesktop.org RedHat developed and provides DeviceKit-power pre RH7 which is called UPower starting with RH7. It consists of a daemon and command line tool. A manpage for it is at http://www.pkill.info/linux/man/1-upower/. The --dump option of the command line tool provides some useful info but rarely up to date. Maybe restarting the daemon would cause an update. Here is an example of the output from a CentOS 6 host:
ca:17: devkit-power --dump
Device: /org/freedesktop/DeviceKit/Power/devices/line_power_ACAD
native-path: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0003:00/power_supply/ACAD
power supply: yes
updated: Tue Dec 23 20:28:27 2014 (866 seconds ago)
has history: no
has statistics: no
line-power
online: yes
Daemon:
daemon-version: 014
can-suspend: no
can-hibernate yes
on-battery: no
on-low-battery: no
lid-is-closed: no
lid-is-present: no
Most major PC vendors such as Dell and HP provide their own apps for power management and monitoring and I've found it is best to use them because they know how to query custom probes designed into the HW and print full diagnostics for their support team.
On My Ubuntu system I found this Information in /sys/class/power_suply/ADP1/online .
For example I used it in a script in an If statement with the following code:
if (( CPUBenutzung > 11 )) || ! (( $(cat /sys/class/power_suply/ADP1/online) )); then Stopmining ; fi
for me this worked fine and stopped the mining process allways when there was no power connected or I did use for some other reason all 12 threads of my notebook.