Windows compatibility (.exe ARM tools)
nono313 opened this issue · comments
I managed to build and install puncover on my Windows 10 machine.
When I try to run it, I get the following error :
parsing ELF at firmware.elf Traceback (most recent call last): File "C:\Python\Python37-32\Scripts\puncover-script.py", line 11, in <module> load_entry_point('puncover==0.0.1', 'console_scripts', 'puncover')() File "C:\Python\Python37-32\lib\site-packages\puncover-0.0.1-py3.7.egg\puncover\puncover.py", line 58, in main builder.build_if_needed() File "C:\Python\Python37-32\lib\site-packages\puncover-0.0.1-py3.7.egg\puncover\builders.py", line 32, in build_if_needed self.build() File "C:\Python\Python37-32\lib\site-packages\puncover-0.0.1-py3.7.egg\puncover\builders.py", line 22, in build self.collector.parse_elf(self.get_elf_path()) File "C:\Python\Python37-32\lib\site-packages\puncover-0.0.1-py3.7.egg\puncover\collector.py", line 306, in parse_elf self.parse_assembly_text("".join(self.gcc_tools.get_assembly_lines(elf_file))) File "C:\Python\Python37-32\lib\site-packages\puncover-0.0.1-py3.7.egg\puncover\gcc_tools.py", line 27, in get_assembly_lines return self.gcc_tool_lines('objdump', ['-dslw', os.path.basename(elf_file)], os.path.dirname(elf_file)) File "C:\Python\Python37-32\lib\site-packages\puncover-0.0.1-py3.7.egg\puncover\gcc_tools.py", line 23, in gcc_tool_lines proc = subprocess.Popen([self.gcc_tool_path(name)] + args, stdout=subprocess.PIPE, cwd=cwd) File "C:\Python\Python37-32\lib\site-packages\puncover-0.0.1-py3.7.egg\puncover\gcc_tools.py", line 18, in gcc_tool_path raise Exception("Could not find %s" % path) Exception: Could not find C:\Program Files\...\gcc\arm-none-eabi\bin\objdump
As this is Windows, the objdump tool do exist but as a 'objdump.exe' file, not as 'objdump'.
Would it be possible to check for .exe file and use them for Windows users ?
I am not sure puncover will word on Windows at all as this hasn't been tested. Adding .exe
to the various executable paths sounds easy enough but traditionally there are more issues with Windows vs. non-Windows systems that are in the details.
Before going down that rabbit whole and backing Windows support via CI: Did you try running its unit-tests from source? That would give some early signal about the general feasibility of using puncover on Windows.
I have run the command python -m unittest
which I assume is what should be used to execute the unit tests (tell me if I'm wrong), and I do get a lot of errors but all related to the same thing it seems.
It seems that it's mostly the program looking for a root / and an assert checking paths with / and not .
I am also trying to run pancover on windows, a fast change of some files made it run and the unit test returned 3 errors, which are a mismatch of paths and looks okay.
Running it i only see a partly a overview, gcc was setup to create the stack usage files. It seems for me somewhere else is matching problem between file names and symbol names.
Perhaps it helps to get an idea, where to search for more os dependencies, or you have an idea what i could check to make it work additionally on windows.
gcc_tool_path(self, name):
if os.name == 'nt':
path = self.gcc_base_filename + name + ".exe"
else:
path = self.gcc_base_filename + name`
normalize_files_paths
And modifying the normalize_files_paths
def normalize_files_paths(self, base_dir):
base_dir = os.path.abspath(base_dir) if base_dir else os.path.sep
for s in self.all_symbols():
path = s.get(PATH, None)
if path:
if path.startswith(base_dir):
path = os.path.relpath(path, base_dir)
elif path.startswith(os.path.sep):
path = path[1:]
s[PATH] = path
and file_element_
def file_element_for_path(self, path, type, default_values):
if not path:
return None
result = self.file_elements.get(path, None)
if not result:
parent_dir = os.path.dirname(path)
parent_folder = self.folder_for_path(parent_dir) if parent_dir and parent_dir != os.path.sep else None
result = {
TYPE: type,
PATH: path,
FOLDER: parent_folder,
NAME: os.path.basename(path),
}
for k, v in default_values.items():
result[k] = v
self.file_elements[path] = result
return result if result[TYPE] == type else None
edit
so it seems to be the different regex in the collector.py don't like the windows path c:/
changing that also make it more usable. Still seem to be a few things missing
if os.name == 'nt':
parse_size_line_re = re.compile(r"^([\da-f]{8})\s+([\da-f]{8})\s+(.)\s+(\w+)(\s+([\w]:)([^:]+):(\d+))?")
else:
parse_size_line_re = re.compile(r"^([\da-f]{8})\s+([\da-f]{8})\s+(.)\s+(\w+)(\s+([^:]+):(\d+))?")
Hello,
before I saw this post i fixed the problem in my own way. You can see the results of my changes in the attached patch-file. If you have any questions about my changes then feel free to concat me.
Thank you @ckak07. I managed to run puncover on Windows thanks to your patch.
Maybe this could be included in a PR for integration ?
@ckak07 Thanks for the patch, this works perfectly 👍
Just a side note, I think the regex pattern suggested by @tobiwan88 is wrong.
This is the regex output you get with his suggestion
https://regex101.com/r/elYiD0/1
As you see match group for file is number 7 and for the line it is match group 8. However, in the code the match groups should be 6 and 7 respectively
puncover/puncover/collector.py
Lines 134 to 135 in ec63f21
My suggestion is to change the pattern for windows to be
parse_size_line_re = re.compile(r"^([\da-f]{8})\s+([\da-f]{8})\s+(.)\s+(\w+)(\s+([a-zA-Z]:.+)):(\d+)?")
See example
Just an FYI. I fixed the OS path dependency issue. Feel free to test my changes