← Back to team overview

kicad-developers team mailing list archive

Separated debug symbols

 

What do you think about providing archives with debug symbols for
Windows builds? It is a platform where we rarely get a stacktrace,
because the process is not trivial and Windows debug builds take lots of
space (_pcbnew.kiface is ~1.5 GB on my PC). Normally it would be wasted
bandwidth, but from time to time we get bug reports which noone else can
reproduce and then a stacktrace would be of great help.

I have written a patch that adds a CMake flag to split debug information
to another file. This way we could offer compact binaries to the users
and ask them to download debug information only in case of serious
problems. There is already GDB shipped with the nightly installers, so
then getting a stacktrace becomes feasible or we could use catchsegv [1]
for an automated approach (see the attached example log; do not worry
about the null pointer dereference - I added it temporarily to test the
software). Obviously, Thomas' crash reporter looks even more convenient,
but it is not mingw-gcc compatible [2]. The patch is also compatible
with BUILD_SMALL_DEBUG_FILES flag.

I have not pushed the patch yet, as I still wonder whether adding
another CMake flag is a good idea. Just now I realized that there are
just a few extra commands to create the needed files, so perhaps they
could be executed by the build scripts on Jenkins hosts.

Cheers,
Orson

1. https://github.com/jrfonseca/drmingw/tree/master/src/catchsegv
2.
https://docs.wxwidgets.org/3.0/group__group__funcmacro__appinitterm.html#ga28a4fb827b93fa6bac18c9666c23ee10
From 6d7f070ed838f70a739406dae24640c6831bd0b8 Mon Sep 17 00:00:00 2001
From: Maciej Suminski <maciej.suminski@xxxxxxx>
Date: Thu, 25 Oct 2018 20:51:32 +0200
Subject: [PATCH] Added KICAD_SPLIT_DEBUG CMake flag to store debug symbols as
 a separate file

---
 CMakeLists.txt                   | 12 ++++++++++++
 CMakeModules/SplitDebug.cmake    | 29 +++++++++++++++++++++++++++++
 cvpcb/CMakeLists.txt             |  4 ++++
 eeschema/CMakeLists.txt          |  5 +++++
 gerbview/CMakeLists.txt          |  5 +++++
 pagelayout_editor/CMakeLists.txt |  5 +++++
 pcb_calculator/CMakeLists.txt    |  5 +++++
 pcbnew/CMakeLists.txt            |  5 +++++
 8 files changed, 70 insertions(+)
 create mode 100644 CMakeModules/SplitDebug.cmake

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 246277826..8e646488e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -98,6 +98,10 @@ option( KICAD_INSTALL_DEMOS
     "Install KiCad demos and examples (default ON)"
     ON )
 
+option( KICAD_SPLIT_DEBUG
+    "Saves debugging data to a separate file (default OFF)"
+    OFF )
+
 # when option KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES is enabled:
 # PYTHON_EXECUTABLE can be defined when invoking cmake
 # ( use -DPYTHON_EXECUTABLE=<python path>/python.exe or python2 )
@@ -116,6 +120,14 @@ if ( KICAD_SCRIPTING_ACTION_MENU AND NOT KICAD_SCRIPTING )
     set ( KICAD_SCRIPTING ON )
 endif()
 
+if( KICAD_SPLIT_DEBUG )
+    if( NOT CMAKE_BUILD_TYPE STREQUAL "Debug" )
+        message( WARNING "KICAD_SPLIT_DEBUG makes sense only for debug builds" )
+    endif()
+
+    include( SplitDebug )
+endif()
+
 option( BUILD_GITHUB_PLUGIN "Build the GITHUB_PLUGIN for pcbnew." ON )
 
 option( KICAD_SPICE "Build KiCad with internal Spice simulator." ON )
