In gdb, when you run next command. It apply to innermost frame instead of selected frame. How to ask to gdb to break in next line of the selected frame?
For exemple:
Set a breakpoint in a sub-function:
(gdb) b subfunc
Breakpoint 1 at 0x400f09: file prog.c, line 94.
(gdb) c
Continuing.
Breakpoint 1 at 0x400f09: file prog.c, line 94.
94 void subfunc() {
Change selected frame:
(gdb) up
#1 0x0000000000400f7e in main (argc=1, argv=0x7fffffffe468) at prog.c:70
70 subfunc();
I want to stop at line 71 of prog.c:
(gdb) n
95 i = 0;
... but it stop line 95 of prog.c.
I finally found what I want. advance allow to continue until a particular line. Thus advance +1 do the job. It can be abbreviated adv +1.
You can do this with a temporary breakpoint offset from the current line in the selected frame :
tbreak +1
continue
Abbreviated:
tb +1
c
Since the question is
gdb: apply “next” to selected frame instead of innermost frame
The accepted answer is "advance + 1" is not so correct, which only works if the next line of selected frame could be hit.
advance -- Continue the program up to the given location (same form as args for break command)
A general solution is:
Switch to the inferior frame of the selected frame, finish it and step the program.
frame x-1
fin
n
where x is the selected frame.
Ref:
finish -- Execute until selected stack frame returns
next -- Step program
frame -- Select and print a stack frame
Related
In my program I keep filling the following array with data obtained from a database table then inspect it to find certain words:
01 PRODUCTS-TABLE.
03 PRODUCT-LINE PIC X(40) OCCURS 50 TIMES.
sometimes it occurs 6 times, sometimes more than 6 times.
I'd like to find the number of lines in the array every time I write data to it , how can I do that ?
I tried this but it based on a fixed length:
INSPECT-PROCESS.
MOVE 0 TO TALLY-1.
INSPECT PRODUCTS-TABLE TALLYING TALLY-1 FOR ALL "PRODUCT"
IF TALLY-1 > 0
MOVE SER-NUMBER TO HITS-SN-OUTPUT
MOVE FILLER-SYM TO FILLER-O
MOVE PRODUCT-LINE(1) TO HITS-PR-OUTPUT
WRITE HITS-REC
PERFORM WRITE-REPORT VARYING CNT1 FROM 2 BY 1 UNTIL CNT1 = 11.
WRITE-REPORT.
MOVE " " TO HITS-SN-OUTPUT
MOVE PRODUCT-LINE(CNT1) TO HITS-TX-OUTPUT
WRITE HITS-REC.
In the first output line it writes the SN and the first product-line then in the following lines it writes all remaining product-line and blank out SN.
Something like:
12345678 first product-line
Second product-line
etc
It’s working, however, it only stops when CNT1 is 11, how can I feed the procedure with a variable CNT1 based on how many lines are actually in PRODUCTS-TABLE each time?
I solved the problem by adding an array line counter (LINE-COUNTER-1) to count (ADD 1 TO LINE-COUNTER-1) how many times I add data to the array and stop writing the report when "WRITE-COUNTER = LINE-COUNTER-1"
INSPECT-PROCESS.
MOVE 0 TO TALLY-1
INSPECT PRODUCTS-TABLE TALLYING TALLY-1 FOR ALL "PRODUCT"
IF TALLY-1 > 0
MOVE HOLD-SER-NUM TO HITS-SN-OUTPUT
MOVE FILLER-SYM TO FILLER-O
MOVE PRODUCT-LINE(1) TO HITS-PR-OUTPUT
WRITE HITS-REC
PERFORM WRITE-REPORT VARYING WRITE-COUNTER FROM 2 BY 1
UNTIL WRITE-COUNTER = LINE-COUNTER-1.
Good afternoon.
I am writing a SAS program that will loop through several sets of time-series/ observations. For each set, there is one observation per month, with roughly 450 observations/months total. For simplicity's sake, the months start at 1 and move sequentially.
Now, for each set of observations I have an additional set of variables to be employed. I am importing an auxiliary data set that contains these variables for all of the sets, and using the &&var&i. structure to assign each observation's variables a unique macro variable to be called during the execution of the main loop. So, for example, all of the variables in the first observation have a "1" concatenated onto their variable name, second observation variables have a "2," and so on. When the main loop goes through it's first iteration and calls &&var&i., it will resolve to &var1 and pull in the value assigned from the first observation in the auxiliary data set. I have tested this, and it is working fine.
Important note: each observation in the auxiliary set has a series of variables called ratio_1, ratio_2, ... up to ratio_9. After passing through the macro assignment above, they would assume macro names of ratio_11, ratio_21... for the first set, and ratio_12, ratio_22,... and so on for subsequent sets.
My problem arises when I try to insert code that is only supposed to occur at very specific time intervals within each set. Each set has a variable initial_check that determines on which month this code should begin executing. This code should then execute on each observation that occurs in 12-month increments. So, for example, set 1 might have an initial_check value of 36, meaning that the code will only execute for the observation on month 35 (see code below), with subsequent executions on months 47, 59, 71, and so on.
The first line of code is meant to determine that the code that follows only executes at the aforementioned intervals (the rem_var checks for the remainder of the difference between the current month and the initial_check, over 12 - if there is no remainder, then a multiple of 12 months has passed) :
if mon >= %eval(&&initial_check&k -1) and rem_var = 0 and mon < &&term&k. then do ;
I have run that code in isolation to check that each of its parameters is doing what it should, and it appears to be working correctly. The following code comes next:
** Iterate ratios **
if mon = %eval(&&initial_check&k. -1) then call symput('j',1) ;
else if mon = %eval(&&initial_check&k. +11) then call symput('j',2) ;
else if mon = %eval(&&initial_check&k. +23) then call symput('j',3) ;
else if mon = %eval(&&initial_check&k. +35) then call symput('j',4) ;
else if mon = %eval(&&initial_check&k. +47) then call symput('j',5) ;
else if mon = %eval(&&initial_check&k. +59) then call symput('j',6) ;
else if mon = %eval(&&initial_check&k. +71) then call symput('j',7) ;
else if mon = %eval(&&initial_check&k. +83) then call symput('j',8) ;
else if mon = %eval(&&initial_check&k. +95) then call symput('j',9) ;
end ;
Again, I have tested this using non-macro language (that is, assigning the values to regular variable j), and this also appears to be working. Unfortunately, even with the "mprint" option on, I can't see if the macro variable is being properly assigned. Following that, I have additional code that is only supposed to execute if that first condition was met.
if &&ratio_&j&k ne 0 then do ;
And HERE is the issue: I'm getting a note that macro variable j is unresolved.
This code is only supposed to execute in an instance in which &j has been defined, so I can't figure out why it is unresolved. That &&ratio_&j&k is supposed to resolve to &ratio_11 in month 35, &ratio_21 in month 47, and so on for the first loop of the broader program.
I have tried experimenting with the macro versions of the conditional logic (%IF, %THEN, %DO), but have so far failed to get the results I want.
Would anyone happen to have any insight? I'm at my wit's end. I will be following this thread, so I can add details where necessary. And thank you in advance for taking the time to read this.
We need more information. You cannot include the last two blocks of code in the same data step since the data step will use the value of the macro variable J that exists when the data step is compiled and not the one generated by the call symput() function.
Why isn't J just a data step variable?
If it is a macro variable and you want to use the value that call symput() created then you need to use symget() (or symgetn()) to retrieve it at run time. You can then use its value to generate the name of the macro variable that you actually want to reference.
if symgetn(cats('ratio_',symgetn('j'),"&k")) ne 0 then do ;
I want to receive a string from an array using a variables' integer as the array index. But it is not working.
Attempt 1
; Suspended | 0 = No, 1 = Yes
global Suspended := 0
global SuspendedMsg := ["The script has been paused.","The script has been re-activated."]
Pause::
Suspend
if suspended = 0 ; If script is not suspended
{
TrayTip, Paused, SuspendedMsg[Suspended], 3
Suspended++
} else ; If it is suspended
{
TrayTip, Activated, SuspendedMsg[Suspended], 3
Suspended--
}
return
Attempt #1 will just display the string "SuspendedMsg[Suspended]" because I don't know where to set the variable indicator %. Even if I set it to SuspendedMsg[%Suspended%] it will either display [1] or [0].
Attempt 2
; Suspended | 0 = No, 1 = Yes
global Suspended := 0
global SuspendedMsg := ["The script has been paused.","The script has been re-activated."]
global SendSuspendMsg := SuspendedMsg[Suspended]
Pause::
Suspend
if suspended = 0 ; If script is not suspended
{
TrayTip, Paused, %SendSuspendMsg%, 3
Suspended++
} else ; If it is suspended
{
TrayTip, Activated, %SendSuspendMsg%, 3
Suspended--
}
return
Attempt #2 won't do as well, it doesn't even display any message. I tried fiddling arround with % inside the global SendSuspendMsg := SuspendedMsg[Suspended] variable but it won't do no good. Anyone care to help me out?
#Blauhim missed an important point, although his answer is mostly correct. First the Index in an Array when created like you did, always starts at 1, then proceeds to 2 etc, etc... So your code was flawed when you tried to use your Boolean variable to call to an index as a 0 Index does not exist (not to mention that you didn't force and Expression on that TrayTip Command).
; Set our variable to 1 why? Because we are going to use a Logical switch below.
Suspended := 1
; This was correct format and I left it, although I removed Global's as they are not needed
SuspendedMsg := ["The script has been paused.","The script has been re-activated."]
Pause::
; Suspend toggles each time it's called
Suspend
; Here we are toggling the value of our variable using !
; We started with a 1 so that it would be correctly
;Changed to a 0 for the code below.
suspended := !suspended
; Nothing changed here
if suspended = 0 ; If script is not suspended
{
; In order to pass an Array or Object or Expression to a Command you Force it
; using the a Percent Sign with a space on either side.
; Also note you were trying to use your Logical True/False 0 or 1 variable to
; itterate. This didn't work because Array's always start with an Index of 1.
; Below I've accounted for this by simply added a 1 to your suspended so it correctly
; points to the Index in our Array.
TrayTip, Paused, % SuspendedMsg[suspended + 1], 3
} else ; If it is suspended
{
TrayTip, Activated, % SuspendedMsg[suspended + 1], 3
}
return
Instead of TrayTip, Paused, SuspendedMsg[Suspended], 3 or TrayTip, Paused, SuspendedMsg[%Suspended%], 3, try
TrayTip, Paused, % SuspendedMsg[Suspended], 3
. TrayTip asks you for a
specify the message to display
which means as much as a String. So, variables names aren't handled as variables here, but as strings instead (as most of the times in commands). It would make sense to state TrayTip, Paused, %SuspendedMsg[%Suspended%]%, 3
, but you cannot nest variable's percent signs. So, we'll have to use the percent sign to force an expression:
Force an expression: An expression can be used in a parameter that does not directly support it (except OutputVar parameters) by preceding the expression with a percent sign and a space or tab. In [v1.1.21+], this prefix can be used in the InputVar parameters of all commands except the traditional IF commands (use If (expression) instead). This technique is often used to access arrays.
Concerning your second problem: I don't think Arrays can be declared like that, can they..? (but I'm not sure). Also see this short article. So I guess the problem lies within the 3rd line of your code, because the rest of it looks good to me
I have a vector of 126 elements which is usually correctly sorted; however, I always sort it to make sure everything is okay.
The problem is that: when the array is already sorted, performing a sort would destroy the original values of the array.
I attached the array in a csv file and executed the script below, where I insert the vector in the first column of 'a' then sort it in the second then check for any differences in the third column.
a = csvread('a.csv')
a(:,2)=sort(a(:,1))
a(:,3)=a(:,2)-a(:,1)
result=sum(a(:,3).^2)
You could easily see that the first two columns aren't identical, and the third column has some none zero values.
Syntax for array
a = [17.4800
18.6800
19.8800
21.0800
22.2800
23.4800
24.6800
25.8800
27.0800
28.2800
29.4800
30.6800
46.1600
47.3600
48.5600
49.7600
50.9600
52.1600
53.3600
54.5600
55.7600
56.9600
58.1600
59.3600
74.8400
76.0400
77.2400
78.4400
79.6400
80.8400
103.5200
104.7200
105.9200
107.1200
108.3200
109.5200
110.7200
111.9200
113.1200
114.3200
115.5200
116.7200
132.2000
133.4000
134.6000
135.8000
137.0000
138.2000
139.4000
140.6000
141.8000
143.0000
144.2000
145.4000
165.4200
166.6200
167.8200
169.0200
170.2200
171.4200
172.6200
173.8200
175.0200
176.2200
177.4200
178.6200
179.9300
181.1300
182.3300
183.5300
184.7300
185.9300
187.1300
188.3300
189.5300
201.3700
202.5700
203.7700
204.9700
206.1700
207.3700
236.1100
237.3100
238.5100
239.7100
240.9100
242.1100
243.3100
244.5100
245.7100
246.9100
248.1100
249.3100
239.8400
241.0400
242.2400
276.9900
278.1900
279.3900
280.5900
281.7900
282.9900
284.1900
285.3900
286.5900
287.7900
288.9900
290.1900
277.8200
279.0200
280.2200
281.4200
282.6200
283.8200
285.0200
286.2200
287.4200
288.6200
289.8200
291.0200
291.0700
292.2700
293.4700
295.6900
296.8900
298.0900];
Your original vector is unfortunately not sorted. Therefore, sorting this result will obviously not give you what the original vector is supposed to be as the values that were out of order will become in order.
You can check this by using diff on the read in vector from the CSV file and seeing if there are any negative differences. diff takes the difference between the (i+1)th value and the ith value and if your values are monotonically increasing, you should get positive differences all around. We can see which locations are affected by finding values in the difference that are negative:
a = csvread('a.csv');
ind = find(diff(a) < 0);
We get:
>> ind
ind =
93
108
This says that locations 93 and 108 are where the out of order starts. Locations 94 and 109 is where it actually happens. Let's check out portions 90 - 110 of your vector to be sure:
>> a(90:110)
ans =
245.7100 % 90
246.9100 % 91
248.1100 % 92
249.3100 % 93
239.8400 %<-------
241.0400
242.2400
276.9900
278.1900
279.3900
280.5900
281.7900
282.9900
284.1900
285.3900
286.5900
287.7900 % 106
288.9900 % 107
290.1900 % 108
277.8200 % <------
279.0200
As you can see, locations 93 and 108 take a dip in numerical value, and so if you tried sorting the result then taking the difference, you'll notice that locations 1 up to 93 will exhibit a difference of 0, but after location 93, that's when it becomes unequal.
I'm frankly surprised you didn't see that they're out of order because your snapshot clearly shows there's a decrease in value on the left column towards the top of the snapshot.
Therefore, either check your data to see if you have input it correctly, or modify whatever process you're working on to ensure that it can handled unsorted data.
When using lldb to debug a program, the program crashes and I print "bt" to backtrace. But even I scroll all the way back to the top of the screen, I still don't see the where the program is crashed because the backtrace is too large.
If you're using Terminal.app on Mac OS X, you can increase the size of your scroll-back buffer by opening the Preferences window for Terminal, click on the Profiles tab, there will be a series of buttons on the right, "Text / Window / Shell / Keyboard / Advanced". Under "Window" under "Scrollback" you can select a number of rows, or whether Terminal should limit the scrollback buffer to a number of lines.
Also, in lldb, the bt command accepts an argument which is the number of stack frames to show. It sounds like it's the first few stack frames that you're having trouble seeing, so this is exactly what you want. For instance, here I have bt only showing me the first two stack frames:
(lldb) bt
* thread #1: tid = 0x09bd, 0x00007fff888194de libsystem_kernel.dylib`mach_msg_trap + 10, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
* #0: 0x00007fff888194de libsystem_kernel.dylib`mach_msg_trap + 10
#1: 0x00007fff8881864f libsystem_kernel.dylib`mach_msg + 55
#2: 0x00007fff85c75b34 CoreFoundation`__CFRunLoopServiceMachPort + 212
#3: 0x00007fff85c74ffb CoreFoundation`__CFRunLoopRun + 1371
#4: 0x00007fff85c74858 CoreFoundation`CFRunLoopRunSpecific + 296
#5: 0x000000010148f497 Dock`___lldb_unnamed_function2$$Dock + 1202
#6: 0x00007fff8e7fd5c9 libdyld.dylib`start + 1
#7: 0x00007fff8e7fd5c9 libdyld.dylib`start + 1
(lldb) bt 2
* thread #1: tid = 0x09bd, 0x00007fff888194de libsystem_kernel.dylib`mach_msg_trap + 10, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
* #0: 0x00007fff888194de libsystem_kernel.dylib`mach_msg_trap + 10
#1: 0x00007fff8881864f libsystem_kernel.dylib`mach_msg + 55
(lldb)