Using debug symbols with perf - symbols

I monitor a process on a PowerPC system in order to extract performance information.
How I can load the debug symbols of this process?
I use the following command
perf record -g dwarf -p 4591
and I take an error that the "dwarf cannot be found (no such file or directory)"
Could you please give me a hint how to load debug information about the functions that have been called when the report is generated?

You are using an old version of perf which do not support -g dwarf but only -g (without argument) i.e. it does not support DWARF unwinding.

perf record -g dwarf -p 4591
These days the correct option to chose a method is --call-graph whereas -g is only a flag to enable call stacks with it's default method fp.
from man perf-record.
-g
Enables call-graph (stack chain/backtrace) recording.
--call-graph
Setup and enable call-graph (stack chain/backtrace) recording,
implies -g. Default is "fp".
Allows specifying "fp" (frame pointer) or "dwarf"
(DWARF's CFI - Call Frame Information) or "lbr"
(Hardware Last Branch Record facility) as the method to collect
the information used to show the call graphs.
In some systems, where binaries are build with gcc
--fomit-frame-pointer, using the "fp" method will produce bogus
call graphs, using "dwarf", if available (perf tools linked to
the libunwind or libdw library) should be used instead.
Using the "lbr" method doesn't require any compiler options. It
will produce call graphs from the hardware LBR registers. The
main limitation is that it is only available on new Intel
platforms, such as Haswell. It can only get user call chain. It
doesn't work with branch stack sampling at the same time.
When "dwarf" recording is used, perf also records (user) stack dump
when sampled. Default size of the stack dump is 8192 (bytes).
User can change the size by passing the size after comma like
"--call-graph dwarf,4096".
By the way, try fp first - it's much more efficient, but doesn't work well with optimized binaries (e.g. --fomit-frame-pointer). Also this has very little to do with debug information. If you do not need to know the stack trace, you needn't add -g.

Related

How does pointer data stored in MachO __objc_classlist section rebased when run a iOS app?

In MachOView, I can see that in a iOS binary file, class pointers are stored in section __objc_classlist. They are absolute address values which point to class Data in section __objc_data. But we known that iOS use ASLR, so when loaded, the real address must be different.
I checked the "getsectiondata" method, can not found any rebase logic.
So the question is:
when and how does the pointer Data rebased?
Is the rebased data dirty?
dyld handles rebasing as part of loading the binary, long before you call getsectiondata. The LC_DYLD_INFO_ONLY load command within the binary points to the rebase opcodes which contain information about which addresses to update and how.
You can use xcrun dyldinfo -rebase <binary> to see the list of addresses that dyld will rebase. You'll see entries for each class within __DATA,__objc_classlist. You can set DYLD_PRINT_REBASINGS=1 in the environment prior to launch to have dyld print out each address it rebases.
And yes, since dyld modifies data as it rebases it, the page no longer matches the underlying storage and is dirty. Avoiding dirtying pages during load has been a motivation for switching some Objective-C data structures from using pointers to relative offsets.

Prevent ArmClang to add calls to Standard C library

I am evaluating Keil Microvision IDE on STM32H753.
I am doing compiler comparison between ARMCC5 and AC6 in the different optimisation levels. AC6 is based on Clang.
My code is not using memcpy and I have unchecked "Use MicroLIB" in the project settings , However a basic byte per byte copy loop in my code is replaced by a memcpy with AC6 (only in "high" optimisation levels). It doesn't happen with ARMCC5.
I tried using compilation options to avoid that, as described here: -ffreestanding and -disable-simplify-libcalls, at both compiler and linker levels but it didn't change (for the second option, I get an error message saying that the option is not supported).
In the ARMCLANG reference guide i've found the options -nostdlib -nostdlibinc that prevent (??) the compiler to use any function of a standard lib.
However I still need the math.h function.
Do you know how to prevent clang to use functions from the Standard C Lib that are not explicitely called in the code ?
EDIT: here is a quick and dirty reproduceable example:
https://godbolt.org/z/AX8_WV
Please do not discuss the quality of this example, I know it is dumb !!, I know about memset, etc... It is just to understand the issue
gcc know a lot about the memcpy, memset and similar functions and even they are called "the builtin functions". If you do not want those functions to be used by default just use the command line option -fno-builtin
https://godbolt.org/z/a42m4j

How can you tell if your Java program is running in a GraalVM AOT context?

I have a little Java program. I build a binary using Graal's native-image (i.e. GraalVM AOT aka SubstrateVM).
My program can be executed either with a Java runtime or from the native-image binary. What's the best way to tell which context I'm running in?
(This might be a bad practice in general but I believe it's inevitable/necessary in certain not-uncommon circumstances.)
Edit: There is now an API for that. See user7983712's answer.
The way it's done in the GraalVM is by capturing the com.oracle.graalvm.isaot system property: it is set to true while building AOT images. If you combine that with the fact that static initializers run during image generation, you can use
static final boolean IS_AOT = Boolean.getBoolean("com.oracle.graalvm.isaot")
This boolean will remain true when running the native image.
This is also useful to cut-off paths that you don't want in the final output: for example if you have some code that uses a feature that SVM doesn't support (e.g., dynamic class-loading) you can predicate it with !IS_AOT.
GraalVM now provides an API for checking the AOT context:
ImageInfo.inImageCode()
ImageInfo.inImageRuntimeCode()
ImageInfo.inImageBuildtimeCode()
ImageInfo.isExecutable()
ImageInfo.isSharedLibrary()
I'm leaning towards checking the presence/absence of some system properties. When I print out the system properties under Graal AOT I see:
{os.arch=x86_64, file.encoding=UTF-8, user.home=/Users/thom, path.separator=:, os.name=Mac OS X, user.dir=/Users/thom, line.separator=
, sun.jnu.encoding=UTF-8, file.separator=/, java.io.tmpdir=/var/folders/0x/rms5rjn526x33rm394xwmr8c0000gn/T/, user.name=thom}
As you may notice it's fairly short and is missing all the usual java.* ones such as java.class.path. I'll omit listing the lengthy Java version and instead link to another SO listing the usual Java System properties:
What is the full list of standard keys recognized by the Java System.getProperty() method?
So one way to do it would seem to be to check whether one or more of the java.* properties are absent.
AFAIK there are no plans to set these in SubstrateVM. But System properties are mutable so one could possibly choose to fake them.
But anyway here's a way to do it:
def isGraalAOT = System.properties.getProperty("java.class.path") == null

lldb 'step into' can't jump into function call on Xcode7?

I use Xcode7 to debug a App.
Seems step into behave like the step over, can't jump into the execution of a sub procedure? It's just jump to the next line in the source code each time.
And if I'm debug in the UIKit method(I don't have source code), it's jump to the next instruction.
As you have found, step-in avoids frames with no debug information. Most people like to just hit one step command, rather than switching between step & next depending on the line they are on, and in my experience, tend to choose step. This is made more pleasant if the debugger doesn't stop in printf & other code you have no debug info for.
However, lldb's "step" command has an option to control this:
-a <boolean> ( --step-in-avoids-no-debug <boolean> )
A boolean value that sets whether stepping into functions will step over functions with no debug information.
If you use this frequently, you can either reset the step alias to include this option, or make another alias that includes it. Use the command alias command to do this.
And if you always want step-in to step into code with no debug information, just set the global setting:
settings set target.process.thread.step-in-avoid-nodebug 0
either at the start of a debug session or in your .lldbinit.
Note, most of lldb's commands are documented in the help system. For instance, help step would have shown the above option for the step command, and apropos step would have shown the setting.
From GDB Manual:
Also, the step command only enters a function if there is line number information for the function. Otherwise it acts like the next command. This avoids problems when using cc -gl on MIPS machines. Previously, step entered subroutines if there was any debugging information about the routine.
And I found Step into works well when I have source file.
So maybe I have make a mistake. But the lldb is very lack of documents.

gcov froze when giving -a option?

When I do gcov . there is no problems. However, when I do gcov -a . gcov froze. The last few lines of the output is:
File '/usr/include/boost/archive/detail/iserializer.hpp'
Lines executed:78.18% of 55
/usr/include/boost/archive/detail/iserializer.hpp:creating 'iserializer.hpp.gcov'
File '/usr/include/boost/serialization/extended_type_info_typeid.hpp'
Lines executed:40.74% of 27
/usr/include/boost/serialization/extended_type_info_typeid.hpp:creating 'extended_type_info_typeid.hpp.gcov
Do you know why that is happening ? The reason I need "-a" is when I use lcov, it gives that option to gcov, I can hack geninfo to ignore that option but I prefer not to since I'll eventually run lcov on a public system.
Thank you for any inputs!
I also have code that uses boost::serialization - the lcov process isn't /frozen/, it just takes a very very long time to run. I have had it complete successfully after several hours, and I finally do get a nice lcov report.
It would be lovely to be able to exclude processing of the boost serialization code when running lcov -c but I have not been able to figure out exactly how to do that yet. (Of course, I /want/ to get coverage over the code that uses boost serialization, but not the boost headers themselves) Even putting // LCOV_EXCL_START & LCOV_EXCL_STOP around the majority of the serialization code doesn't work, as I think those exclusion markers are only used when genhtml is called, not on lcov -c.

Resources