Александр Ильин писал(а):
Только вот я не понял. Остановка, кажется, произошла на Pragma.c:1415, а я-то просил на Pragma.c:391... Почему так? Строка совсем не та, что я имел в виду.
Выполнив команду "step" несколько раз, я понял, что выполнение на самом деле остановилось там, где я хотел. Временные прыжки не на ту строку - это результат оптимизации и перемещения блоков кода (забыл убрать опцию -O2, когда добавлял -g).
Поскольку ошибка воспроизводимая, то мне удалось автоматизировать получение стека вызовов с помощью GDB, достаточно выполнить следующую последовательность команд:
Код:
break exit
run
backtrace
continue
quit
А если эту последовательность записать в файл с именем, например, "bt.gdb" (от англ. backtrace и GDB), то становится достаточно следующей командной строки:
Код:
bash-3.1$ gdb --quiet -x bt.gdb --args bin/oo2c ../ImportGraph/ImportGraph.Mod
Reading symbols from d:\Programs\Dev\MinGW\msys\1.0\local\src\oo2c/bin/oo2c.exe...done.
Breakpoint 1 at 0x545268
[New Thread 10176.0x1f58]
##
## Runtime error in module OOC:Scanner:Pragma at pos 9577
## Assertion failed, code 20
##
Breakpoint 1, 0x00545268 in exit ()
#0 0x00545268 in exit ()
#1 0x00401721 in _runtime_error (msg=0x22f870 "Assertion failed, code 20", mid=0x555644, pos=9577) at d:/Programs/Dev/MinGW/msys/1.0/local/src/oo2c/lib/src/RT0.c:64
#2 0x00401c05 in RT0__ErrorAssertionFailed (mid=0x555644, pos=9577, code=20) at d:/Programs/Dev/MinGW/msys/1.0/local/src/oo2c/lib/src/RT0.c:321
#3 0x0045223e in OOC_Scanner_Pragma__ParsePragma_Expression_SimpleExpr_Term_Factor (eval=<value optimized out>, value=0x22fa88, value__tag=0x555620) at obj/OOC/Scanner/Pragma.c:391
#4 OOC_Scanner_Pragma__AddSymbol (eval=<value optimized out>, value=Could not find the frame base for "OOC_Scanner_Pragma__AddSymbol".) at obj/OOC/Scanner/Pragma.c:346
#5 0x004522f2 in OOC_Scanner_Pragma__ParsePragma_Expression_SimpleExpr_Term (eval=1 '\001', value=0x22fa88, value__tag=0x555620) at obj/OOC/Scanner/Pragma.c:510
#6 OOC_Scanner_Pragma__AddSymbol (eval=Could not find the frame base for "OOC_Scanner_Pragma__AddSymbol".) at obj/OOC/Scanner/Pragma.c:341
#7 0x00451b32 in OOC_Scanner_Pragma__ParsePragma_Expression_SimpleExpr (eval=1 '\001', value=0x22fa88, value__tag=0x555620) at obj/OOC/Scanner/Pragma.c:562
#8 OOC_Scanner_Pragma__AddSymbol (eval=Could not find the frame base for "OOC_Scanner_Pragma__AddSymbol".) at obj/OOC/Scanner/Pragma.c:336
#9 0x00451c2f in OOC_Scanner_Pragma__ParsePragma_Expression (eval=<value optimized out>, value=0x22fa88, value__tag=0x555620) at obj/OOC/Scanner/Pragma.c:615
#10 OOC_Scanner_Pragma__AddSymbol (eval=<value optimized out>, value=Could not find the frame base for "OOC_Scanner_Pragma__AddSymbol".) at obj/OOC/Scanner/Pragma.c:325
#11 0x00452494 in OOC_Scanner_Pragma__ParsePragma_Assignment (define=0 '\000', eval=1 '\001') at obj/OOC/Scanner/Pragma.c:936
#12 OOC_Scanner_Pragma__AddSymbol (define=0 '\000', eval=Could not find the frame base for "OOC_Scanner_Pragma__AddSymbol".) at obj/OOC/Scanner/Pragma.c:874
#13 0x00452efc in OOC_Scanner_Pragma__ParsePragma (state__tag=0x555520, inputMode=0x22fbef "\001м√\"") at obj/OOC/Scanner/Pragma.c:1074
#14 OOC_Scanner_Pragma__AddSymbol (state__tag=0x555520, inputMode=0x22fbef "\001м√\"") at obj/OOC/Scanner/Pragma.c:1415
#15 0x004546e3 in OOC_Scanner__ScanInput (builder=0x1147528, defaultPragmas=0x1143560, scanOptions=63) at obj/OOC/Scanner.c:1514
#16 0x004a6558 in OOC_Auxiliary_ParseModule__ParseModule (m=0x1187698, checkModuleName=0 '\000', createNamespace=0 '\000', writeSymbolFile=0 '\000', abortAfterImport=1 '\001', libraryName=0x0, uses=0x11479e8, ast=0x22fce4, symTab=0x22fce8, pragmaHistory=0x22fcec, errList=0x22fce0) at obj/OOC/Auxiliary/ParseModule.c:35
#17 0x00533c19 in OOC_Make__RulesDesc_GetImports (r=0x11452a8) at obj/OOC/Make.c:553
#18 0x005340ef in OOC_Make__RulesDesc_UpdateHeaderFileC (r=0x11452a8, module=0x1187698) at obj/OOC/Make.c:1200
#19 0x00535acf in OOC_Make__RulesDesc_Update (r=0x11452a8, module=0x1187698, fileId=13 '\r') at obj/OOC/Make.c:2026
#20 0x005327fe in OOC_Make__RulesDesc_UpdateDeclFileC (r=0x11452a8, module=0x1187698) at obj/OOC/Make.c:1249
#21 0x00535ae7 in OOC_Make__RulesDesc_Update (r=0x11452a8, module=0x1187698, fileId=12 '\f') at obj/OOC/Make.c:2022
#22 0x00532eea in OOC_Make__RulesDesc_UpdateCodeFileC (r=0x11452a8, module=0x1187698) at obj/OOC/Make.c:1266
#23 0x00535aff in OOC_Make__RulesDesc_Update (r=0x11452a8, module=0x1187698, fileId=11 '\v') at obj/OOC/Make.c:2018
#24 0x005394c4 in OOC_oo2c_init () at obj/oo2c.c:1290
#25 0x005399d0 in OOC_oo2c_open (client=0x0) at obj/oo2c.d:125
#26 0x00539a12 in main (argc=2, argv=0x3e24f0) at obj/oo2c_.c:5
Program exited with code 0177.
bash-3.1$
Другими словами, для получения стека вызовов достаточно запустить программу под отладчиком с правильными параметрами, и дождаться поломки. Чтобы не писать всю командную строку, можно создать файл bt.bat следующего содержания:
Код:
gdb --quiet -x bt.gdb --args %*
Запускать, соответственно, так (из cmd.exe): bt bin/oo2c ../ImportGraph/ImportGraph.Mod
Для Bash этот командный файл будет выглядеть немного иначе:
Код:
#!/bin/bash
gdb --quiet -x bt.gdb --args $*
Запуск тоже чуточку отличается: ./bt bin/oo2c ../ImportGraph/ImportGraph.Mod
Текущим каталогом должен быть путь к local/src/oo2c, поскольку GDB по умолчанию ищет сишные исходники относительно текущего пути, в подкаталоге obj (такие пути прописаны внутри exe-файла). При желании можно воспользоваться параметром --directory, указав путь к исходникам так: gdb --directory=d:/Programs/Dev/MinGW/msys/1.0/local/src/oo2c