diff --git a/CMakeModules/SplitDebug.cmake b/CMakeModules/SplitDebug.cmake
new file mode 100644
index 000000000..f85fed301
--- /dev/null
+++ b/CMakeModules/SplitDebug.cmake
@@ -0,0 +1,29 @@
+# Copyright (C) 2018 CERN
+# @author Maciej Suminski <maciej.suminski@xxxxxxx>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# SplitDebug separates debug information to another file,
+# leaving the original binary stripped and compact.
+
+function( SplitDebug target filename )
+    add_custom_command( TARGET ${target} POST_BUILD
+        COMMAND objcopy --only-keep-debug ${filename} ${filename}.debug
+        COMMAND strip --strip-debug --strip-unneeded ${filename}
+        # TODO objcopy can also take --strip-debug
+        COMMAND objcopy --add-gnu-debuglink="${filename}.debug" ${filename}
+        COMMENT "Creating a debug info file for ${filename}"
+        # OUTPUT ${filename}.debug
+    )
+endfunction()
diff --git a/cvpcb/CMakeLists.txt b/cvpcb/CMakeLists.txt
index eb77f6b68..9c7b55509 100644
--- a/cvpcb/CMakeLists.txt
+++ b/cvpcb/CMakeLists.txt
@@ -193,6 +193,10 @@ if( MAKE_LINK_MAPS )
         LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=_cvpcb.kiface.map" )
 endif()
 
+if( KICAD_SPLIT_DEBUG ) # create a debug info file and strip the output binary
+    SplitDebug( cvpcb_kiface _cvpcb.kiface )
+endif()
+
 # these 2 binaries are a matched set, keep them together:
 if( APPLE )
     # puts binaries into the *.app bundle while linking
diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt
index e56f3c849..491b2e2c2 100644
--- a/eeschema/CMakeLists.txt
+++ b/eeschema/CMakeLists.txt
@@ -376,6 +376,11 @@ set_source_files_properties( eeschema.cpp PROPERTIES
 # if building eeschema, then also build eeschema_kiface if out of date.
 add_dependencies( eeschema eeschema_kiface )
 
+if( KICAD_SPLIT_DEBUG ) # create a debug info file and strip the output binary
+    SplitDebug( eeschema_kiface _eeschema.kiface )
+    SplitDebug( eeschema "eeschema${CMAKE_EXECUTABLE_SUFFIX}" )
+endif()
+
 if( MAKE_LINK_MAPS )
     # generate link map with cross reference
     set_target_properties( eeschema_kiface PROPERTIES
diff --git a/gerbview/CMakeLists.txt b/gerbview/CMakeLists.txt
index 9f76f86a7..27a40f276 100644
--- a/gerbview/CMakeLists.txt
+++ b/gerbview/CMakeLists.txt
@@ -174,6 +174,11 @@ endif()
 # if building gerbview, then also build gerbview_kiface if out of date.
 add_dependencies( gerbview gerbview_kiface )
 
+if( KICAD_SPLIT_DEBUG ) # create a debug info file and strip the output binary
+    SplitDebug( gerbview_kiface _gerbview.kiface )
+    SplitDebug( gerbview "gerbview${CMAKE_EXECUTABLE_SUFFIX}" )
+endif()
+
 # these 2 binaries are a matched set, keep them together
 if( APPLE )
     set_target_properties( gerbview PROPERTIES
diff --git a/pagelayout_editor/CMakeLists.txt b/pagelayout_editor/CMakeLists.txt
index 4e82fab7d..2070f0888 100644
--- a/pagelayout_editor/CMakeLists.txt
+++ b/pagelayout_editor/CMakeLists.txt
@@ -148,6 +148,11 @@ endif()
 # if building pl_editor, then also build pl_editor_kiface if out of date.
 add_dependencies( pl_editor pl_editor_kiface )
 
+if( KICAD_SPLIT_DEBUG ) # create a debug info file and strip the output binary
+    SplitDebug( pl_editor_kiface _pl_editor.kiface )
+    SplitDebug( pl_editor "pl_editor${CMAKE_EXECUTABLE_SUFFIX}" )
+endif()
+
 # these 2 binaries are a matched set, keep them together:
 if( APPLE )
     set_target_properties( pl_editor PROPERTIES
diff --git a/pcb_calculator/CMakeLists.txt b/pcb_calculator/CMakeLists.txt
index 94d6ce469..9ead4402d 100644
--- a/pcb_calculator/CMakeLists.txt
+++ b/pcb_calculator/CMakeLists.txt
@@ -106,6 +106,11 @@ endif()
 # if building pcb_calculator, then also build pcb_calculator_kiface if out of date.
 add_dependencies( pcb_calculator pcb_calculator_kiface )
 
+if( KICAD_SPLIT_DEBUG ) # create a debug info file and strip the output binary
+    SplitDebug( pcb_calculator_kiface _pcb_calculator.kiface )
+    SplitDebug( pcb_calculator "pcb_calculator${CMAKE_EXECUTABLE_SUFFIX}" )
+endif()
+
 # these 2 binaries are a matched set, keep them together
 if( APPLE )
     set_target_properties( pcb_calculator PROPERTIES
diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt
index efe36a5fe..03e4715d2 100644
--- a/pcbnew/CMakeLists.txt
+++ b/pcbnew/CMakeLists.txt
@@ -700,6 +700,11 @@ add_dependencies( pcbnew pcbnew_kiface )
 # generation of autogenerated file
 add_dependencies( pcbnew_kiface_objects specctra_lexer_source_files )
 
+if( KICAD_SPLIT_DEBUG ) # create a debug info file and strip the output binary
+    SplitDebug( pcbnew_kiface "_pcbnew.kiface" )
+    SplitDebug( pcbnew "pcbnew${CMAKE_EXECUTABLE_SUFFIX}" )
+endif()
+
 # these 2 binaries are a matched set, keep them together:
 if( APPLE )
     set_target_properties( pcbnew PROPERTIES
-- 
2.19.0

Adding locale lookup path: C:\Program Files\KiCad\share\kicad\internat

Checking template path 'C:\msys64\mingw64\share\kicad\template' exists

Adding duplicate image handler for 'PNG file'

Adding duplicate image handler for 'JPEG file'

Adding duplicate image handler for 'TIFF file'

Adding duplicate image handler for 'GIF file'

Adding duplicate image handler for 'PNM file'

Adding duplicate image handler for 'PCX file'

Adding duplicate image handler for 'IFF file'

Adding duplicate image handler for 'Windows icon file'

Adding duplicate image handler for 'Windows cursor file'

Adding duplicate image handler for 'Windows animated cursor file'

Adding duplicate image handler for 'TGA file'

Adding duplicate image handler for 'XPM file'

In file ../wxWidgets-3.0.4/src/msw/statusbar.cpp at line 441: 'SendMessage(SB_GETRECT)' failed with error 0x00000000 (the operation completed successfully.).

In file ../wxWidgets-3.0.4/src/msw/statusbar.cpp at line 441: 'SendMessage(SB_GETRECT)' failed with error 0x00000000 (the operation completed successfully.).

In file ../wxWidgets-3.0.4/src/msw/statusbar.cpp at line 441: 'SendMessage(SB_GETRECT)' failed with error 0x00000000 (the operation completed successfully.).

In file ../wxWidgets-3.0.4/src/msw/statusbar.cpp at line 441: 'SendMessage(SB_GETRECT)' failed with error 0x00000000 (the operation completed successfully.).

In file ../wxWidgets-3.0.4/src/msw/statusbar.cpp at line 441: 'SendMessage(SB_GETRECT)' failed with error 0x00000000 (the operation completed successfully.).

In file ../wxWidgets-3.0.4/src/msw/statusbar.cpp at line 441: 'SendMessage(SB_GETRECT)' failed with error 0x00000000 (the operation completed successfully.).

In file ../wxWidgets-3.0.4/src/msw/statusbar.cpp at line 441: 'SendMessage(SB_GETRECT)' failed with error 0x00000000 (the operation completed successfully.).

In file ../wxWidgets-3.0.4/src/msw/statusbar.cpp at line 441: 'SendMessage(SB_GETRECT)' failed with error 0x00000000 (the operation completed successfully.).

In file ../wxWidgets-3.0.4/src/msw/statusbar.cpp at line 441: 'SendMessage(SB_GETRECT)' failed with error 0x00000000 (the operation completed successfully.).

In file ../wxWidgets-3.0.4/src/msw/statusbar.cpp at line 441: 'SendMessage(SB_GETRECT)' failed with error 0x00000000 (the operation completed successfully.).

pcbnew.exe caused an Access Violation at location 0000000003297A49 in module _pcbnew.kiface Writing to location 0000000000000000.

AddrPC           Params
0000000003297A49 0000000006F8A8E0 000000000048B040 0000000000000000  _pcbnew.kiface! ??   [C:/msys64/home/Orson/kicad/pcbnew/pcb_edit_frame.cpp @ 323]
   321:     SetGalCanvas( galCanvas );
   322:     int *a = nullptr;
>  323:     *a = 5;
   324: 
   325:     SetBoard( new BOARD() );
000000000391E28E 00000000044BC4E0 0000000000000000 0072006200000005  _pcbnew.kiface!CreateWindow  [C:/msys64/mingw64/include/wx-3.0/wx/wxcrtbase.h @ 675]
   673: 
   674: /* safe version of strlen() (returns 0 if passed NULL pointer) */
>  675: inline size_t wxStrlen(const char *s) { return s ? wxCRT_StrlenA(s) : 0; }
   676: inline size_t wxStrlen(const wchar_t *s) { return s ? wxCRT_StrlenW(s) : 0; }
   677: #ifndef wxWCHAR_T_IS_WXCHAR16
0000000000405D68 000000000048B040 0000000000000005 000000000022F501  pcbnew.exe!Player  [C:/msys64/home/Orson/kicad/common/kiway.cpp @ 329]
   327:         if( kiface )
   328:         {
>  329:             frame = (KIWAY_PLAYER*) kiface->CreateWindow(
   330:                     aParent,    // Parent window of frame in modal mode, NULL in non modal mode
   331:                     aFrameType,
0000000000401C81 000000000048B4C0 000000006A6F0BA0 0000000000373030  pcbnew.exe!OnPgmInit  [C:/msys64/home/Orson/kicad/common/single_top.cpp @ 355]
   353:     // "TOP_FRAME" is a macro that is passed on compiler command line from CMake,
   354:     // and is one of the types in FRAME_T.
>  355:     KIWAY_PLAYER* frame = Kiway.Player( appType, true );
   356: 
   357:     Kiway.SetTop( frame );
0000000000435CB1 0000000000371150 0000000000770065 0000000000000000  pcbnew.exe!OnInit  [C:/msys64/mingw64/include/wx-3.0/wx/wxcrtbase.h @ 676]
   674: /* safe version of strlen() (returns 0 if passed NULL pointer) */
   675: inline size_t wxStrlen(const char *s) { return s ? wxCRT_StrlenA(s) : 0; }
>  676: inline size_t wxStrlen(const wchar_t *s) { return s ? wxCRT_StrlenW(s) : 0; }
   677: #ifndef wxWCHAR_T_IS_WXCHAR16
   678:        WXDLLIMPEXP_BASE size_t wxStrlen(const wxChar16 *s );
0000000000438282 0000000000371150 0000000000000001 0000000077960CD0  pcbnew.exe!CallOnInit  [C:/msys64/mingw64/include/wx-3.0/wx/wxcrtbase.h @ 676]
   674: /* safe version of strlen() (returns 0 if passed NULL pointer) */
   675: inline size_t wxStrlen(const char *s) { return s ? wxCRT_StrlenA(s) : 0; }
>  676: inline size_t wxStrlen(const wchar_t *s) { return s ? wxCRT_StrlenW(s) : 0; }
   677: #ifndef wxWCHAR_T_IS_WXCHAR16
   678:        WXDLLIMPEXP_BASE size_t wxStrlen(const wxChar16 *s );
000000006A547995 0000000000000000 0000000000400000 0000000000000001  wxbase30u_gcc_custom.dll!wxEntryReal
00000000006CA24B 0000000000000000 0000000000000007 0000000000362D90  wxmsw30u_core_gcc_custom.dll!wxEntry
00000000004016EC 0000000000400000 0000000000000000 00000000005C3ED6  pcbnew.exe!WinMain  [C:/msys64/home/Orson/kicad/common/single_top.cpp @ 272]
   270: };
   271: 
>  272: IMPLEMENT_APP( APP_SINGLE_TOP )
   273: 
   274: 
00000000004013A5 0000000000000000 0000000000000000 0000000000000000  pcbnew.exe!__tmainCRTStartup  [C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c @ 339]
00000000004014DB 0000000000000000 0000000000000000 0000000000000000  pcbnew.exe!WinMainCRTStartup  [C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c @ 195]
00000000778459CD 0000000000000000 0000000000000000 0000000000000000  kernel32.dll!BaseThreadInitThunk
0000000077AA385D 0000000000000000 0000000000000000 0000000000000000  ntdll.dll!RtlUserThreadStart

Attachment: signature.asc
Description: OpenPGP digital signature


Follow ups